470744 : Merge m2e-wtp's jpa and core git repositories

Merge remote-tracking branch 'jpa/master' from http://git.eclipse.org/c/m2e-wtp/org.eclipse.m2e.wtp.jpa.git/
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6ed3cc1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+/.project
+/.metadata
+/its
+/target
+.DS_Store
diff --git a/.settings/org.maven.ide.eclipse.prefs b/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 0000000..0e3bb8b
--- /dev/null
+++ b/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,9 @@
+#Sat Jul 31 16:21:31 CEST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..12cfb9e
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,17 @@
+Contributing to m2e-wtp
+=======================
+
+
+If you are interested in contributing to m2e-wtp, you can : 
+
+* join the project mailing list [m2e-wtp-dev@eclipse.org](https://dev.eclipse.org/mailman/listinfo/m2e-wtp-dev).
+
+* Report bugs to the [Eclipse Bugzilla instance](https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bugidtype=include&classification=Technology&list_id=9231713&product=M2E-WTP&query_format=advanced)
+
+* Take a look at the code :
+
+    - The canonical git repository is available at http://git.eclipse.org/c/m2e-wtp/org.eclipse.m2e.wtp.git/
+    - The JPA feature is maintained in a separate [git repository](http://git.eclipse.org/c/m2e-wtp/org.eclipse.m2e.wtp.jpa.git)   
+    - The git repository containing integration tests is available at [m2e-wtp-tests (@github.com)](https://github.com/jbosstools/m2e-wtp-tests.git)
+    
+* Currently, m2e-wtp only accepts contributions as git patches attached the [Eclipse Bugzilla instance](https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bugidtype=include&classification=Technology&list_id=9231713&product=M2E-WTP&query_format=advanced). Please note that contributors need to sign the [Eclipse Foundation Contributor License Agreement](https://www.eclipse.org/legal/CLA.php).
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9cb502f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,25 @@
+Maven Integration for Eclipse WTP
+=================================
+
+Maven Integration for Eclipse WTP, a.k.a m2e-wtp, aims at providing a tight integration between Maven Integration for Eclipse (a.k.a m2e) and the Eclipse Web Tools Project (WTP) .
+
+m2eclipse-wtp provides a set of m2e connectors used for the configuration of Java EE projects in WTP. It features :
+
+* Support for war projects : adds the Java and Dynamic Web Facets. Support war overlays and on-the-fly resource filtering
+* Support for ejb projects : adds the Java and EJB Facets. Supports deployment descriptor filtering.
+* Support for ear projects : adds the EAR Facet. Supports application.xml and jboss.xml file generation, resource filtering
+* Support for rar projects : adds the Java and Connector Facets.
+* Support for app-client projects : adds the Java and Application Client Facets. Supports deployment descriptor filtering.
+* Support for jar dependency projects : adds the Java and Utility Facets.
+* Support for web-fragment projects : adds the Java and Web Fragment Facets if a web-fragment.xml file is detected in the resource folders.
+
+Note that m2e-wtp requires m2e > 1.0. You must make sure m2e's update site (http://download.eclipse.org/technology/m2e/releases/) is defined in :
+Window > Preferences > Install / Update > Available Software Sites
+Since m2e 1.0 is incompatible with previous versions, you may have to uninstall old m2e and m2e-wtp versions before proceeding with the installation.
+
+[Public source repository](http://git.eclipse.org/c/m2e-wtp/org.eclipse.m2e.wtp.git/)
+
+[Issue tracking](https://bugs.eclipse.org/bugs/enter_bug.cgi?product=M2E-WTP)
+
+[Public wiki](wiki.eclipse.org/M2E-WTP)
+
diff --git a/catalog.xml b/catalog.xml
new file mode 100644
index 0000000..f877974
--- /dev/null
+++ b/catalog.xml
@@ -0,0 +1,27 @@
+<catalog>
+  <catalogItems>    
+    <catalogItem>
+      <categoryId>org.eclipse.m2e.discovery.category.lifecycles</categoryId>
+      <m2e-versions>1.0,1.1</m2e-versions>
+      <description>m2e-wtp</description>
+      <groupId>lifecycles</groupId>
+      <id>org.eclipse.m2e.discovery.lifecyclemapping.m2e-wtp</id>
+      <kind>lifecycles</kind>
+      <license>EPL</license>
+      <name>m2e-wtp</name>
+      <provider>JBoss by Red Hat</provider>
+      <p2>
+        <repositoryUrl>http://download.jboss.org/jbosstools/updates/m2eclipse-wtp/</repositoryUrl>
+        <iuId>org.maven.ide.eclipse.wtp.feature.feature.group</iuId>
+        <iuVersion>0.15.2.20120306-2040</iuVersion>
+        <lifecycleMappingIU>
+          <iuId>org.maven.ide.eclipse.wtp</iuId>
+        </lifecycleMappingIU>
+      </p2>
+      <overview>
+        <summary>Maven Integration for WTP</summary>
+        <url>https://github.com/sonatype/m2eclipse-wtp</url>
+      </overview>
+    </catalogItem>
+  </catalogItems>
+</catalog>
\ No newline at end of file
diff --git a/description b/description
new file mode 100644
index 0000000..e2cf764
--- /dev/null
+++ b/description
@@ -0,0 +1 @@
+m2e-wtp main source repository
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.feature/.gitignore b/org.eclipse.m2e.wtp.feature/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/org.eclipse.m2e.wtp.feature/.project b/org.eclipse.m2e.wtp.feature/.project
new file mode 100644
index 0000000..6f898ae
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..08d14a1
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,5 @@
+#Wed Apr 06 19:19:49 CEST 2011
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000..b295bb6
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Thu Aug 28 19:43:49 EDT 2008
+eclipse.preferences.version=1
+project.repository.kind=jira
+project.repository.url=http\://jira.codehaus.org
diff --git a/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..1df28c8
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Thu Jan 10 02:40:59 EST 2008
+commit.comment.template=${task.key}\: ${task.description}
+eclipse.preferences.version=1
diff --git a/org.eclipse.m2e.wtp.feature/.settings/org.maven.ide.eclipse.prefs b/org.eclipse.m2e.wtp.feature/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 0000000..445a799
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,9 @@
+#Thu Feb 04 09:56:35 EST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/org.eclipse.m2e.wtp.feature/build.properties b/org.eclipse.m2e.wtp.feature/build.properties
new file mode 100644
index 0000000..1aaf3a7
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/build.properties
@@ -0,0 +1,4 @@
+bin.includes = feature.xml,\
+               feature.properties,\
+               p2.inf
+
diff --git a/org.eclipse.m2e.wtp.feature/feature.properties b/org.eclipse.m2e.wtp.feature/feature.properties
new file mode 100644
index 0000000..6b7acbe
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/feature.properties
@@ -0,0 +1,41 @@
+###############################################################################
+# Copyright (c) 2008, 2012 Sonatype, Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     Sonatype, Inc. - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=m2e-wtp - Maven Integration for WTP
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org - m2e-wtp
+
+# "updateSiteName" property - label for the update site
+#updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=m2e project configurators for Eclipse WTP.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2008-2014 Sonatype, Inc and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+     Sonatype, Inc. - initial API and implementation\n\
+     Red Hat, Inc. - Java EE configurators\n
+
+################ end of copyright property ####################################
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.feature/feature.xml b/org.eclipse.m2e.wtp.feature/feature.xml
new file mode 100644
index 0000000..b49ea3d
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/feature.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.m2e.wtp.feature"
+      label="%featureName"
+      version="1.3.0.qualifier"
+      provider-name="%providerName"
+      plugin="org.eclipse.m2e.wtp"
+      license-feature="org.eclipse.license"
+      license-feature-version="0.0.0">
+   <install-handler/>
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <requires>
+      <import feature="org.eclipse.platform" version="3.6.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.rcp" version="3.6.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jdt" version="3.6.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.wst.web_ui.feature" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jst.enterprise_ui.feature" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.wst.common.fproj" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jst.common.fproj.enablement.jdt" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.m2e.feature" version="1.5.0" match="greaterOrEqual"/>
+      <import feature="org.sonatype.m2e.mavenarchiver.feature" version="0.16.0" match="greaterOrEqual"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.m2e.wtp"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.m2e.wtp.overlay"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.m2e.wtp.overlay.ui"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/org.eclipse.m2e.wtp.feature/p2.inf b/org.eclipse.m2e.wtp.feature/p2.inf
new file mode 100644
index 0000000..16f5d47
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/p2.inf
@@ -0,0 +1,16 @@
+units.1.id=org.maven.ide.eclipse.wtp
+units.1.properties.0.name=org.eclipse.equinox.p2.name
+units.1.properties.0.value=This version of m2e-wtp cannot be installed on top of the already installed m2eclipse-wtp. Uninstall the previous version of m2eclipse-wtp and try the install again.
+units.1.properties.1.name=maven-classifier
+units.1.properties.1.value=p2inf
+units.1.version=$version$
+units.1.singleton=true
+units.1.provides.0.namespace=osgi.bundle
+units.1.provides.0.name=org.maven.ide.eclipse.wtp
+units.1.provides.0.version=$version$
+
+requires.0.namespace=osgi.bundle
+requires.0.name=org.maven.ide.eclipse.wtp
+requires.0.range=[$version$, $version$]
+
+update.matchExp=providedCapabilities.exists(pc | pc.namespace \=\= 'org.eclipse.equinox.p2.iu' && (pc.name \=\= 'org.maven.ide.eclipse.wtp.feature.feature.group' || pc.name \=\= 'org.eclipse.m2e.wtp.feature.feature.group' && pc.version < '$version$'))
diff --git a/org.eclipse.m2e.wtp.feature/pom.xml b/org.eclipse.m2e.wtp.feature/pom.xml
new file mode 100644
index 0000000..f5d7137
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/pom.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2008 Sonatype, Inc.
+  All rights reserved. This program and the accompanying materials
+  are made available under the terms of the Eclipse Public License v1.0
+  which accompanies this distribution, and is available at
+  http://www.eclipse.org/legal/epl-v10.html
+-->
+<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>
+    <groupId>org.eclipse.m2e.wtp</groupId>
+    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.m2e.wtp.feature</artifactId>
+  <packaging>eclipse-feature</packaging>
+
+  <name>M2E-WTP :: Core Feature</name>
+  <!--
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-packaging-plugin</artifactId>
+		<version>${tycho-version}</version>
+        <configuration>
+          <deployableFeature>true</deployableFeature>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-p2-plugin</artifactId>
+        <version>${tycho-version}</version>
+        <executions>
+          <execution>
+            <id>categorization</id>
+            <phase>package</phase>
+            <goals>
+              <goal>category-p2-metadata</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <metadataRepositoryName>Maven Integration for Eclipse WTP</metadataRepositoryName>
+          <artifactRepositoryName>Maven Integration for Eclipse WTP</artifactRepositoryName>
+          <compressRepository>false</compressRepository>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <configuration>
+          <descriptors>
+            <descriptor>src/main/assembly/assembly.xml</descriptor>
+          </descriptors>
+        </configuration>
+        <executions>
+          <execution>
+            <id>make-assembly</id> 
+            <phase>package</phase> 
+            <goals>
+              <goal>single</goal> 
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>publish-site</id>
+
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.sonatype.plugins</groupId>
+            <artifactId>maven-upload-plugin</artifactId>
+            <version>0.0.1</version>
+            <executions>
+              <execution>
+                <id>publish-site</id>
+                <phase>deploy</phase>
+                <goals>
+                  <goal>upload-file</goal>
+                </goals>
+                <configuration>
+                  <file>${project.build.directory}/${project.artifactId}-${project.version}-site.zip</file>
+
+                  <serverId>forge-releases</serverId>
+                  <repositoryUrl>${m2e.site-compressed}</repositoryUrl>
+                  <repositoryPath>m2eclipse-wtp/${unqualifiedVersion}/N/${unqualifiedVersion}.${buildQualifier}</repositoryPath>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+  -->
+</project>
diff --git a/org.eclipse.m2e.wtp.feature/src/main/assembly/assembly.xml b/org.eclipse.m2e.wtp.feature/src/main/assembly/assembly.xml
new file mode 100644
index 0000000..2a8a526
--- /dev/null
+++ b/org.eclipse.m2e.wtp.feature/src/main/assembly/assembly.xml
@@ -0,0 +1,14 @@
+<assembly>
+  <id>site</id>
+  <formats>
+    <format>zip</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <fileSets>
+    <fileSet>
+      <directory>${project.build.directory}/site</directory>
+      <outputDirectory>/</outputDirectory>
+    </fileSet>
+  </fileSets>
+
+</assembly>
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/.gitignore b/org.eclipse.m2e.wtp.jaxrs.feature/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/.project b/org.eclipse.m2e.wtp.jaxrs.feature/.project
new file mode 100644
index 0000000..8f12d0e
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp.jaxrs.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.jaxrs.feature/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.jaxrs.feature/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/build.properties b/org.eclipse.m2e.wtp.jaxrs.feature/build.properties
new file mode 100644
index 0000000..e2bd14c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/build.properties
@@ -0,0 +1,3 @@
+bin.includes = feature.xml,\
+               p2.inf,\
+               feature.properties
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/feature.properties b/org.eclipse.m2e.wtp.jaxrs.feature/feature.properties
new file mode 100644
index 0000000..82348c3
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/feature.properties
@@ -0,0 +1,40 @@
+###############################################################################
+# Copyright (c) 2008, 2012 Red Hat, Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     Red Hat, Inc. - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=m2e-wtp - JAX-RS configurator for WTP (Optional)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org - m2e-wtp
+
+# "updateSiteName" property - label for the update site
+#updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=m2e JAX-RS project configurator for Eclipse WTP.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2008-2014 Red Hat, Inc and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+     Red Hat, Inc. - Java EE configurators\n
+
+################ end of copyright property ####################################
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/feature.xml b/org.eclipse.m2e.wtp.jaxrs.feature/feature.xml
new file mode 100644
index 0000000..422df56
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/feature.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.m2e.wtp.jaxrs.feature"
+      label="%featureName"
+      version="1.3.0.qualifier"
+      provider-name="%providerName"
+      plugin="org.eclipse.m2e.wtp.jaxrs"
+      license-feature="org.eclipse.license"
+      license-feature-version="0.0.0">
+   <install-handler/>
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <requires>
+      <!--
+      <import plugin="org.eclipse.wst.common.frameworks"/>
+      <import plugin="org.eclipse.wst.common.modulecore"/>
+      <import plugin="org.eclipse.wst.common.project.facet.core"/>
+      <import plugin="org.eclipse.jst.common.frameworks"/>
+      <import plugin="org.eclipse.jst.common.project.facet.core"/>
+      <import plugin="org.eclipse.jst.j2ee.web"/>
+      <import plugin="org.eclipse.jst.j2ee"/>
+      <import plugin="org.eclipse.jst.j2ee.core"/>
+      -->
+      <import feature="org.eclipse.platform" version="3.6.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.rcp" version="3.6.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jdt" version="3.6.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.wst.web_ui.feature" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jst.enterprise_ui.feature" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.wst.common.fproj" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jst.common.fproj.enablement.jdt" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.m2e.feature" version="1.1.0" match="greaterOrEqual"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.m2e.wtp.jaxrs"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/p2.inf b/org.eclipse.m2e.wtp.jaxrs.feature/p2.inf
new file mode 100644
index 0000000..d952606
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/p2.inf
@@ -0,0 +1,16 @@
+units.1.id=org.jboss.tools.maven.jaxrs
+units.1.properties.0.name=org.eclipse.equinox.p2.name
+units.1.properties.0.value=This version of the JAX-RS configurator cannot be installed on top of the already installed org.jboss.tools.maven.jaxrs plugin. Uninstall the previous version of org.jboss.tools.maven.jaxrs and try the install again.
+units.1.properties.1.name=maven-classifier
+units.1.properties.1.value=p2inf
+units.1.version=$version$
+units.1.singleton=true
+units.1.provides.0.namespace=osgi.bundle
+units.1.provides.0.name=org.jboss.tools.maven.jaxrs
+units.1.provides.0.version=$version$
+
+requires.0.namespace=osgi.bundle
+requires.0.name=org.jboss.tools.maven.jaxrs
+requires.0.range=[$version$, $version$]
+
+update.matchExp=providedCapabilities.exists(pc | pc.namespace \=\= 'org.eclipse.equinox.p2.iu' && (pc.name \=\= 'org.jboss.tools.maven.jaxrs.feature.feature.group' || pc.name \=\= 'org.eclipse.m2e.wtp.jaxrs.feature.feature.group' && pc.version < '$version$'))
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/pom.xml b/org.eclipse.m2e.wtp.jaxrs.feature/pom.xml
new file mode 100644
index 0000000..42f2814
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.eclipse.m2e.wtp</groupId>
+    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.m2e.wtp.jaxrs.feature</artifactId>
+  <packaging>eclipse-feature</packaging>
+
+  <name>M2E-WTP :: JAX-RS Support Feature</name>
+
+</project>
+
diff --git a/org.eclipse.m2e.wtp.jaxrs.feature/sdk b/org.eclipse.m2e.wtp.jaxrs.feature/sdk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs.feature/sdk
diff --git a/org.eclipse.m2e.wtp.jaxrs/.classpath b/org.eclipse.m2e.wtp.jaxrs/.classpath
new file mode 100644
index 0000000..46cec6e
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/org.eclipse.m2e.wtp.jaxrs/.gitignore b/org.eclipse.m2e.wtp.jaxrs/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/org.eclipse.m2e.wtp.jaxrs/.project b/org.eclipse.m2e.wtp.jaxrs/.project
new file mode 100644
index 0000000..778317d
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp.jaxrs</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp.jaxrs/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.jaxrs/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.jaxrs/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.m2e.wtp.jaxrs/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..935535c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,99 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/org.eclipse.m2e.wtp.jaxrs/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.jaxrs/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.jaxrs/META-INF/MANIFEST.MF b/org.eclipse.m2e.wtp.jaxrs/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..bc765e9
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.m2e.wtp.jaxrs;singleton:=true
+Bundle-Version: 1.3.0.qualifier
+Bundle-Activator: org.eclipse.m2e.wtp.jaxrs.internal.MavenJaxRsActivator
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.ui,
+ org.eclipse.jdt.core,
+ org.eclipse.m2e.maven.runtime,
+ org.eclipse.m2e.core;bundle-version="[1.0.0,2.0.0)",
+ org.eclipse.m2e.wtp,
+ org.eclipse.jst.common.project.facet.core,
+ org.eclipse.jst.j2ee,
+ org.eclipse.jst.j2ee.core,
+ org.eclipse.jst.ws.jaxrs.core,
+ org.eclipse.wst.common.emfworkbench.integration,
+ org.eclipse.wst.common.project.facet.core,
+ org.eclipse.wst.common.frameworks,
+ org.slf4j.api
+Bundle-Localization: plugin
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-Vendor: %Bundle-Vendor
+Export-Package: org.eclipse.m2e.wtp.jaxrs.internal,org.eclipse.m2e.wtp
+ .jaxrs.internal.configurators
diff --git a/org.eclipse.m2e.wtp.jaxrs/about.html b/org.eclipse.m2e.wtp.jaxrs/about.html
new file mode 100644
index 0000000..f5783af
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/about.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About Maven JAX-RS Configurator</title>
+</head>
+<body lang="EN-US">
+<h3>Maven JAX-RS Configurator</h3>
+<p>m2e configurator setting the JAX-RS Facet on projects having JAX-RS dependencies</p>
+ 
+<p>October 29, 2010</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
diff --git a/org.eclipse.m2e.wtp.jaxrs/about.ini b/org.eclipse.m2e.wtp.jaxrs/about.ini
new file mode 100644
index 0000000..2a3e3ee
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/about.ini
@@ -0,0 +1,27 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+# test
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%blurb
+
+# Property "windowImage" contains path to window icon (16x16)
+# needed for primary features only
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=m2e-wtp_icon_32px.png
+
+# Property "aboutImage" contains path to product image (500x330 or 115x164)
+# needed for primary features only
+
+# Property "appName" contains name of the application (not translated)
+# needed for primary features only
+
+# Property "welcomePerspective" contains the id of the perspective in which the
+# welcome page is to be opened.
+# optional
+
+
+
diff --git a/org.eclipse.m2e.wtp.jaxrs/about.mappings b/org.eclipse.m2e.wtp.jaxrs/about.mappings
new file mode 100644
index 0000000..c367bc8
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/about.mappings
@@ -0,0 +1,5 @@
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
diff --git a/org.eclipse.m2e.wtp.jaxrs/about.properties b/org.eclipse.m2e.wtp.jaxrs/about.properties
new file mode 100644
index 0000000..07365e4
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/about.properties
@@ -0,0 +1,2 @@
+blurb=m2e JAX-RS project configurator for Eclipse WTP\n\nVersion\: {featureVersion}\n\n(c) Copyright (c) Red Hat, Inc. and others 2011 - 2014.  All rights reserved.\nVisit http\://www.eclipse.org/m2e-wtp
+
diff --git a/org.eclipse.m2e.wtp.jaxrs/build.properties b/org.eclipse.m2e.wtp.jaxrs/build.properties
new file mode 100644
index 0000000..638a219
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/build.properties
@@ -0,0 +1,16 @@
+source.. = src/
+output.. = target/classes/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               plugin.properties,\
+               about.html,\
+               about.ini,\
+               about.mappings,\
+               about.properties,\
+               lifecycle-mapping-metadata.xml,\
+               m2e-wtp_icon_32px.png
+src.includes = about.html,\
+               about.ini,\
+               about.mappings,\
+               about.properties
diff --git a/org.eclipse.m2e.wtp.jaxrs/lifecycle-mapping-metadata.xml b/org.eclipse.m2e.wtp.jaxrs/lifecycle-mapping-metadata.xml
new file mode 100644
index 0000000..9927711
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/lifecycle-mapping-metadata.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lifecycleMappingMetadata>
+
+	<pluginExecutions>
+		<pluginExecution>
+			<pluginExecutionFilter>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-war-plugin</artifactId>
+				<versionRange>[1.0,)</versionRange>
+				<goals>
+					<goal>war</goal>
+				</goals>
+			</pluginExecutionFilter>
+			<action>
+				<configurator>
+					<id>org.eclipse.m2e.wtp.jaxrs.configurator</id>
+				</configurator>
+			</action>
+		</pluginExecution>
+	</pluginExecutions>
+
+</lifecycleMappingMetadata>
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.jaxrs/m2e-wtp_icon_32px.png b/org.eclipse.m2e.wtp.jaxrs/m2e-wtp_icon_32px.png
new file mode 100644
index 0000000..2d37574
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/m2e-wtp_icon_32px.png
Binary files differ
diff --git a/org.eclipse.m2e.wtp.jaxrs/plugin.properties b/org.eclipse.m2e.wtp.jaxrs/plugin.properties
new file mode 100644
index 0000000..0089635
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/plugin.properties
@@ -0,0 +1,10 @@
+Bundle-Vendor =Eclipse.org - m2e-wtp
+Bundle-Name = Maven JAX-RS Configurator
+JAXRS_Project_configurator=JAX-RS
+JAXRS_Lifecycle_Mapping=JAX-RS Lifecycle Mapping
+Maven_Configuration_Problem=Maven Java EE Configuration Problem
+Maven_Configuration_Problems=Maven Java EE Configuration Problem
+jaxrs_enabler_label=JAX-RS Configurator
+jaxrs_enabler_description=The JAX-RS Configurator adds the JAX-RS Facet to Dynamic Web projects if JAX-RS classpath dependencies are found.
+template.jaxRsActivationProperty.name=m2e-wtp JAX-RS activation
+template.jaxRsActivationProperty.description=Enable or disable automatic JAX-RS configuration
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.jaxrs/plugin.xml b/org.eclipse.m2e.wtp.jaxrs/plugin.xml
new file mode 100644
index 0000000..277dccf
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/plugin.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+	<extension
+         point="org.eclipse.m2e.core.lifecycleMappingMetadataSource">
+    </extension>
+   
+    <extension
+         point="org.eclipse.m2e.core.lifecycleMappings">
+      <lifecycleMapping
+            class="org.eclipse.m2e.wtp.jaxrs.internal.configurators.JaxRsLifecycleMapping"
+            id="org.eclipse.m2e.wtp.jaxrs.JaxrsLifecycleMapping"
+            name="%JAXRS_Lifecycle_Mapping">
+      </lifecycleMapping>
+    </extension>
+    
+	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.eclipse.m2e.wtp.jaxrs.configurator"
+          class="org.eclipse.m2e.wtp.jaxrs.internal.configurators.JaxRsProjectConfigurator"
+          name="%JAXRS_Project_configurator" 
+          secondaryTo="org.maven.ide.eclipse.configuration.wtp.configurator"/>
+    </extension>
+    
+     <extension point="org.eclipse.core.resources.markers"
+         id="org.eclipse.m2e.core.maven2Problem.wtp.jaxrs.configuration"
+         name="%Maven_Configuration_Problem">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <persistent value="true"/>
+    </extension>
+
+   <extension
+         point="org.eclipse.m2e.wtp.javaeeConfiguratorEnabler">
+         <javaeeConfiguratorEnabler
+           id="org.eclipse.m2e.wtp.jaxrs.enabler"
+           label="%jaxrs_enabler_label"
+           description="%jaxrs_enabler_description"
+           configuratorIds="org.eclipse.m2e.wtp.jaxrs.configurator"
+         />
+   </extension> 
+   
+   <extension
+         point="org.eclipse.m2e.wtp.facetDetectors">
+         <facetDetector
+           facetId="jst.jaxrs"
+           class="org.eclipse.m2e.wtp.jaxrs.internal.configurators.ClasspathJaxRsFacetDetector"
+           priority="10"
+         />
+   </extension>
+   
+   <extension point="org.eclipse.ui.editors.templates">
+    <template id="org.eclipse.m2e.wtp.jaxrs.xml.templates.jaxRsActivationProperty"
+         contextTypeId="org.eclipse.m2e.editor.xml.templates.contextType.properties"
+         name="%template.jaxRsActivationProperty.name" 
+         description="%template.jaxRsActivationProperty.description">
+      <pattern>&lt;m2e.jaxrs.activation&gt;${cursor}${false}&lt;/m2e.jaxrs.activation&gt;</pattern>
+    </template>
+   </extension> 
+</plugin>
diff --git a/org.eclipse.m2e.wtp.jaxrs/pom.xml b/org.eclipse.m2e.wtp.jaxrs/pom.xml
new file mode 100644
index 0000000..ae4ee99
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.eclipse.m2e.wtp</groupId>
+		<artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+		<version>1.3.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>org.eclipse.m2e.wtp.jaxrs</artifactId>
+	<packaging>eclipse-plugin</packaging>
+
+	<name>M2E-WTP :: JAX-RS Support</name>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/MavenJaxRsActivator.java b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/MavenJaxRsActivator.java
new file mode 100644
index 0000000..41670d5
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/MavenJaxRsActivator.java
@@ -0,0 +1,56 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.jaxrs.internal;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ * 
+ * @author Fred Bricon
+ */
+public class MavenJaxRsActivator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.m2e.wtp.jaxrs"; //$NON-NLS-1$
+
+	// The shared instance
+	private static MavenJaxRsActivator plugin;
+	
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 */
+	public static MavenJaxRsActivator getDefault() {
+		return plugin;
+	}
+	
+}
diff --git a/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/MavenJaxRsConstants.java b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/MavenJaxRsConstants.java
new file mode 100644
index 0000000..dcba94f
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/MavenJaxRsConstants.java
@@ -0,0 +1,50 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.jaxrs.internal;
+
+import org.eclipse.jst.ws.jaxrs.core.internal.IJAXRSCoreConstants;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * 
+ * @author Fred Bricon
+ *
+ */
+public class MavenJaxRsConstants {
+	
+	public static final String JAXRS_CONFIGURATION_ERROR_MARKER_ID = "org.eclipse.m2e.core.maven2Problem.wtp.jaxrs.configuration"; //$NON-NLS-1$
+
+	public static final IProjectFacet JAX_RS_FACET; 
+
+	public static final IProjectFacetVersion JAX_RS_FACET_1_0; 
+	
+	public static final IProjectFacetVersion JAX_RS_FACET_1_1; 
+	
+	public static final IProjectFacetVersion JAX_RS_FACET_2_0; 
+
+	static {
+		JAX_RS_FACET = ProjectFacetsManager.getProjectFacet(IJAXRSCoreConstants.JAXRS_FACET_ID);
+		JAX_RS_FACET_1_0 = JAX_RS_FACET.getVersion(IJAXRSCoreConstants.JAXRS_VERSION_1_0);
+		JAX_RS_FACET_1_1 = JAX_RS_FACET.getVersion(IJAXRSCoreConstants.JAXRS_VERSION_1_1);
+		if (JAX_RS_FACET.hasVersion("2.0")) { //$NON-NLS-1$
+			JAX_RS_FACET_2_0 = JAX_RS_FACET.getVersion("2.0"); //$NON-NLS-1$
+		} else {
+			JAX_RS_FACET_2_0 = JAX_RS_FACET_1_1; 
+		}
+	}
+	
+	/**
+	 * Private constructor to prevent instanciation.
+	 */
+	private MavenJaxRsConstants() {};
+}
diff --git a/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/Messages.java b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/Messages.java
new file mode 100644
index 0000000..c092059
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/Messages.java
@@ -0,0 +1,33 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Snjezana Peco (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.jaxrs.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * I18N messages
+ * 
+ * @author snjeza
+ *
+ */
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.m2e.wtp.jaxrs.internal.messages"; //$NON-NLS-1$
+	public static String ClasspathJaxRsFacetDetector_Unable_To_Determine_JAXRS_Version;
+	public static String JaxrsProjectConfigurator_facet_cannot_be_installed;
+	public static String JaxRsProjectConfigurator_Unknown_Error;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/configurators/ClasspathJaxRsFacetDetector.java b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/configurators/ClasspathJaxRsFacetDetector.java
new file mode 100644
index 0000000..c6cdab0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/configurators/ClasspathJaxRsFacetDetector.java
@@ -0,0 +1,74 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2013 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.jaxrs.internal.configurators;
+
+import static org.eclipse.m2e.wtp.jaxrs.internal.MavenJaxRsConstants.JAX_RS_FACET_1_0;
+import static org.eclipse.m2e.wtp.jaxrs.internal.MavenJaxRsConstants.JAX_RS_FACET_1_1;
+import static org.eclipse.m2e.wtp.jaxrs.internal.MavenJaxRsConstants.JAX_RS_FACET_2_0;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.facets.AbstractFacetDetector;
+import org.eclipse.m2e.wtp.jaxrs.internal.Messages;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Inspects the project classpath to detect JAX-RS classes.  
+ * 
+ * @author Fred Bricon
+ *
+ */
+public class ClasspathJaxRsFacetDetector extends AbstractFacetDetector {
+
+	private static final Logger LOG = LoggerFactory.getLogger(ClasspathJaxRsFacetDetector.class);
+
+	@Override
+	public IProjectFacetVersion findFacetVersion(IMavenProjectFacade mavenProjectFacade, Map<?, ?> context, IProgressMonitor monitor) {
+		IProject project = mavenProjectFacade.getProject();
+		if (project == null) {
+			return null;
+		}
+		
+		IJavaProject javaProject = JavaCore.create(project);
+		if (javaProject != null) {
+			IType type = null;
+			try {
+				type = javaProject.findType("javax.ws.rs.client.Client"); //$NON-NLS-1$
+				if (type != null) {
+					return JAX_RS_FACET_2_0;
+				}
+
+				type = javaProject.findType("javax.ws.rs.ApplicationPath");//$NON-NLS-1$ 
+				if (type != null) {
+					return JAX_RS_FACET_1_1;
+				}
+
+				type = javaProject.findType("javax.ws.rs.Path");//$NON-NLS-1$ 
+				if (type != null) {
+					return JAX_RS_FACET_1_0;
+				}
+			} catch (JavaModelException e) {
+				LOG.error(Messages.ClasspathJaxRsFacetDetector_Unable_To_Determine_JAXRS_Version, e);
+			}
+		}
+		return null;
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/configurators/JaxRsLifecycleMapping.java b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/configurators/JaxRsLifecycleMapping.java
new file mode 100644
index 0000000..a72952b
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/configurators/JaxRsLifecycleMapping.java
@@ -0,0 +1,22 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2012 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.jaxrs.internal.configurators;
+
+import org.eclipse.m2e.core.project.configurator.AbstractCustomizableLifecycleMapping;
+
+/**
+ * JAX-RS Lifecycle Mapping
+ * 
+ * @author Fred Bricon
+ */
+public class JaxRsLifecycleMapping extends AbstractCustomizableLifecycleMapping {
+
+}
diff --git a/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/configurators/JaxRsProjectConfigurator.java b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/configurators/JaxRsProjectConfigurator.java
new file mode 100644
index 0000000..ffd9710
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/configurators/JaxRsProjectConfigurator.java
@@ -0,0 +1,185 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2014 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.jaxrs.internal.configurators;
+
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.isWTPProject;
+import static org.eclipse.m2e.wtp.jaxrs.internal.MavenJaxRsConstants.JAX_RS_FACET;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderFramework;
+import org.eclipse.jst.ws.jaxrs.core.internal.IJAXRSCoreConstants;
+import org.eclipse.jst.ws.jaxrs.core.internal.project.facet.IJAXRSFacetInstallDataModelProperties;
+import org.eclipse.jst.ws.jaxrs.core.internal.project.facet.JAXRSFacetInstallDataModelProvider;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.MavenProjectChangedEvent;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+import org.eclipse.m2e.wtp.ProjectUtils;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.m2e.wtp.WarPluginConfiguration;
+import org.eclipse.m2e.wtp.facets.FacetDetectorManager;
+import org.eclipse.m2e.wtp.jaxrs.internal.MavenJaxRsConstants;
+import org.eclipse.m2e.wtp.jaxrs.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * JAX-RS maven project configurator.
+ * <p>
+ * This configurator adds the JAX-RS facet to a project if it has a dependency on the JAX-RS API.
+ * </p>
+ * 
+ * @author Fred Bricon
+ *
+ */
+public class JaxRsProjectConfigurator extends AbstractProjectConfigurator {
+
+	private static final String WAR_PACKAGING = "war"; //$NON-NLS-1$
+	
+	private static final String M2E_JAXRS_ACTIVATION_PROPERTY = "m2e.jaxrs.activation"; //$NON-NLS-1$
+
+	@Override
+	public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
+		configureInternal(request.getMavenProjectFacade(), monitor);
+	}
+
+	private void configureInternal(IMavenProjectFacade mavenProjectFacade,
+			IProgressMonitor monitor) throws CoreException {
+
+		MavenProject mavenProject = mavenProjectFacade.getMavenProject(monitor);
+		if(!WAR_PACKAGING.equals(mavenProject.getPackaging())) {
+			return;
+		}
+
+		if (!isConfigurationEnabled(mavenProjectFacade, monitor)) {
+			return;
+		}
+		IProject project = mavenProjectFacade.getProject();
+		
+    	final IFacetedProject fproj = ProjectFacetsManager.create(project);
+    	if (fproj == null) {
+    		return;
+    	}
+    	
+		if ((!fproj.hasProjectFacet(WTPProjectsUtil.DYNAMIC_WEB_FACET)) 
+				|| fproj.hasProjectFacet(JAX_RS_FACET)) {
+			//everything already installed. Since there's no support for version update -yet- we bail
+			return;
+		}
+		
+		FacetDetectorManager facetDetectorManager = FacetDetectorManager.getInstance();
+		IProjectFacetVersion jaxRsVersion = facetDetectorManager.findFacetVersion(mavenProjectFacade, JAX_RS_FACET.getId(), monitor);
+	    if (jaxRsVersion != null) {
+	      installJaxRsFacet(fproj, jaxRsVersion, mavenProject, monitor);
+	    }
+
+	}
+
+	private boolean isConfigurationEnabled(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
+		if (WTPProjectsUtil.isM2eWtpDisabled(facade, monitor)) {
+			return false;
+		}
+		
+		Object pomActivationValue = facade.getMavenProject(monitor).getProperties().get(M2E_JAXRS_ACTIVATION_PROPERTY);
+		boolean enabled;
+		if (pomActivationValue == null) {
+			enabled = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().isEnabled(getId());
+		} else {
+			enabled = Boolean.parseBoolean(pomActivationValue.toString());
+		}	
+		return enabled;
+	}
+
+	@SuppressWarnings("restriction")
+	private void installJaxRsFacet(IFacetedProject fproj, IProjectFacetVersion facetVersion,
+			MavenProject mavenProject, IProgressMonitor monitor) throws CoreException {
+
+		markerManager.deleteMarkers(fproj.getProject(), MavenJaxRsConstants.JAXRS_CONFIGURATION_ERROR_MARKER_ID);
+
+		IStatus status = facetVersion.getConstraint().check(fproj.getProjectFacets());
+		if (status.isOK()) {
+			// refreshing the project hierarchy to make sure that Eclipse "sees" the .settings folder and file, 
+			// to be able to add the JAX-RS Facet. see https://issues.jboss.org/browse/JBIDE-10037
+			ProjectUtils.refreshHierarchy(mavenProject.getBasedir(), 
+					                      IResource.DEPTH_INFINITE, 
+					                      new SubProgressMonitor(monitor, 1));
+			IDataModel model = createJaxRsDataModel(fproj,facetVersion);
+			WarPluginConfiguration warConfig = new WarPluginConfiguration(mavenProject, fproj.getProject());
+			String warSourceDirectory = warConfig.getWarSourceDirectory();
+			model.setProperty(IJAXRSFacetInstallDataModelProperties.WEBCONTENT_DIR, warSourceDirectory);
+			model.setProperty(IJAXRSFacetInstallDataModelProperties.UPDATEDD, false);
+			fproj.installProjectFacet(facetVersion, model, monitor);
+		} else {
+			String errorMessage = status.getMessage() == null ? Messages.JaxRsProjectConfigurator_Unknown_Error:status.getMessage();
+			String markerMessage = NLS.bind(Messages.JaxrsProjectConfigurator_facet_cannot_be_installed, 
+									facetVersion, errorMessage);
+	        addErrorMarker(fproj.getProject(), markerMessage);
+			for (IStatus st : status.getChildren()) {
+		        addErrorMarker(fproj.getProject(), st.getMessage());
+			}
+		}
+	}
+
+
+	@SuppressWarnings("restriction")
+	private IDataModel createJaxRsDataModel(IFacetedProject fproj,
+			IProjectFacetVersion facetVersion) {
+		IDataModel config = (IDataModel) new JAXRSFacetInstallDataModelProvider().create();
+		LibraryInstallDelegate libraryDelegate = new LibraryInstallDelegate(fproj, facetVersion);
+		ILibraryProvider provider = LibraryProviderFramework.getProvider(IJAXRSCoreConstants.NO_OP_LIBRARY_ID);
+		libraryDelegate.setLibraryProvider(provider);
+		config.setProperty(IJAXRSFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE, libraryDelegate);
+		return config;
+	}
+
+	@SuppressWarnings("restriction")
+	private void addErrorMarker(IProject project, String message) {
+	    markerManager.addMarker(project, 
+	    		MavenJaxRsConstants.JAXRS_CONFIGURATION_ERROR_MARKER_ID, 
+	    		message
+	    		,-1,  IMarker.SEVERITY_ERROR);
+	}
+	
+	@Override
+	public void mavenProjectChanged(MavenProjectChangedEvent event,
+			IProgressMonitor monitor) throws CoreException {
+		IMavenProjectFacade facade = event.getMavenProject();
+	    if(facade != null) {
+	      IProject project = facade.getProject();
+	      MavenProject mavenProject = facade.getMavenProject(monitor);
+	      if(isWTPProject(project) && WAR_PACKAGING.equals(mavenProject.getPackaging())) {
+		    IMavenProjectFacade oldFacade = event.getOldMavenProject();
+		    if (oldFacade != null) {
+		    	MavenProject oldProject = oldFacade.getMavenProject(monitor);
+		    	if (oldProject != null && oldProject.getArtifacts().equals(mavenProject.getArtifacts())) {
+		    		//Nothing changed since last build, no need to lookup for new Facets
+		    		return;
+		    	}
+		    }
+	        configureInternal(facade, monitor);
+	      }
+	    }
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/messages.properties b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/messages.properties
new file mode 100644
index 0000000..0ec80c2
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jaxrs/src/org/eclipse/m2e/wtp/jaxrs/internal/messages.properties
@@ -0,0 +1,4 @@
+ClasspathJaxRsFacetDetector_Unable_To_Determine_JAXRS_Version=Unable to determine JAX-RS version
+JaxrsProjectConfigurator_The_project_does_not_contain_required_facets=The {0} project does not contain the Dynamic Web Module facet or the EJB Module facet required to enable JAX-RS support.
+JaxrsProjectConfigurator_facet_cannot_be_installed={0} can not be installed : {1}
+JaxRsProjectConfigurator_Unknown_Error=<unknown error>
diff --git a/org.eclipse.m2e.wtp.jpa.feature/pom.xml b/org.eclipse.m2e.wtp.jpa.feature/pom.xml
index 35c68d0..2a3486c 100644
--- a/org.eclipse.m2e.wtp.jpa.feature/pom.xml
+++ b/org.eclipse.m2e.wtp.jpa.feature/pom.xml
@@ -4,7 +4,7 @@
 	<modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.eclipse.m2e.wtp</groupId>
-    <artifactId>org.eclipse.m2e.wtp.jpa.parent</artifactId>
+    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
     <version>1.3.0-SNAPSHOT</version>
   </parent>
 
@@ -14,4 +14,3 @@
   <name>M2E-WTP :: JPA Support Feature</name>
 
 </project>
-
diff --git a/org.eclipse.m2e.wtp.jpa.site/category.xml b/org.eclipse.m2e.wtp.jpa.site/category.xml
deleted file mode 100644
index 8884fdb..0000000
--- a/org.eclipse.m2e.wtp.jpa.site/category.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<site>
-   <feature url="features/org.eclipse.m2e.wtp.jpa.feature_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.jpa.feature" version="0.0.0">
-      <category name="m2e-wtp"/>
-   </feature>
-   <category-def name="m2e-wtp" label="Maven Integration for WTP"/>
-   
-   <feature url="features/org.eclipse.m2e.wtp.jpa.feature.source_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.jpa.feature.source" version="0.0.0">
-      <category name="m2e-wtp-sdk"/>
-   </feature>
-
-   <category-def name="m2e-wtp-sdk" label="Maven Integration for WTP - SDK"/>
-
-</site>
diff --git a/org.eclipse.m2e.wtp.jpa/pom.xml b/org.eclipse.m2e.wtp.jpa/pom.xml
index 8da64df..8915397 100644
--- a/org.eclipse.m2e.wtp.jpa/pom.xml
+++ b/org.eclipse.m2e.wtp.jpa/pom.xml
@@ -4,7 +4,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<parent>
 		<groupId>org.eclipse.m2e.wtp</groupId>
-		<artifactId>org.eclipse.m2e.wtp.jpa.parent</artifactId>
+		<artifactId>org.eclipse.m2e.wtp.parent</artifactId>
 		<version>1.3.0-SNAPSHOT</version>
 	</parent>
 
@@ -12,4 +12,4 @@
 	<packaging>eclipse-plugin</packaging>
 
 	<name>M2E-WTP :: JPA Support</name>
-</project>
\ No newline at end of file
+</project>
diff --git a/org.eclipse.m2e.wtp.jsf.feature/.gitignore b/org.eclipse.m2e.wtp.jsf.feature/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/org.eclipse.m2e.wtp.jsf.feature/.project b/org.eclipse.m2e.wtp.jsf.feature/.project
new file mode 100644
index 0000000..e2d475a
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp.jsf.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp.jsf.feature/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.jsf.feature/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.jsf.feature/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.jsf.feature/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.jsf.feature/build.properties b/org.eclipse.m2e.wtp.jsf.feature/build.properties
new file mode 100644
index 0000000..e2bd14c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/build.properties
@@ -0,0 +1,3 @@
+bin.includes = feature.xml,\
+               p2.inf,\
+               feature.properties
diff --git a/org.eclipse.m2e.wtp.jsf.feature/feature.properties b/org.eclipse.m2e.wtp.jsf.feature/feature.properties
new file mode 100644
index 0000000..3dd932c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/feature.properties
@@ -0,0 +1,40 @@
+###############################################################################
+# Copyright (c) 2008, 2012 Red Hat, Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     Red Hat, Inc. - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=m2e-wtp - JSF configurator for WTP (Optional)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org - m2e-wtp
+
+# "updateSiteName" property - label for the update site
+#updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=m2e JSF project configurator for Eclipse WTP.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2008-2014 Red Hat, Inc and others.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+     Red Hat, Inc. - Java EE configurators\n
+
+################ end of copyright property ####################################
diff --git a/org.eclipse.m2e.wtp.jsf.feature/feature.xml b/org.eclipse.m2e.wtp.jsf.feature/feature.xml
new file mode 100644
index 0000000..0c07af0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/feature.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.m2e.wtp.jsf.feature"
+      label="%featureName"
+      version="1.3.0.qualifier"
+      provider-name="%providerName"
+      plugin="org.eclipse.m2e.wtp.jsf"
+      license-feature="org.eclipse.license"
+      license-feature-version="0.0.0">
+   <install-handler/>
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <requires>
+      <import feature="org.eclipse.platform" version="3.6.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.rcp" version="3.6.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jdt" version="3.6.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.wst.web_ui.feature" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jst.enterprise_ui.feature" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.wst.common.fproj" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jst.common.fproj.enablement.jdt" version="3.2.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.m2e.feature" version="1.1.0" match="greaterOrEqual"/>
+      <import feature="org.eclipse.jsf.feature" version="3.0.0" match="greaterOrEqual"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.m2e.wtp.jsf"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/org.eclipse.m2e.wtp.jsf.feature/p2.inf b/org.eclipse.m2e.wtp.jsf.feature/p2.inf
new file mode 100644
index 0000000..db97d38
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/p2.inf
@@ -0,0 +1,17 @@
+units.1.id=org.jboss.tools.maven.jsf
+units.1.properties.0.name=org.eclipse.equinox.p2.name
+units.1.properties.0.value=This version of the JSF configurator cannot be installed on top of the already installed org.jboss.tools.maven.jsf plugin. Uninstall the previous version of org.jboss.tools.maven.jsf and try the install again.
+units.1.properties.1.name=maven-classifier
+units.1.properties.1.value=p2inf
+units.1.version=$version$
+units.1.singleton=true
+units.1.provides.0.namespace=osgi.bundle
+units.1.provides.0.name=org.jboss.tools.maven.jsf
+units.1.provides.0.version=$version$
+
+requires.0.namespace=osgi.bundle
+requires.0.name=org.jboss.tools.maven.jsf
+requires.0.range=[$version$, $version$]
+
+update.matchExp=providedCapabilities.exists(pc | pc.namespace \=\= 'org.eclipse.equinox.p2.iu' && (pc.name \=\= 'org.jboss.tools.maven.jsf.feature.feature.group' || pc.name \=\= 'org.eclipse.m2e.wtp.jsf.feature.feature.group' && pc.version < '$version$'))
+
diff --git a/org.eclipse.m2e.wtp.jsf.feature/pom.xml b/org.eclipse.m2e.wtp.jsf.feature/pom.xml
new file mode 100644
index 0000000..e6f5cf5
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.eclipse.m2e.wtp</groupId>
+    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.m2e.wtp.jsf.feature</artifactId>
+  <packaging>eclipse-feature</packaging>
+
+  <name>M2E-WTP :: JSF Support Feature</name>
+
+</project>
+
diff --git a/org.eclipse.m2e.wtp.jsf.feature/sdk b/org.eclipse.m2e.wtp.jsf.feature/sdk
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf.feature/sdk
diff --git a/org.eclipse.m2e.wtp.jsf/.classpath b/org.eclipse.m2e.wtp.jsf/.classpath
new file mode 100644
index 0000000..46cec6e
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/org.eclipse.m2e.wtp.jsf/.gitignore b/org.eclipse.m2e.wtp.jsf/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/org.eclipse.m2e.wtp.jsf/.project b/org.eclipse.m2e.wtp.jsf/.project
new file mode 100644
index 0000000..c7be778
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp.jsf</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp.jsf/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.jsf/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.jsf/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.m2e.wtp.jsf/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..935535c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,99 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/org.eclipse.m2e.wtp.jsf/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.jsf/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.jsf/META-INF/MANIFEST.MF b/org.eclipse.m2e.wtp.jsf/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a350a98
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/META-INF/MANIFEST.MF
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.m2e.wtp.jsf;singleton:=true
+Bundle-Version: 1.3.0.qualifier
+Bundle-Activator: org.eclipse.m2e.wtp.jsf.internal.MavenJSFActivator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.jst.j2ee.core,
+ org.eclipse.jst.j2ee,
+ org.eclipse.wst.common.emfworkbench.integration,
+ org.eclipse.jst.jsf.core;bundle-version="1.3.4",
+ org.eclipse.core.resources,
+ org.eclipse.emf.common,
+ org.eclipse.m2e.core;bundle-version="[1.6.0,2.0.0)",
+ org.eclipse.m2e.maven.runtime;bundle-version="[1.6.0,2.0.0)",
+ org.eclipse.wst.common.frameworks,
+ org.eclipse.wst.common.project.facet.core,
+ org.eclipse.jst.common.project.facet.core,
+ org.eclipse.jdt.core,
+ org.eclipse.jst.j2ee.web,
+ org.slf4j.api,
+ org.eclipse.m2e.wtp
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-Vendor: %Bundle-Vendor
+Bundle-Localization: plugin
+Export-Package: org.eclipse.m2e.wtp.jsf.internal,org.eclipse.m2e.wtp.j
+ sf.internal.configurators,org.eclipse.m2e.wtp.jsf.internal.utils
diff --git a/org.eclipse.m2e.wtp.jsf/about.html b/org.eclipse.m2e.wtp.jsf/about.html
new file mode 100644
index 0000000..f73d742
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/about.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About Maven JSF Configurator</title>
+</head>
+<body lang="EN-US">
+<h3>Maven JSF Configurator</h3>
+<p>m2e configurator setting the JSF Facet on projects having JSF Dependencies</p>
+ 
+<p>October 29, 2010</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
diff --git a/org.eclipse.m2e.wtp.jsf/about.ini b/org.eclipse.m2e.wtp.jsf/about.ini
new file mode 100644
index 0000000..2a3e3ee
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/about.ini
@@ -0,0 +1,27 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+# test
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%blurb
+
+# Property "windowImage" contains path to window icon (16x16)
+# needed for primary features only
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=m2e-wtp_icon_32px.png
+
+# Property "aboutImage" contains path to product image (500x330 or 115x164)
+# needed for primary features only
+
+# Property "appName" contains name of the application (not translated)
+# needed for primary features only
+
+# Property "welcomePerspective" contains the id of the perspective in which the
+# welcome page is to be opened.
+# optional
+
+
+
diff --git a/org.eclipse.m2e.wtp.jsf/about.mappings b/org.eclipse.m2e.wtp.jsf/about.mappings
new file mode 100644
index 0000000..c367bc8
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/about.mappings
@@ -0,0 +1,5 @@
+# about.mappings
+# contains fill-ins for about.properties
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file does not need to be translated.
+
diff --git a/org.eclipse.m2e.wtp.jsf/about.properties b/org.eclipse.m2e.wtp.jsf/about.properties
new file mode 100644
index 0000000..856847c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/about.properties
@@ -0,0 +1,2 @@
+blurb=m2e JSF project configurator for Eclipse WTP\n\nVersion\: {featureVersion}\n\n(c) Copyright (c) Red Hat, Inc. and others 2011 - 2014.  All rights reserved.\nVisit http\://www.eclipse.org/m2e-wtp
+
diff --git a/org.eclipse.m2e.wtp.jsf/build.properties b/org.eclipse.m2e.wtp.jsf/build.properties
new file mode 100644
index 0000000..638a219
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/build.properties
@@ -0,0 +1,16 @@
+source.. = src/
+output.. = target/classes/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               plugin.properties,\
+               about.html,\
+               about.ini,\
+               about.mappings,\
+               about.properties,\
+               lifecycle-mapping-metadata.xml,\
+               m2e-wtp_icon_32px.png
+src.includes = about.html,\
+               about.ini,\
+               about.mappings,\
+               about.properties
diff --git a/org.eclipse.m2e.wtp.jsf/lifecycle-mapping-metadata.xml b/org.eclipse.m2e.wtp.jsf/lifecycle-mapping-metadata.xml
new file mode 100644
index 0000000..5a6e8bd
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/lifecycle-mapping-metadata.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lifecycleMappingMetadata>
+  
+      <pluginExecutions>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-war-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>war</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.eclipse.m2e.wtp.jsf.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>
+      </pluginExecutions>
+
+</lifecycleMappingMetadata>
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.jsf/m2e-wtp_icon_32px.png b/org.eclipse.m2e.wtp.jsf/m2e-wtp_icon_32px.png
new file mode 100644
index 0000000..2d37574
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/m2e-wtp_icon_32px.png
Binary files differ
diff --git a/org.eclipse.m2e.wtp.jsf/plugin.properties b/org.eclipse.m2e.wtp.jsf/plugin.properties
new file mode 100644
index 0000000..6e846c2
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/plugin.properties
@@ -0,0 +1,10 @@
+Bundle-Vendor=Eclipse.org - m2e-wtp
+Bundle-Name=Maven JSF Configurator
+JSF_Project_configurator=JSF configurator
+JSF_Lifecycle_mapping=JSF Lifecycle mapping
+Maven_Configuration_Problem=Maven Java EE Configuration Problem
+Maven_Configuration_Problems=Maven Java EE Configuration Problems
+jsf_enabler_label=JSF Configurator
+jsf_enabler_description=The JSF Configurator adds the JSF Facet to Dynamic Web projects if JSF classpath dependencies are found.
+template.jsfActivationProperty.name=m2e-wtp JSF activation
+template.jsfActivationProperty.description=Enable or disable automatic JSF configuration
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.jsf/plugin.xml b/org.eclipse.m2e.wtp.jsf/plugin.xml
new file mode 100644
index 0000000..5ba08a6
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/plugin.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+    <extension
+         point="org.eclipse.m2e.core.lifecycleMappingMetadataSource">
+    </extension>
+   
+    <extension
+         point="org.eclipse.m2e.core.lifecycleMappings">
+      <lifecycleMapping
+            class="org.eclipse.m2e.wtp.jsf.internal.configurators.JSFLifecycleMapping"
+            id="org.eclipse.m2e.wtp.jsf.JSFLifecycleMapping"
+            name="%JSF_Lifecycle_mapping">
+      </lifecycleMapping>
+    </extension>
+ 
+	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.eclipse.m2e.wtp.jsf.configurator"
+          class="org.eclipse.m2e.wtp.jsf.internal.configurators.JSFProjectConfigurator"
+          name="%JSF_Project_configurator"
+          secondaryTo="org.maven.ide.eclipse.configuration.wtp.configurator"/>
+    </extension>
+    
+     <extension point="org.eclipse.core.resources.markers"
+         id="org.eclipse.m2e.core.maven2Problem.wtp.jsf.configuration"
+         name="%Maven_Configuration_Problem">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <persistent value="true"/>
+    </extension>
+    <extension
+         point="org.eclipse.m2e.wtp.javaeeConfiguratorEnabler">
+         <javaeeConfiguratorEnabler
+           id="org.eclipse.m2e.wtp.jsf.enabler"
+           label="%jsf_enabler_label"
+           description="%jsf_enabler_description"
+           configuratorIds="org.eclipse.m2e.wtp.jsf.configurator"
+         />
+    </extension>
+
+   <extension
+         point="org.eclipse.m2e.wtp.facetDetectors">
+         <facetDetector
+           facetId="jst.jsf"
+           class="org.eclipse.m2e.wtp.jsf.internal.configurators.FacesConfigJSFFacetDetector"
+           priority="10"
+         />
+         <facetDetector
+           facetId="jst.jsf"
+           class="org.eclipse.m2e.wtp.jsf.internal.configurators.ClasspathJSFFacetDetector"
+           priority="20"
+         />
+         <facetDetector
+           facetId="jst.jsf"
+           class="org.eclipse.m2e.wtp.jsf.internal.configurators.WebXmlJSFFacetDetector"
+           priority="30"
+         />
+   </extension>
+   
+   <extension point="org.eclipse.ui.editors.templates">
+    <template id="org.eclipse.m2e.wtp.jsf.xml.templates.jsfActivationProperty"
+         contextTypeId="org.eclipse.m2e.editor.xml.templates.contextType.properties"
+         name="%template.jsfActivationProperty.name" 
+         description="%template.jsfActivationProperty.description">
+      <pattern>&lt;m2e.jsf.activation&gt;${cursor}${false}&lt;/m2e.jsf.activation&gt;</pattern>
+    </template>
+   </extension>    
+</plugin>
diff --git a/org.eclipse.m2e.wtp.jsf/pom.xml b/org.eclipse.m2e.wtp.jsf/pom.xml
new file mode 100644
index 0000000..536ba0e
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.eclipse.m2e.wtp</groupId>
+		<artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+		<version>1.3.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>org.eclipse.m2e.wtp.jsf</artifactId>
+	<packaging>eclipse-plugin</packaging>
+
+	<name>M2E-WTP :: JSF Support</name>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/MavenJSFActivator.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/MavenJSFActivator.java
new file mode 100644
index 0000000..baa253c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/MavenJSFActivator.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2011-2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Snjezana Peco (Red Hat, Inc.) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.m2e.wtp.jsf.internal;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * 
+ * @author snjeza
+ *
+ */
+public class MavenJSFActivator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.m2e.wtp.jsf"; //$NON-NLS-1$
+
+	private static BundleContext context;
+	
+	// The shared instance
+	private static MavenJSFActivator plugin;
+
+	static BundleContext getContext() {
+		return context;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext bundleContext) throws Exception {
+		super.start(bundleContext);
+		MavenJSFActivator.plugin = this;
+		MavenJSFActivator.context = bundleContext;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext bundleContext) throws Exception {
+		MavenJSFActivator.context = null;
+		MavenJSFActivator.plugin = null;
+		super.stop(bundleContext);
+	}
+	
+	public static MavenJSFActivator getDefault() {
+		return plugin;
+	}
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/MavenJSFConstants.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/MavenJSFConstants.java
new file mode 100644
index 0000000..68a724d
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/MavenJSFConstants.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.m2e.wtp.jsf.internal;
+
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @author Fred Bricon
+ */
+public class MavenJSFConstants {
+	
+	public static final String JSF_CONFIGURATION_ERROR_MARKER_ID = "org.eclipse.m2e.core.maven2Problem.wtp.jsf.configuration"; //$NON-NLS-1$
+
+	public static final String JSF_VERSION_2_2 = "2.2"; //$NON-NLS-1$
+	
+	public static final String JSF_VERSION_2_1 = "2.1"; //$NON-NLS-1$
+
+	public static final String JSF_VERSION_2_0 = "2.0"; //$NON-NLS-1$
+	
+	public static final String JSF_VERSION_1_2 = "1.2"; //$NON-NLS-1$
+	
+	public static final String JSF_VERSION_1_1 = "1.1"; //$NON-NLS-1$
+	
+	public static final IProjectFacet JSF_FACET;
+	
+	public static final IProjectFacetVersion JSF_FACET_VERSION_2_2;
+
+	public static final IProjectFacetVersion JSF_FACET_VERSION_2_1;
+	
+	public static final IProjectFacetVersion JSF_FACET_VERSION_2_0;
+	
+	public static final IProjectFacetVersion JSF_FACET_VERSION_1_2;
+	
+	public static final IProjectFacetVersion JSF_FACET_VERSION_1_1;
+
+	private static final Logger LOG = LoggerFactory.getLogger(MavenJSFConstants.class);
+	
+	static {
+		JSF_FACET = ProjectFacetsManager.getProjectFacet("jst.jsf"); //$NON-NLS-1$
+		JSF_FACET_VERSION_2_0 = JSF_FACET.getVersion(JSF_VERSION_2_0); 
+		JSF_FACET_VERSION_1_2 = JSF_FACET.getVersion(JSF_VERSION_1_2); 
+		JSF_FACET_VERSION_1_1 = JSF_FACET.getVersion(JSF_VERSION_1_1);
+		
+		IProjectFacetVersion jsf21Version = null;
+		try {
+			jsf21Version = JSF_FACET.getVersion(JSF_VERSION_2_1); 
+		} catch (Exception e) {
+			LOG.warn(Messages.MavenJSFConstants_Warning_JSF21_Unavailable);
+			jsf21Version = JSF_FACET_VERSION_2_0; 
+		}
+		JSF_FACET_VERSION_2_1 = jsf21Version;
+
+		IProjectFacetVersion jsf22Version = null;
+		try {
+			jsf22Version = JSF_FACET.getVersion(JSF_VERSION_2_2); 
+		} catch (Exception e) {
+			LOG.warn(NLS.bind(Messages.MavenJSFConstants_Warning_JSF22_Unavailable, JSF_FACET_VERSION_2_1.getVersionString()));
+			jsf22Version = JSF_FACET_VERSION_2_1; 
+		}
+		JSF_FACET_VERSION_2_2 = jsf22Version;
+	}
+	
+	
+	/**
+	 * Private constructor to prevent instantiation.
+	 */
+	private MavenJSFConstants() {};
+	
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/Messages.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/Messages.java
new file mode 100644
index 0000000..dbaa07b
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/Messages.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011-2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Snjezana Peco (Red Hat, Inc.) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.m2e.wtp.jsf.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * 
+ * @author snjeza
+ *
+ */
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.m2e.wtp.jsf.internal.messages"; //$NON-NLS-1$
+	public static String JSFAppConfigUtils_Error_Reading_WebXml;
+	public static String JSFProjectConfigurator_Marker_Facet_Version_Cant_Be_Installed;
+	public static String JSFProjectConfigurator_The_project_does_not_contain_the_Web_Module_facet;
+	public static String JSFUtils_Error_Finding_Faces_Servlet;
+	public static String JSFUtils_Error_Finding_Faces_Servlet_In_WebXml;
+	public static String JSFUtils_Error_Finding_JSF_Version;
+	public static String JSFUtils_Error_Finding_Latest_JSF_Version;
+	public static String JSFUtils_Error_Reading_FacesConfig;
+	public static String JSFUtils_Error_Searching_For_JSF_Type;
+	public static String MavenJSFConstants_Warning_JSF21_Unavailable;
+	public static String MavenJSFConstants_Warning_JSF22_Unavailable;
+	public static String WebXmlJSFFacetDetector_Error_Cant_Detect_JSF_From_WebXml;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/ClasspathJSFFacetDetector.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/ClasspathJSFFacetDetector.java
new file mode 100644
index 0000000..eab81b8
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/ClasspathJSFFacetDetector.java
@@ -0,0 +1,41 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2013 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.jsf.internal.configurators;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.facets.AbstractFacetDetector;
+import org.eclipse.m2e.wtp.jsf.internal.utils.JSFUtils;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * Inspects the project classpath to determine the JSF version from known JSF classes.
+ * 
+ * @author Fred Bricon
+ * @since 0.18.0
+ */
+public class ClasspathJSFFacetDetector extends AbstractFacetDetector {
+
+	@Override
+	public IProjectFacetVersion findFacetVersion(IMavenProjectFacade mavenProjectFacade, Map<?, ?> context, IProgressMonitor monitor) {
+		IProject project = mavenProjectFacade.getProject();
+		if (project == null) {
+			return null;
+		}
+
+		String version = JSFUtils.getJSFVersionFromClasspath(project);
+		return (version == null)?null:JSFUtils.getSafeJSFFacetVersion(version);
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/FacesConfigJSFFacetDetector.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/FacesConfigJSFFacetDetector.java
new file mode 100644
index 0000000..227cfd7
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/FacesConfigJSFFacetDetector.java
@@ -0,0 +1,40 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2013 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.jsf.internal.configurators;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.facets.AbstractFacetDetector;
+import org.eclipse.m2e.wtp.jsf.internal.utils.JSFUtils;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * Inspects the project faces-config to determine the JSF Facet version.
+ * 
+ * @author Fred Bricon
+ * @since 0.18.0
+ */
+public class FacesConfigJSFFacetDetector extends AbstractFacetDetector {
+
+	@Override
+	public IProjectFacetVersion findFacetVersion(IMavenProjectFacade mavenProjectFacade, Map<?, ?> context, IProgressMonitor monitor) {
+		IProject project = mavenProjectFacade.getProject();
+		if (project == null) {
+			return null;
+		}
+		String version = JSFUtils.getVersionFromFacesconfig(project);
+		return version == null ? null : JSFUtils.getSafeJSFFacetVersion(version);
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/JSFLifecycleMapping.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/JSFLifecycleMapping.java
new file mode 100644
index 0000000..2a0a444
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/JSFLifecycleMapping.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2011-2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+  *     Snjezna Peco (Red Hat, Inc.) - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.m2e.wtp.jsf.internal.configurators;
+
+import org.eclipse.m2e.core.project.configurator.AbstractCustomizableLifecycleMapping;
+
+/**
+ * JSF Lifecycle Mapping
+ *
+ * @author snjeza
+ */
+public class JSFLifecycleMapping extends AbstractCustomizableLifecycleMapping {
+
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/JSFProjectConfigurator.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/JSFProjectConfigurator.java
new file mode 100644
index 0000000..f916c8a
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/JSFProjectConfigurator.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2011-2014 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Snjezana Peco (Red Hat, Inc.) - initial API and implementation
+ *     Fred Bricon (Red Hat, Inc.)   - read infos from faces-config.xml
+ ******************************************************************************/
+
+package org.eclipse.m2e.wtp.jsf.internal.configurators;
+
+import static org.eclipse.m2e.wtp.jsf.internal.MavenJSFConstants.JSF_FACET;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryInstallDelegate;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderFramework;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.jst.jsf.core.internal.project.facet.IJSFFacetInstallDataModelProperties;
+import org.eclipse.jst.jsf.core.internal.project.facet.JSFFacetInstallDataModelProvider;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+import org.eclipse.m2e.wtp.ProjectUtils;
+import org.eclipse.m2e.wtp.ResourceCleaner;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.m2e.wtp.WarPluginConfiguration;
+import org.eclipse.m2e.wtp.facets.FacetDetectorManager;
+import org.eclipse.m2e.wtp.jsf.internal.MavenJSFConstants;
+import org.eclipse.m2e.wtp.jsf.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * JSF maven project configurator.
+ * <p>
+ * This configurator adds the JSF facet to a project if it has or declares a faces-config.xml.
+ * </p>
+ * @author snjeza
+ * @author Fred Bricon
+ *
+ */
+public class JSFProjectConfigurator extends AbstractProjectConfigurator {
+	
+	private static final String M2E_JSF_ACTIVATION_PROPERTY = "m2e.jsf.activation"; //$NON-NLS-1$
+	
+	@Override
+	public void configure(ProjectConfigurationRequest request,
+			IProgressMonitor monitor) throws CoreException {
+		configureInternal(request.getMavenProjectFacade(), monitor);
+	}
+	
+	private void configureInternal(IMavenProjectFacade mavenProjectFacade,
+			IProgressMonitor monitor) throws CoreException {
+		MavenProject mavenProject = mavenProjectFacade.getMavenProject();
+		IProject project = mavenProjectFacade.getProject();
+		
+		if (!"war".equals(mavenProject.getPackaging()))  {//$NON-NLS-1$
+			return;
+		}
+		
+		if (!isConfigurationEnabled(mavenProjectFacade, monitor)) {
+			return;
+		}
+		
+    	final IFacetedProject fproj = ProjectFacetsManager.create(project);
+		if (fproj != null) {
+			if (fproj.hasProjectFacet(JSF_FACET)) {
+				//everything already installed. 
+				//Since there's no support for version update -yet- we stop here
+				return;
+			}
+			
+			FacetDetectorManager facetDetectorManager = FacetDetectorManager.getInstance();
+			IProjectFacetVersion jsfVersion = facetDetectorManager.findFacetVersion(mavenProjectFacade, JSF_FACET.getId(), monitor);
+			if (jsfVersion != null) { 
+				installJSFFacet(fproj, mavenProject, jsfVersion, monitor);
+			}
+		}
+		
+	}
+
+	private boolean isConfigurationEnabled(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
+		if (WTPProjectsUtil.isM2eWtpDisabled(facade, monitor)) {
+			return false;
+		}
+		
+		Object pomActivationValue = facade.getMavenProject(monitor).getProperties().get(M2E_JSF_ACTIVATION_PROPERTY);
+		boolean enabled;
+		if (pomActivationValue == null) {
+			enabled = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().isEnabled(getId());
+		} else {
+			enabled = Boolean.parseBoolean(pomActivationValue.toString());
+		}	
+		return enabled;
+	}
+	
+	private void installJSFFacet(IFacetedProject fproj, MavenProject mavenProject,
+			IProjectFacetVersion facetVersion, IProgressMonitor monitor)
+			throws CoreException {
+
+		markerManager.deleteMarkers(fproj.getProject(), MavenJSFConstants.JSF_CONFIGURATION_ERROR_MARKER_ID);
+				
+		if (fproj.hasProjectFacet(IJ2EEFacetConstants.DYNAMIC_WEB_FACET) && !fproj.hasProjectFacet(JSF_FACET)) {
+			IProject project = fproj.getProject();
+			//JBIDE-10785 : refresh parent to prevent 
+			// org.osgi.service.prefs.BackingStoreException: Resource '/parent/web/.settings' does not exist.
+			ProjectUtils.refreshHierarchy(mavenProject.getBasedir(), 
+										  IResource.DEPTH_INFINITE, 
+										  new SubProgressMonitor(monitor, 1));
+	
+			WarPluginConfiguration warConfig = new WarPluginConfiguration(mavenProject, project);
+			IFolder warSourceDir  = project.getFolder(warConfig.getWarSourceDirectory());
+
+			//We don't want to generate any files automatically
+			IPath facesConfigPath = new Path("WEB-INF/faces-config.xml"); //$NON-NLS-1$
+			IFile defaultFacesConfig = warSourceDir.getFile(facesConfigPath);
+			IFolder generatedWebResourcesFolder = ProjectUtils.getGeneratedWebResourcesFolder(mavenProject, project);
+			IFile generatedFacesConfig = generatedWebResourcesFolder.getFile(facesConfigPath);
+			
+			ResourceCleaner cleaner = new ResourceCleaner(project);
+			cleaner.addFolder(warSourceDir.getFolder("WEB-INF/lib")); //$NON-NLS-1$
+			cleaner.addFiles(defaultFacesConfig, generatedFacesConfig);
+			
+			IStatus status = facetVersion.getConstraint().check(fproj.getProjectFacets());
+			try {
+				if (status.isOK()) {
+					IDataModel model = createJSFDataModel(fproj,facetVersion);
+					model.setBooleanProperty(IJSFFacetInstallDataModelProperties.CONFIGURE_SERVLET, false);
+					fproj.installProjectFacet(facetVersion, model, monitor);
+				} else {
+					addErrorMarker(fproj.getProject(), NLS.bind(Messages.JSFProjectConfigurator_Marker_Facet_Version_Cant_Be_Installed, facetVersion, status.getMessage()));
+					for (IStatus st : status.getChildren()) {
+						addErrorMarker(fproj.getProject(), st.getMessage());
+					}
+				}
+			} finally {
+				cleaner.cleanUp();
+			} 
+		}
+	}
+	
+	private void addErrorMarker(IProject project, String message) {
+	    markerManager.addMarker(project, 
+	    		MavenJSFConstants.JSF_CONFIGURATION_ERROR_MARKER_ID, 
+	    		message
+	    		,-1,  IMarker.SEVERITY_ERROR);
+		
+	}
+
+	@SuppressWarnings("restriction")
+	private IDataModel createJSFDataModel(IFacetedProject fproj, IProjectFacetVersion facetVersion) {
+		IDataModel config = (IDataModel) new JSFFacetInstallDataModelProvider().create();
+		LibraryInstallDelegate libraryDelegate = new LibraryInstallDelegate(fproj, facetVersion);
+		ILibraryProvider provider = LibraryProviderFramework.getProvider("jsf-no-op-library-provider"); //$NON-NLS-1$
+		libraryDelegate.setLibraryProvider(provider);
+		config.setProperty(IJSFFacetInstallDataModelProperties.LIBRARY_PROVIDER_DELEGATE, libraryDelegate);
+		config.setProperty(IJSFFacetInstallDataModelProperties.SERVLET_NAME, ""); //$NON-NLS-1$
+		config.setProperty(IJSFFacetInstallDataModelProperties.SERVLET_URL_PATTERNS, new String[0]);
+		
+		return config;
+	}
+	
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/WebXmlJSFFacetDetector.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/WebXmlJSFFacetDetector.java
new file mode 100644
index 0000000..b97c02e
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/configurators/WebXmlJSFFacetDetector.java
@@ -0,0 +1,83 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2013 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.jsf.internal.configurators;
+
+import java.util.Map;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.ProjectUtils;
+import org.eclipse.m2e.wtp.facets.AbstractFacetDetector;
+import org.eclipse.m2e.wtp.jsf.internal.MavenJSFConstants;
+import org.eclipse.m2e.wtp.jsf.internal.Messages;
+import org.eclipse.m2e.wtp.jsf.internal.utils.JSFUtils;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Inspects the project web.xml descriptor for a servlet facet declaration.
+ * 
+ * @author Fred Bricon
+ * @since 0.18.0
+ */
+public class WebXmlJSFFacetDetector extends AbstractFacetDetector {
+
+	private static final Logger LOG = LoggerFactory.getLogger(WebXmlJSFFacetDetector.class);
+
+	@Override
+	public IProjectFacetVersion findFacetVersion(IMavenProjectFacade mavenProjectFacade, Map<?, ?> context, IProgressMonitor monitor) throws CoreException {
+		IProject project = mavenProjectFacade.getProject();
+		if (project == null) {
+			return null;
+		}
+		MavenProject mavenProject = mavenProjectFacade.getMavenProject(monitor);
+		if (mavenProject == null) {
+			return null;
+		}
+
+		IProjectFacetVersion version = null;
+		if (hasFacesServletInWebXml(mavenProject, project)) {
+			//Uses faces-servlet so we try to best guess the version depending on the installed web facet
+			IFacetedProject fproj;
+			try {
+				fproj = ProjectFacetsManager.create(project);
+				if (fproj != null) {
+					IProjectFacetVersion webVersion = fproj .getInstalledVersion(IJ2EEFacetConstants.DYNAMIC_WEB_FACET);
+					if (webVersion.compareTo(IJ2EEFacetConstants.DYNAMIC_WEB_30) < 0) {
+						version = MavenJSFConstants.JSF_FACET_VERSION_1_2;
+					} else {
+						version = MavenJSFConstants.JSF_FACET_VERSION_2_0;
+					}
+				}
+			} catch (CoreException e) {
+				LOG.error(Messages.WebXmlJSFFacetDetector_Error_Cant_Detect_JSF_From_WebXml, e);
+			}
+		}
+		return version;
+	}
+	
+	private boolean hasFacesServletInWebXml(MavenProject mavenProject, IProject project) {
+		//We look for javax.faces.webapp.FacesServlet in web.xml
+		//We should look for a custom web.xml at this point, but WTP would then crash on the JSF Facet installation
+		//if it's not in a standard location, so we stick with the regular file.
+		IFile webXml = ProjectUtils.getWebResourceFile(project, "WEB-INF/web.xml"); //$NON-NLS-1$
+		return webXml != null && webXml.exists() && JSFUtils.hasFacesServlet(webXml);
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/messages.properties b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/messages.properties
new file mode 100644
index 0000000..fb1fdb8
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/messages.properties
@@ -0,0 +1,12 @@
+JSFAppConfigUtils_Error_Reading_WebXml=Error reading web.xml
+JSFProjectConfigurator_Marker_Facet_Version_Cant_Be_Installed={0} can not be installed : {1}
+JSFProjectConfigurator_The_project_does_not_contain_the_Web_Module_facet=The project doesn't contain the Web Module facet.
+JSFUtils_Error_Finding_Faces_Servlet=An error occured trying to find to {0} :
+JSFUtils_Error_Finding_Faces_Servlet_In_WebXml=An error occured trying to find to {0} in {1}
+JSFUtils_Error_Finding_JSF_Version=Can not get JSF Facet version {0}
+JSFUtils_Error_Finding_Latest_JSF_Version=Can not get Latest JSF Facet version
+JSFUtils_Error_Reading_FacesConfig=Error reading face-config.xml
+JSFUtils_Error_Searching_For_JSF_Type=Error searching for javax.faces.context.FacesContext
+MavenJSFConstants_Warning_JSF21_Unavailable=JSF 2.1 Facet is unavailable, fall back to 2.0
+MavenJSFConstants_Warning_JSF22_Unavailable=JSF 2.2 Facet is unavailable, fall back to {0}
+WebXmlJSFFacetDetector_Error_Cant_Detect_JSF_From_WebXml=Can't detect JSF version from web.xml
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/utils/FacesConfigQuickPeek.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/utils/FacesConfigQuickPeek.java
new file mode 100644
index 0000000..e358b38
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/utils/FacesConfigQuickPeek.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2011-2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+  *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.m2e.wtp.jsf.internal.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
+import org.eclipse.jst.jee.util.internal.XMLRootHandler;
+import org.xml.sax.InputSource;
+
+@SuppressWarnings("restriction")
+public class FacesConfigQuickPeek {
+
+	private static final String FACES_CONFIG_PUBLIC_ID_1_0 = "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_SYSTEM_ID_1_0 = "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_PUBLIC_ID_1_1 = "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_SYSTEM_ID_1_1 = "http://java.sun.com/dtd/web-facesconfig_1_1.dtd"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_SCHEMA_ID_1_2 = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_SCHEMA_ID_2_0 = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_SCHEMA_ID_2_1 = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_ID_1_0 = "1.0"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_ID_1_1 = "1.1"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_ID_1_2 = "1.2"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_ID_2_0 = "2.0"; //$NON-NLS-1$
+	private static final String FACES_CONFIG_ID_2_1 = "2.1"; //$NON-NLS-1$
+	
+	private XMLRootHandler handler;
+
+	private String storedVersion = null;
+	
+	private boolean versionSet = false;
+	
+	public FacesConfigQuickPeek(InputStream in) {
+		if (in != null) {
+			try {
+				InputSource inputSource = new InputSource(in);
+				handler = new XMLRootHandler();
+				handler.parseContents(inputSource);
+			} catch (Exception ex) {
+				// ignore
+			} finally {
+				try {
+					in.reset();
+				} catch (IOException ex) {
+					// ignore
+				}
+			}
+		}
+	}
+	
+	public String getVersion() {
+		if (!versionSet) {
+			if (handler != null && "faces-config".equals(handler.getRootName())) { //$NON-NLS-1$
+				String version = null;
+				if (handler.getRootAttributes() != null) {
+					version = handler.getRootAttributes().getValue("version"); //$NON-NLS-1$
+				}
+				if (version == null || version.trim().length() == 0) {
+					version = getVersionFromDtdSchema();
+				}
+				storedVersion = version;
+				versionSet = true;
+			}
+			
+		}
+		return storedVersion;
+	}
+
+	private String getVersionFromDtdSchema() {
+		//Algorithm copied from org.eclipse.jst.jee.util.internal.JavaEEQuickPeek
+		if (handler == null) {
+			return null;
+		}
+		String publicID = handler.getDtdPublicID();
+		String systemID = handler.getDtdSystemID();
+		String schemaName = null;
+		if (publicID == null || systemID == null) {
+			if (handler.getRootAttributes() != null) {
+				schemaName = JavaEEQuickPeek.normalizeSchemaLocation(handler.getRootAttributes().getValue("xsi:schemaLocation")); //$NON-NLS-1$
+			}
+			if (schemaName == null) {
+				return null;
+			}
+		}
+		String version = null;
+		if (publicID != null && systemID != null) {
+			if (publicID.equals(FACES_CONFIG_PUBLIC_ID_1_0) && (systemID.equals(FACES_CONFIG_SYSTEM_ID_1_0))) {
+				version = FACES_CONFIG_ID_1_0;
+			} else if (publicID.equals(FACES_CONFIG_PUBLIC_ID_1_1) && systemID.equals(FACES_CONFIG_SYSTEM_ID_1_1)) {
+				version = FACES_CONFIG_ID_1_1;
+			}
+		} else if (schemaName != null) {
+			if (schemaName.equals(FACES_CONFIG_SCHEMA_ID_1_2)) {
+				version = FACES_CONFIG_ID_1_2;
+			} else if (schemaName.equals(FACES_CONFIG_SCHEMA_ID_2_0)) {
+				version = FACES_CONFIG_ID_2_0;
+			} else if (schemaName.equals(FACES_CONFIG_SCHEMA_ID_2_1)) {
+				version = FACES_CONFIG_ID_2_1;
+			} 
+		}
+		return version;
+	}
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/utils/JSFUtils.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/utils/JSFUtils.java
new file mode 100644
index 0000000..a7b92b2
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/utils/JSFUtils.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.m2e.wtp.jsf.internal.utils;
+
+import static org.eclipse.m2e.wtp.jsf.internal.MavenJSFConstants.JSF_FACET;
+import static org.eclipse.m2e.wtp.jsf.internal.MavenJSFConstants.JSF_VERSION_1_1;
+import static org.eclipse.m2e.wtp.jsf.internal.MavenJSFConstants.JSF_VERSION_1_2;
+import static org.eclipse.m2e.wtp.jsf.internal.MavenJSFConstants.JSF_VERSION_2_0;
+import static org.eclipse.m2e.wtp.jsf.internal.MavenJSFConstants.JSF_VERSION_2_1;
+import static org.eclipse.m2e.wtp.jsf.internal.MavenJSFConstants.JSF_VERSION_2_2;
+
+import java.io.InputStream;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathFactory;
+
+import org.codehaus.plexus.util.IOUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.m2e.wtp.ProjectUtils;
+import org.eclipse.m2e.wtp.jsf.internal.Messages;
+import org.eclipse.m2e.wtp.jsf.internal.utils.xpl.JSFAppConfigUtils;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+
+public class JSFUtils {
+
+	private static final Logger LOG = LoggerFactory.getLogger(JSFUtils.class);
+
+	public static final String FACES_SERVLET = "javax.faces.webapp.FacesServlet"; //$NON-NLS-1$
+
+	private static final String FACES_SERVLET_XPATH = "//servlet[servlet-class=\"" + FACES_SERVLET + "\"]"; //$NON-NLS-1$ //$NON-NLS-2$
+
+	private JSFUtils() {
+		// no public constructor
+	}
+
+	/**
+	 * Return the faces-config.xml of the given project, or null if faces-config.xml doesn't exist
+	 */
+	public static IFile getFacesconfig(IProject project) {
+		IFile facesConfig = null;
+		@SuppressWarnings("unchecked")
+		List<String> configFiles = JSFAppConfigUtils.getConfigFilesFromContextParam(project);
+		for (String configFile : configFiles) {
+			facesConfig = ProjectUtils.getWebResourceFile(project, configFile);
+			if (facesConfig != null && facesConfig.exists()) {
+				return facesConfig;
+			}
+		}
+		facesConfig = ProjectUtils.getWebResourceFile(project, "WEB-INF/faces-config.xml"); //$NON-NLS-1$
+		
+		return facesConfig;
+	}
+	
+	/**
+	 * Return the faces config version of the given project, or null if faces-config.xml doesn't exist
+	 */
+	public static  String getVersionFromFacesconfig(IProject project) {
+		IFile facesConfig = getFacesconfig(project);
+	    String version = null;
+		if (facesConfig != null) {
+			InputStream in = null;
+			try {
+				facesConfig.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
+				in = facesConfig.getContents();
+				FacesConfigQuickPeek peek = new FacesConfigQuickPeek(in);
+				version = peek.getVersion();
+			} catch (CoreException e) {
+				// ignore
+				LOG.error(Messages.JSFUtils_Error_Reading_FacesConfig, e);
+			} finally {
+				IOUtil.close(in);
+			}
+		}
+		return version;
+	}
+	
+	/**
+	 * Checks if the webXml {@link IFile} declares the Faces servlet.
+	 */
+	public static boolean hasFacesServlet(IFile webXml) {
+		//We look for javax.faces.webapp.FacesServlet in web.xml
+		if (webXml == null || !webXml.isAccessible()) {
+			return false;
+		}
+		
+		InputStream is = null;
+		try {
+			is = webXml.getContents();
+			return hasFacesServlet(is);
+		} catch (Exception e) {
+			LOG.error(NLS.bind(Messages.JSFUtils_Error_Finding_Faces_Servlet_In_WebXml, FACES_SERVLET, webXml.getLocation().toOSString()), e);
+		} finally {
+			IOUtil.close(is);
+		}
+		return false;
+	}	
+	
+	/**
+	 * Checks if the webXml {@link InputStream} declares the Faces servlet.
+	 */
+	public static boolean hasFacesServlet(InputStream input) {
+		if (input == null) {
+			return false;
+		}
+		boolean hasFacesServlet = false;
+		try {
+			DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+			domFactory.setNamespaceAware(false); // never forget this!
+			domFactory.setValidating(false);
+			DocumentBuilder builder = domFactory.newDocumentBuilder();
+			
+			//FIX_POST_MIGRATION builder.setEntityResolver(new DtdResolver());
+			Document doc = builder.parse(input);
+
+			XPath xpath = XPathFactory.newInstance().newXPath();
+			XPathExpression expr = xpath.compile(FACES_SERVLET_XPATH);
+			hasFacesServlet = null != expr.evaluate(doc, XPathConstants.NODE);
+		} catch (Exception e) {
+			LOG.error(NLS.bind(Messages.JSFUtils_Error_Finding_Faces_Servlet,FACES_SERVLET), e);
+		}
+		return hasFacesServlet;
+	}		
+	
+	/**
+	 * Determines the JSF version by searching for the methods of javax.faces.application.Application 
+	 * in the project's classpath.
+	 * @param project : the java project to analyze
+	 * @return the JSF version (1.1, 1.2, 2.0, 2.1, 2.2) found in the classpath, 
+	 * or null if the project doesn't depend on JSF 
+	 */
+	public static String getJSFVersionFromClasspath(IProject project) {
+		String version = null;
+		IJavaProject javaProject = JavaCore.create(project);
+		if (javaProject != null) {
+			IType type = null;
+			try {
+				type = javaProject.findType("javax.faces.context.FacesContext");//$NON-NLS-1$ 
+			} catch (JavaModelException e) {
+				LOG.error(Messages.JSFUtils_Error_Searching_For_JSF_Type, e) ;
+			}
+			if (type != null) {
+				String[] emptyParams = new String[0];
+				if (type.getMethod("getResourceLibraryContracts", emptyParams).exists()) { //$NON-NLS-1$
+					return JSF_VERSION_2_2;
+				}
+				if (type.getMethod("isReleased", emptyParams).exists()) { //$NON-NLS-1$
+					return JSF_VERSION_2_1;					
+				}
+				if (type.getMethod("getAttributes", emptyParams).exists() &&     //$NON-NLS-1$
+					type.getMethod("getPartialViewContext", emptyParams).exists()) {       //$NON-NLS-1$
+					return JSF_VERSION_2_0;
+			    }
+				if (type.getMethod("getELContext", emptyParams).exists()) {  //$NON-NLS-1$
+					return JSF_VERSION_1_2;
+				} 
+				version = JSF_VERSION_1_1;
+			}
+		}
+		return version;
+	}
+	
+	/**
+	 * Transforms a JSF version string into the equivalent {@link IProjectFacetVersion}.
+	 * If no equivalent {@link IProjectFacetVersion} is available, it's assumed the version 
+	 * is not supported and the latest available JSF version is returned.
+	 *  
+	 * @param version
+	 * @return
+	 * @since 0.18.0
+	 */
+	public static IProjectFacetVersion getSafeJSFFacetVersion(String version) {
+		IProjectFacetVersion facetVersion = null;
+		if (version != null && version.trim().length() > 0) {
+			try {
+				facetVersion = JSF_FACET.getVersion(version);
+			} catch (Exception e) {
+				LOG.error(NLS.bind(Messages.JSFUtils_Error_Finding_JSF_Version,version), e);
+				try {
+					//We assume the detected version is not supported *yet* so take the latest.
+					facetVersion = JSF_FACET.getLatestVersion();
+				} catch(CoreException cex) {
+					LOG.error(Messages.JSFUtils_Error_Finding_Latest_JSF_Version, cex);
+					facetVersion =  JSF_FACET.getDefaultVersion();		
+				}
+			}
+		}
+		return facetVersion;
+	}
+}
diff --git a/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/utils/xpl/JSFAppConfigUtils.java b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/utils/xpl/JSFAppConfigUtils.java
new file mode 100644
index 0000000..39a3669
--- /dev/null
+++ b/org.eclipse.m2e.wtp.jsf/src/org/eclipse/m2e/wtp/jsf/internal/utils/xpl/JSFAppConfigUtils.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Oracle Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ian Trimble - initial API and implementation
+ *******************************************************************************/ 
+package org.eclipse.m2e.wtp.jsf.internal.utils.xpl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.jst.j2ee.common.ParamValue;
+import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
+import org.eclipse.jst.j2ee.model.IModelProvider;
+import org.eclipse.jst.j2ee.model.ModelProviderManager;
+import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit;
+import org.eclipse.jst.j2ee.webapplication.ContextParam;
+import org.eclipse.jst.j2ee.webapplication.WebApp;
+import org.eclipse.m2e.wtp.jsf.internal.Messages;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class copied from {@link org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigUtils}. 
+ * 
+ * Modifications from the original file :
+ * <ul>
+ * <li>getConfigFilesFromContextParam() method modified to allow reading of javax.faces.CONFIG_FILES 
+ * value in web.xml on projects not having the JSF facet already</li>
+ * <li>Unused methods have been removed</li>
+ * <li>Code changed to use Java 1.5+ features</li>
+ * <li>Use slf4j logger</li>
+ * </ul>
+ * 
+ * JSFAppConfigUtils provides utility methods useful in processing of a JSF
+ * application configuration.
+ * 
+ * 
+ * @author Ian Trimble - Oracle
+ */
+public class JSFAppConfigUtils {
+
+	private static final Logger LOG = LoggerFactory.getLogger(JSFAppConfigUtils.class);
+	
+	/**
+	 * Name of JSF CONFIG_FILES context parameter ("javax.faces.CONFIG_FILES").
+	 */
+	public static final String CONFIG_FILES_CONTEXT_PARAM_NAME = "javax.faces.CONFIG_FILES"; //$NON-NLS-1$
+
+	/**
+	 * Location in JAR file of application configuration resource file
+	 * ("META-INF/faces-config.xml"). 
+	 */
+	public static final String FACES_CONFIG_IN_JAR_PATH = "META-INF/faces-config.xml"; //$NON-NLS-1$
+
+    
+	/**
+	 * Gets list of application configuration file names as listed in the JSF
+	 * CONFIG_FILES context parameter ("javax.faces.CONFIG_FILES"). Will return
+	 * an empty list if WebArtifactEdit is null, if WebApp is null, if context
+	 * parameter does not exist, or if trimmed context parameter's value is
+	 * an empty String.
+	 * 
+	 * @param project IProject instance for which to get the context
+	 * parameter's value.
+	 * @return List of application configuration file names as listed in the
+	 * JSF CONFIG_FILES context parameter ("javax.faces.CONFIG_FILES"); list
+	 * may be empty.
+	 */
+	public static List<String> getConfigFilesFromContextParam(IProject project) {
+		List<String> filesList = Collections.emptyList();
+		if (ModuleCoreNature.isFlexibleProject(project)) {
+			try {
+				IModelProvider provider = ModelProviderManager.getModelProvider(project);
+				if (provider != null) {
+					Object webAppObj = provider.getModelObject();
+					if (webAppObj != null){
+						if (webAppObj instanceof WebApp)
+							filesList = getConfigFilesForJ2EEApp(project);
+						else if (webAppObj instanceof org.eclipse.jst.javaee.web.WebApp)
+							filesList = getConfigFilesForJEEApp((org.eclipse.jst.javaee.web.WebApp)webAppObj);
+					}
+				}
+			} catch (Exception e) {
+				//Fix for JBIDE-11078 : in extremely rare cases, 
+				//a NPE can be thrown if no IModelProvider is found for project
+				//At this point that error shouldn't block the user so we just log it
+				LOG.error("Could not read web.xml", e); //$NON-NLS-1$
+			}
+		}
+		return filesList;
+	}
+
+	private static List<String> getConfigFilesForJEEApp(org.eclipse.jst.javaee.web.WebApp webApp) {
+		String filesString = null;
+		for (org.eclipse.jst.javaee.core.ParamValue paramValue : webApp.getContextParams()) {
+			if (paramValue.getParamName().equals(CONFIG_FILES_CONTEXT_PARAM_NAME)) {
+				filesString = paramValue.getParamValue();
+				break;
+			}
+		}
+		return parseFilesString(filesString);	
+	}
+
+	private static List<String> getConfigFilesForJ2EEApp(IProject project){
+		List<String> filesList = new ArrayList<>();
+		WebArtifactEdit webArtifactEdit = WebArtifactEdit.getWebArtifactEditForRead(project);
+		if (webArtifactEdit != null) {
+			try {
+				WebApp webApp = null;
+				try {
+					webApp = webArtifactEdit.getWebApp();
+				} catch(ClassCastException cce) {
+					//occasionally thrown from WTP code in RC3 and possibly later
+					LOG.error(Messages.JSFAppConfigUtils_Error_Reading_WebXml, cce);
+					return filesList;
+				}
+				if (webApp != null) {
+					String filesString = null;
+					//need to branch here due to model version differences (BugZilla #119442)
+					if (webApp.getVersionID() == J2EEVersionConstants.WEB_2_3_ID) {
+						EList contexts = webApp.getContexts();
+						Iterator itContexts = contexts.iterator();
+						while (itContexts.hasNext()) {
+							ContextParam contextParam = (ContextParam)itContexts.next();
+							if (contextParam.getParamName().equals(CONFIG_FILES_CONTEXT_PARAM_NAME)) {
+								filesString = contextParam.getParamValue();
+								break;
+							}
+						}
+					} else {
+						EList contextParams = webApp.getContextParams();
+						Iterator itContextParams = contextParams.iterator();
+						while (itContextParams.hasNext()) {
+							ParamValue paramValue = (ParamValue)itContextParams.next();
+							if (paramValue.getName().equals(CONFIG_FILES_CONTEXT_PARAM_NAME)) {
+								filesString = paramValue.getValue();
+								break;
+							}
+						}
+					}					
+					filesList = parseFilesString(filesString);				
+				}
+			} finally {
+				webArtifactEdit.dispose();
+			}
+		}
+
+		return filesList;
+	}
+	
+	private static List<String> parseFilesString(String filesString) {
+		List<String> filesList = new ArrayList<>();
+		if (filesString != null && filesString.trim().length() > 0) {			
+			StringTokenizer stFilesString = new StringTokenizer(filesString, ","); //$NON-NLS-1$
+			while (stFilesString.hasMoreTokens()) {
+				String configFile = stFilesString.nextToken().trim();
+				filesList.add(configFile);
+			}
+		}
+		return filesList;
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.overlay.ui/.classpath b/org.eclipse.m2e.wtp.overlay.ui/.classpath
new file mode 100644
index 0000000..46cec6e
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/org.eclipse.m2e.wtp.overlay.ui/.gitignore b/org.eclipse.m2e.wtp.overlay.ui/.gitignore
new file mode 100644
index 0000000..934e0e0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/.gitignore
@@ -0,0 +1,2 @@
+/bin
+/target
diff --git a/org.eclipse.m2e.wtp.overlay.ui/.project b/org.eclipse.m2e.wtp.overlay.ui/.project
new file mode 100644
index 0000000..ebcd4fe
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp.overlay.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp.overlay.ui/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.overlay.ui/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.overlay.ui/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.m2e.wtp.overlay.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..13c64aa
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,95 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/org.eclipse.m2e.wtp.overlay.ui/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.overlay.ui/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..d7bb4ca
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,5 @@
+#Wed Sep 14 15:43:12 CEST 2011
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.overlay.ui/META-INF/MANIFEST.MF b/org.eclipse.m2e.wtp.overlay.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..339590f
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Overlay support for Eclipse WTP - UI
+Bundle-SymbolicName: org.eclipse.m2e.wtp.overlay.ui;singleton:=true
+Bundle-Version: 1.3.0.qualifier
+Bundle-Activator: org.eclipse.m2e.wtp.overlay.internal.ui.OverlayUIPluginActivator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.wst.common.modulecore,
+ org.eclipse.wst.common.modulecore.ui,
+ org.eclipse.core.resources,
+ org.eclipse.m2e.wtp.overlay
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-Vendor: Eclipse.org - m2e-wtp
diff --git a/org.eclipse.m2e.wtp.overlay.ui/about.html b/org.eclipse.m2e.wtp.overlay.ui/about.html
new file mode 100644
index 0000000..52b4fe9
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/about.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>October 29, 2010</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+</body>
+</html>
diff --git a/org.eclipse.m2e.wtp.overlay.ui/build.properties b/org.eclipse.m2e.wtp.overlay.ui/build.properties
new file mode 100644
index 0000000..4bab3f8
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = target/classes/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               about.html,\
+               plugin.properties
+src.includes = about.html
diff --git a/org.eclipse.m2e.wtp.overlay.ui/plugin.properties b/org.eclipse.m2e.wtp.overlay.ui/plugin.properties
new file mode 100644
index 0000000..e20ef3e
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/plugin.properties
@@ -0,0 +1 @@
+Preferences_Overlays = Overlays
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.overlay.ui/plugin.xml b/org.eclipse.m2e.wtp.overlay.ui/plugin.xml
new file mode 100644
index 0000000..8f296c4
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/plugin.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+	<!--
+   <extension
+         point="org.eclipse.wst.common.modulecore.ui.virtualComponentLabelProvider">
+      <provider
+            class="org.eclipse.m2e.wtp.overlay.ui.VirtualComponentLabelProvider">
+      </provider>
+   </extension>
+   <extension
+         point="org.eclipse.wst.common.modulecore.ui.referenceWizardFragment">
+      <referenceFragment
+            class="org.eclipse.m2e.wtp.overlay.ui.OverlayWizardFragment"
+            hidden="false"
+            id="org.eclipse.m2e.wtp.overlay.ui.referenceFragment"
+            name="Project Overlay">
+      </referenceFragment>
+   </extension>
+	-->   
+   <extension point="org.eclipse.ui.preferencePages">
+      <page id="org.eclipse.m2e.wtp.overlay.ui.preferences.OverlayPreferencePage"
+         category="org.eclipse.wst.server.ui.preferencePage"
+         class="org.eclipse.m2e.wtp.overlay.internal.ui.preferences.OverlayPublishingPreferencePage"
+         name="%Preferences_Overlays">
+         <keywordReference id="org.eclipse.wst.server.preferenceKeywords"/>
+      </page>
+   </extension>
+   
+</plugin>
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.overlay.ui/pom.xml b/org.eclipse.m2e.wtp.overlay.ui/pom.xml
new file mode 100644
index 0000000..3928bc0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/pom.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2010 Sonatype, Inc.
+  All rights reserved. This program and the accompanying materials
+  are made available under the terms of the Eclipse Public License v1.0
+  which accompanies this distribution, and is available at
+  http://www.eclipse.org/legal/epl-v10.html
+-->
+<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>
+    <groupId>org.eclipse.m2e.wtp</groupId>
+    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.m2e.wtp.overlay.ui</artifactId>
+  <packaging>eclipse-plugin</packaging>
+
+  <name>M2E-WTP :: Overlay UI</name>
+
+</project>
diff --git a/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/Messages.java b/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/Messages.java
new file mode 100644
index 0000000..ea28bd2
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/Messages.java
@@ -0,0 +1,15 @@
+package org.eclipse.m2e.wtp.overlay.internal.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.m2e.wtp.overlay.internal.ui.messages"; //$NON-NLS-1$
+	public static String OverlayPublishingPreferencePage_Automatically_Republish_Servers_On_Overlay_Modifications;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/OverlayUIPluginActivator.java b/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/OverlayUIPluginActivator.java
new file mode 100644
index 0000000..bb7081b
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/OverlayUIPluginActivator.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.ui;
+
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.m2e.wtp.overlay.OverlayConstants;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class OverlayUIPluginActivator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.m2e.wtp.overlay.ui"; //$NON-NLS-1$
+
+	// The shared instance
+	private static OverlayUIPluginActivator plugin;
+
+  private IPreferenceStore preferenceStore;
+	
+	/**
+	 * The constructor
+	 */
+	public OverlayUIPluginActivator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static OverlayUIPluginActivator getDefault() {
+		return plugin;
+	}
+
+  @Override
+  public IPreferenceStore getPreferenceStore() {
+    // Create the preference store lazily.
+    if(preferenceStore == null) {
+      // InstanceScope.INSTANCE added in 3.7
+      preferenceStore = new ScopedPreferenceStore(new InstanceScope(), OverlayConstants.PLUGIN_ID);
+
+    }
+    return preferenceStore;
+  }
+}
diff --git a/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/messages.properties b/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/messages.properties
new file mode 100644
index 0000000..ecbb466
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/messages.properties
@@ -0,0 +1 @@
+OverlayPublishingPreferencePage_Automatically_Republish_Servers_On_Overlay_Modifications=Automatically republish servers on overlay modifications
diff --git a/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/preferences/OverlayPublishingPreferencePage.java b/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/preferences/OverlayPublishingPreferencePage.java
new file mode 100644
index 0000000..6baa99c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay.ui/src/org/eclipse/m2e/wtp/overlay/internal/ui/preferences/OverlayPublishingPreferencePage.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.ui.preferences;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.m2e.wtp.overlay.OverlayConstants;
+import org.eclipse.m2e.wtp.overlay.internal.ui.Messages;
+import org.eclipse.m2e.wtp.overlay.internal.ui.OverlayUIPluginActivator;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+public class OverlayPublishingPreferencePage  extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
+
+  public OverlayPublishingPreferencePage() {
+    super(GRID);
+    this.setPreferenceStore(OverlayUIPluginActivator.getDefault().getPreferenceStore());
+  }
+  
+  @Override
+  protected void createFieldEditors() {
+    addField(new BooleanFieldEditor(OverlayConstants.P_REPUBLISH_ON_PROJECT_CHANGE, 
+                                    Messages.OverlayPublishingPreferencePage_Automatically_Republish_Servers_On_Overlay_Modifications,
+                                    getFieldEditorParent()));
+  }
+
+  public void init(IWorkbench workbench) {
+    // Nothing to do
+  }
+
+
+}
diff --git a/org.eclipse.m2e.wtp.overlay/.classpath b/org.eclipse.m2e.wtp.overlay/.classpath
new file mode 100644
index 0000000..46cec6e
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/org.eclipse.m2e.wtp.overlay/.gitignore b/org.eclipse.m2e.wtp.overlay/.gitignore
new file mode 100644
index 0000000..bb5e943
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/.gitignore
@@ -0,0 +1,2 @@
+/bin
+/target
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.overlay/.project b/org.eclipse.m2e.wtp.overlay/.project
new file mode 100644
index 0000000..2a9eb3c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp.overlay</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp.overlay/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.overlay/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.overlay/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.m2e.wtp.overlay/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..13c64aa
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,95 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=error
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/org.eclipse.m2e.wtp.overlay/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.overlay/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..1edf90b
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,5 @@
+#Sat Oct 29 12:10:23 CEST 2011
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.overlay/META-INF/MANIFEST.MF b/org.eclipse.m2e.wtp.overlay/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e8b07ad
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/META-INF/MANIFEST.MF
@@ -0,0 +1,28 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Overlay support for Eclipse WTP
+Bundle-SymbolicName: org.eclipse.m2e.wtp.overlay;singleton:=true
+Bundle-Version: 1.3.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.wst.common.core,
+ org.eclipse.wst.common.modulecore,
+ org.eclipse.emf.common,
+ org.eclipse.emf.ecore,
+ org.eclipse.jst.common.frameworks;bundle-version="1.1.400",
+ org.eclipse.jst.j2ee;bundle-version="1.1.400",
+ org.eclipse.wst.server.core,
+ org.eclipse.wst.common.emfworkbench.integration,
+ org.eclipse.wst.common.emf,
+ org.eclipse.jem.workbench,
+ org.eclipse.jem.util,
+ org.apache.ant,
+ org.eclipse.jface,
+ org.slf4j.api;bundle-version="1.6.0"
+Bundle-Vendor: Eclipse.org - m2e-wtp
+Export-Package: org.eclipse.m2e.wtp.overlay,org.eclipse.m2e.wtp.overla
+ y.internal.modulecore;x-friends:="org.eclipse.m2e.wtp.overlay.ui,org.
+ eclipse.m2e.wtp",org.eclipse.m2e.wtp.overlay.modulecore
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.m2e.wtp.overlay.internal.OverlayPluginActivator
diff --git a/org.eclipse.m2e.wtp.overlay/about.html b/org.eclipse.m2e.wtp.overlay/about.html
new file mode 100644
index 0000000..0a13914
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/about.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>October 29, 2010</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+
+<h3>Third Party Content</h3>
+
+<p>
+The Content includes items that have been sourced from third parties as set out below. If you 
+did not receive this Content directly from the Eclipse Foundation, the following is provided 
+for informational purposes only, and you should look to the Redistributor&rsquo;s license for 
+terms and conditions of use.
+</p>
+
+<h4>Ant (Derivative work)</h4>
+<p>
+This software is based in part on the work of The Apache Software Foundation on the Ant project.</p>
+<p>The class org.eclipse.m2e.wtp.overlay.internal.modulecore.DynamicResourceFilter is derived from the following class from the Ant project :</p>
+<ul>
+<li>org.apache.tools.ant.DirectoryScanner</li>
+</ul>
+<p>
+Your use of Ant in source or binary code form is subject to the terms and conditions of the 
+The Apache Software License, Version 2.0 (&quot;ASL&quot;).  
+A copy of the ASL is available at <a href="http://maven.apache.org/license.html">http://maven.apache.org/license.html</a>.
+(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>)
+</p>
+
+</body>
+</html>
diff --git a/org.eclipse.m2e.wtp.overlay/about_files/LICENSE-2.0.txt b/org.eclipse.m2e.wtp.overlay/about_files/LICENSE-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/about_files/LICENSE-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/org.eclipse.m2e.wtp.overlay/about_files/NOTICE b/org.eclipse.m2e.wtp.overlay/about_files/NOTICE
new file mode 100644
index 0000000..9d9b29b
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/about_files/NOTICE
@@ -0,0 +1,11 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the Ant distribution.                             ==
+   =========================================================================
+
+   This product includes software developed by
+   The Apache Software Foundation (http://www.apache.org/).
+
+   Please read the different LICENSE files present in the root directory of
+   this distribution.
diff --git a/org.eclipse.m2e.wtp.overlay/build.properties b/org.eclipse.m2e.wtp.overlay/build.properties
new file mode 100644
index 0000000..899ec6b
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/build.properties
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = target/classes/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               about.html,\
+               about_files/
+src.includes = about.html,\
+               about_files/
diff --git a/org.eclipse.m2e.wtp.overlay/plugin.xml b/org.eclipse.m2e.wtp.overlay/plugin.xml
new file mode 100644
index 0000000..fb5b455
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/plugin.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+     <extension
+         point="org.eclipse.wst.common.modulecore.referenceResolver">
+      <resolver
+            class="org.eclipse.m2e.wtp.overlay.modulecore.OverlayReferenceResolver"
+            id="org.maven.ide.eclipse.wtp.overlay.modulecore.OverlayReferenceResolver">
+      </resolver>
+   </extension>
+
+   <extension point="org.eclipse.core.runtime.preferences">
+      <initializer class="org.eclipse.m2e.wtp.overlay.internal.preferences.OverlayPreferencesInitializer"/>
+   </extension>
+     
+</plugin>
diff --git a/org.eclipse.m2e.wtp.overlay/pom.xml b/org.eclipse.m2e.wtp.overlay/pom.xml
new file mode 100644
index 0000000..9460964
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/pom.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2010 Sonatype, Inc.
+  All rights reserved. This program and the accompanying materials
+  are made available under the terms of the Eclipse Public License v1.0
+  which accompanies this distribution, and is available at
+  http://www.eclipse.org/legal/epl-v10.html
+-->
+<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>
+    <groupId>org.eclipse.m2e.wtp</groupId>
+    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.m2e.wtp.overlay</artifactId>
+  <packaging>eclipse-plugin</packaging>
+
+  <name>M2E-WTP :: Overlay Core</name>
+
+</project>
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/OverlayConstants.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/OverlayConstants.java
new file mode 100644
index 0000000..55e584d
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/OverlayConstants.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay;
+
+/**
+ * Constants used by the org.eclipse.m2e.wtp.overlay plugin
+ * 
+ * @author Fred Bricon
+ *
+ */
+public class OverlayConstants {
+
+  private OverlayConstants(){}
+
+  public static final String PLUGIN_ID = "org.eclipse.m2e.wtp.overlay"; //$NON-NLS-1$
+
+  /**
+   * Republish on server if an overlay dependency changed.
+   */
+  public static final String P_REPUBLISH_ON_PROJECT_CHANGE = "republishOnProjectChange"; //$NON-NLS-1$
+
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/Messages.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/Messages.java
new file mode 100644
index 0000000..d5ab089
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/Messages.java
@@ -0,0 +1,30 @@
+package org.eclipse.m2e.wtp.overlay.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.m2e.wtp.overlay.internal.messages"; //$NON-NLS-1$
+	public static String CompositeVirtualFolder_Error_Finding_Member;
+	public static String CompositeVirtualFolder_Error_Scanning;
+	public static String CompressionUtil_Extracting_Task;
+	public static String CompressionUtil_Unable_To_Create_Output_Dir;
+	public static String CompressionUtil_Unpacking_Unable;
+	public static String CompressionUtil_Unzipping_Interrupted;
+	public static String OverlayVirtualArchiveComponent_Unpacking_Job;
+	public static String OverlayReferenceResolver_Missing_Parameter;
+	public static String OverlayReferenceResolver_Module_Name_Cant_Be_Inferred;
+	public static String OverlayReferenceResolver_Not_Workspace_Project;
+	public static String OverlayReferenceResolver_Unresolveable;
+	public static String ResourceListVirtualFolder_Error_Finding_Member;
+	public static String UnpackArchiveJob_Deleteing_was_cancelled;
+	public static String UnpackArchiveJob_Error_Unpacking;
+	public static String UnpackArchiveJob_Refreshing;
+	public static String UnpackArchiveJob_Unpacking_Interrupted;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/OverlayPluginActivator.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/OverlayPluginActivator.java
new file mode 100644
index 0000000..b5a1246
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/OverlayPluginActivator.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal;
+
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.m2e.wtp.overlay.OverlayConstants;
+import org.eclipse.m2e.wtp.overlay.internal.servers.OverlayResourceChangeListener;
+import org.osgi.framework.BundleContext;
+
+public class OverlayPluginActivator extends Plugin {
+	
+	public static final String PLUGIN_ID = OverlayConstants.PLUGIN_ID;
+
+	IResourceChangeListener overlayresourceChangeListener;
+	
+	private static OverlayPluginActivator instance;
+	
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		instance = this;
+		overlayresourceChangeListener = new OverlayResourceChangeListener();
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+	    workspace.addResourceChangeListener(overlayresourceChangeListener);
+	}
+	
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		if (overlayresourceChangeListener != null) {
+			IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		    workspace.removeResourceChangeListener(overlayresourceChangeListener);
+		}
+		instance = null;
+		super.stop(context);
+	}
+	
+	public static IPath getWorkspacePluginPath() {
+		return instance == null? null : instance.getStateLocation();
+	}
+	
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/messages.properties b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/messages.properties
new file mode 100644
index 0000000..12fb604
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/messages.properties
@@ -0,0 +1,17 @@
+CompositeVirtualFolder_Error_Finding_Member=Error finding {0} in virtual folder
+CompositeVirtualFolder_Error_Scanning=Error scanning virtual folder
+CompressionUtil_Extracting_Task=Extracting 
+CompressionUtil_Unable_To_Create_Output_Dir=Unable to create archive output directory - 
+CompressionUtil_Unpacking_Unable=Unable to unpack to {0}, it points to a missing file
+CompressionUtil_Unzipping_Interrupted=Unzipping {0} to {1} was interrupted
+OverlayVirtualArchiveComponent_Unpacking_Job=Unpacking {0}
+OverlayReferenceResolver_Missing_Parameter={0} is missing the {1} parameter
+OverlayReferenceResolver_Module_Name_Cant_Be_Inferred=module name can not be inferred from {0}
+OverlayReferenceResolver_Not_Workspace_Project={0} is not a workspace project
+OverlayReferenceResolver_Unresolveable={0} could not be resolved
+ResourceListVirtualFolder_Error_Finding_Member=Error finding {0} in {1}
+UnpackArchiveJob_Deleteing_was_cancelled=Deleting {0} was cancelled
+UnpackArchiveJob_Error_Unpacking=Error unpacking {0}
+UnpackArchiveJob_Refreshing=Refreshing {0}
+UnpackArchiveJob_Unpacking_Interrupted=Unpacking {0}  was interrupted
+
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/CompositeVirtualFolder.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/CompositeVirtualFolder.java
new file mode 100644
index 0000000..7b3c3fb
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/CompositeVirtualFolder.java
@@ -0,0 +1,459 @@
+/*******************************************************************************
+ * Copyright (c) 2011-2015 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.modulecore;
+
+import java.io.File;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.m2e.wtp.overlay.internal.Messages;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent;
+import org.eclipse.wst.common.componentcore.internal.flat.IChildModuleReference;
+import org.eclipse.wst.common.componentcore.internal.flat.IFlatFile;
+import org.eclipse.wst.common.componentcore.internal.flat.IFlatFolder;
+import org.eclipse.wst.common.componentcore.internal.flat.IFlatResource;
+import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
+import org.eclipse.wst.common.componentcore.internal.resources.VirtualFile;
+import org.eclipse.wst.common.componentcore.internal.resources.VirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualContainer;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Virtual folder mapping a FlatVirtualComponent
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ * 
+ */
+@SuppressWarnings("restriction")
+public class CompositeVirtualFolder implements IFilteredVirtualFolder {
+
+	private static final Logger LOG = LoggerFactory.getLogger(CompositeVirtualFolder.class);
+
+	private FlatVirtualComponent flatVirtualComponent;
+	private IPath runtimePath;
+	private IProject project;
+	private Set<IVirtualReference> references = new LinkedHashSet<>();
+	private IVirtualResource[] members;
+	private IResourceFilter filter;
+	
+	public CompositeVirtualFolder(FlatVirtualComponent aFlatVirtualComponent, IPath aRuntimePath, IResourceFilter filter) {
+		this.flatVirtualComponent = aFlatVirtualComponent;
+		if (flatVirtualComponent != null && flatVirtualComponent.getComponent() != null) {
+			project = flatVirtualComponent.getComponent().getProject();
+		}
+		this.runtimePath = aRuntimePath;
+		this.filter = filter;
+		try {
+			treeWalk();
+		} catch (CoreException e) {
+			LOG.error(Messages.CompositeVirtualFolder_Error_Scanning, e);
+		}
+	}
+
+	@Override
+	public IProject getProject() {
+		return project;
+	}
+
+	@Override
+	public IPath getRuntimePath() {
+		return runtimePath;
+	}
+
+	@Override
+	public IVirtualResource[] members() throws CoreException {
+		if (members == null) {
+			members = new IVirtualResource[0]; 
+		}
+		return members;
+	}
+	
+	public void treeWalk() throws CoreException {	 
+		IFlatResource[] flatResources = flatVirtualComponent.fetchResources();
+		
+		List<IVirtualResource> membersList = new ArrayList<>(flatResources.length);
+		for (IFlatResource flatResource : flatResources) {
+			IVirtualResource resource = convert(flatResource);
+			if (resource != null) {
+				membersList.add(resource);	
+			}
+		}
+		for (IChildModuleReference childModule : flatVirtualComponent.getChildModules()) {
+			IVirtualReference reference = childModule.getReference();
+			if (reference != null) {
+				String filePath = getFilePath(reference);
+				if (filter == null || filter.accepts(filePath, true)) {
+					references.add(reference);
+				}
+			}
+		}
+		
+		members = new IVirtualResource[membersList.size()];
+		membersList.toArray(members);
+	}
+
+	private IVirtualResource convert(IFlatResource flatResource) {
+		IVirtualResource virtualResource = null;
+		if (flatResource instanceof IFlatFolder) {
+			virtualResource = convertFolder((IFlatFolder) flatResource);
+		} else if (flatResource instanceof IFlatFile){
+			virtualResource = convertFile((IFlatFile) flatResource);
+		}
+		
+		return virtualResource;
+	}
+
+	private IVirtualFolder convertFolder(IFlatFolder flatFolder) {
+		IFlatResource[] flatMembers = flatFolder.members();
+		List<IVirtualResource> membersList = new ArrayList<>(flatMembers.length);
+		for (IFlatResource flatResource : flatMembers) {
+			IVirtualResource resource = convert(flatResource);
+			if (resource != null) {
+				membersList.add(resource);	
+			}
+		}
+		final IVirtualResource[] folderMembers = new IVirtualResource[membersList.size()];
+		membersList.toArray(folderMembers);
+		VirtualFolder vf = new VirtualFolder(project, flatFolder.getModuleRelativePath().append(flatFolder.getName())) {
+			@Override
+			public IVirtualResource[] members() throws CoreException {
+				return folderMembers; 
+			}
+		}; 
+		return vf;
+		
+	}
+
+	private IVirtualFile convertFile(IFlatFile flatFile) {
+		final IFile f = (IFile)flatFile.getAdapter(IFile.class);
+		String filePath  = null;
+		if (f == null) {
+			//Not a workspace file, we assume it's an external reference
+			File underlyingFile = (File)flatFile.getAdapter(File.class);
+			if (underlyingFile != null && underlyingFile.exists()) {
+				filePath = flatFile.getModuleRelativePath().toPortableString() + Path.SEPARATOR + underlyingFile.getName();
+				if (filter == null || filter.accepts(filePath, true)) {
+					IVirtualReference reference = createReference(underlyingFile, flatFile.getModuleRelativePath());
+					references.add(reference);
+				}
+			}
+		} else {
+			final String fileName = f.getName(); 		
+			IPath ffRuntimePath = flatFile.getModuleRelativePath();
+			filePath = ffRuntimePath.toPortableString() + Path.SEPARATOR + fileName;
+			if (filter == null || filter.accepts(filePath, true)) {
+				return new VirtualFile(project, ffRuntimePath, f) {
+					@Override
+					public String getName() {
+						return fileName;
+					}
+					
+					@Override
+					public IPath getWorkspaceRelativePath() {
+						return f.getFullPath();
+					}
+					
+					@Override
+					public IFile getUnderlyingFile() {
+						IFile f = super.getUnderlyingFile();
+						return f;
+					}
+				};
+			}
+			
+		}
+		return null;
+	}
+	
+	private IVirtualReference createReference(File underlyingFile, IPath path) {
+		VirtualArchiveComponent archive = new VirtualArchiveComponent(project, VirtualArchiveComponent.LIBARCHIVETYPE + Path.SEPARATOR + underlyingFile.getAbsolutePath(), path);
+		IVirtualReference ref = ComponentCore.createReference(flatVirtualComponent.getComponent(), archive);
+		ref.setArchiveName(archive.getArchivePath().lastSegment());
+		ref.setRuntimePath(path);
+		return ref;
+	}
+
+	@Override
+	public void create(int arg0, IProgressMonitor arg1) throws CoreException {
+		// ignore
+	}
+
+	@Override
+	public boolean exists(IPath arg0) {
+		return false;
+	}
+	
+    @Override
+	public IVirtualResource findMember(String sPath) {
+        return findMember(new Path(sPath), 0);
+    }
+
+    @Override
+	public IVirtualResource findMember(String sPath, int searchFlags) {
+        return findMember(new Path(sPath), searchFlags);
+    }
+
+    @Override
+	public IVirtualResource findMember(IPath path) {
+        return findMember(path, 0);
+    }
+
+    @Override
+	public IVirtualResource findMember(IPath path, int theSearchFlags) {
+    	if (path == null) {
+    		return null;
+    	}
+    	Queue<String> segments = new ArrayDeque<String>(path.segmentCount());
+    	for (String s : path.segments()) {
+    		segments.add(s);
+    	}
+    	try {
+    		return findMember(segments, members);
+    	} catch (CoreException ce) {
+    		LOG.error(Messages.CompositeVirtualFolder_Error_Finding_Member, ce);
+    	}
+    	return null;
+    }
+    
+    private static IVirtualResource findMember(Queue<String> segments, IVirtualResource[] members) throws CoreException {
+    	if (segments.isEmpty()) {
+    		return null;
+    	}
+    	String segment = segments.poll();
+    	boolean finalResource = segments.isEmpty();
+    	for (IVirtualResource m : members) {
+    		if (m.getName().equals(segment)) {
+    			if (finalResource) {
+    				return m;
+    			}
+    			if (m instanceof IVirtualFolder) {
+    				return findMember(segments, ((IVirtualFolder)m).members());
+    			}
+    		}
+    	}
+        return null;
+    }
+    
+    
+    
+	@Override
+	public IVirtualFile getFile(IPath arg0) {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IVirtualFile getFile(String arg0) {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IVirtualFolder getFolder(IPath arg0) {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IVirtualFolder getFolder(String arg0) {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IVirtualResource[] getResources(String arg0) {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IVirtualResource[] members(int arg0) throws CoreException {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public void createLink(IPath arg0, int arg1, IProgressMonitor arg2)
+			throws CoreException {
+		// ignore
+	}
+
+	@Override
+	public void delete(int arg0, IProgressMonitor arg1) throws CoreException {
+		// ignore		
+	}
+
+	@Override
+	public boolean exists() {
+		// ignore
+		return false;
+	}
+
+	@Override
+	public IVirtualComponent getComponent() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public String getFileExtension() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public String getName() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IVirtualContainer getParent() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IPath getProjectRelativePath() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public String getResourceType() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public int getType() {
+		// ignore
+		return 0;
+	}
+
+	@Override
+	public IResource getUnderlyingResource() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IResource[] getUnderlyingResources() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IPath getWorkspaceRelativePath() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public boolean isAccessible() {
+		// ignore
+		return false;
+	}
+
+	@Override
+	public void removeLink(IPath arg0, int arg1, IProgressMonitor arg2)
+			throws CoreException {
+		// ignore
+		
+	}
+
+	@Override
+	public void setResourceType(String arg0) {
+		// ignore
+		
+	}
+
+	@Override
+	public boolean contains(ISchedulingRule rule) {
+		// ignore
+		return false;
+	}
+
+	@Override
+	public boolean isConflicting(ISchedulingRule rule) {
+		// ignore
+		return false;
+	}
+
+	@Override
+	public Object getAdapter(Class adapter) {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IContainer getUnderlyingFolder() {
+		// ignore
+		return null;
+	}
+
+	@Override
+	public IContainer[] getUnderlyingFolders() {
+		// ignore
+		return null;
+	}
+
+	public IVirtualReference[] getReferences() {
+		return references.toArray(new IVirtualReference[references.size()]);
+	}
+	
+	@Override
+	public IResourceFilter getFilter() {
+		return filter;
+	}
+
+	@Override
+	public void setFilter(IResourceFilter filter) {
+		this.filter = filter;
+	}
+	
+	
+	private String getFilePath(IVirtualReference reference) {
+		StringBuilder path = new StringBuilder();
+		String prefix = reference.getRuntimePath().makeRelative().toString();
+		path.append(prefix);
+		if (prefix.length() > 0 && prefix.charAt(prefix.length() - 1)!= '/') {
+			path.append("/"); //$NON-NLS-1$
+		}
+		String archiveName = reference.getArchiveName();
+		if (archiveName == null || archiveName.isEmpty()) {
+			archiveName = reference.getReferencedComponent().getDeployedName() + ".jar"; //$NON-NLS-1$
+		}
+		path.append(archiveName);
+		return path.toString();
+	}
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/DynamicResourceFilter.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/DynamicResourceFilter.java
new file mode 100644
index 0000000..8d36d11
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/DynamicResourceFilter.java
@@ -0,0 +1,300 @@
+/*
+ * 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.eclipse.m2e.wtp.overlay.internal.modulecore;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.tools.ant.types.selectors.SelectorUtils;
+import org.eclipse.m2e.wtp.overlay.internal.utilities.PathUtil;
+
+/**
+ * Filter resources based on inclusion/exclusion patterns.
+ * <br/>
+ * This class is derived from ANT's {@link org.apache.tools.ant.DirectoryScanner}
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ */
+public class DynamicResourceFilter implements IResourceFilter {
+
+    protected static final String[] DEFAULTEXCLUDES = {
+        // Miscellaneous typical temporary files
+        "**/*~", //$NON-NLS-1$
+        "**/#*#",//$NON-NLS-1$
+        "**/.#*",//$NON-NLS-1$
+        "**/%*%",//$NON-NLS-1$
+        "**/._*",//$NON-NLS-1$
+
+        // CVS
+        "**/CVS",//$NON-NLS-1$
+        "**/CVS/**",//$NON-NLS-1$
+        "**/.cvsignore",//$NON-NLS-1$
+
+        // SCCS
+        "**/SCCS",//$NON-NLS-1$
+        "**/SCCS/**",//$NON-NLS-1$
+
+        // Visual SourceSafe
+        "**/vssver.scc",//$NON-NLS-1$
+
+        // Subversion
+        "**/.svn",//$NON-NLS-1$
+        "**/.svn/**",//$NON-NLS-1$
+
+        // Mac
+        "**/.DS_Store"//$NON-NLS-1$
+    };
+	
+    /** The patterns for the files to be included. */
+    protected String[] includes;
+
+    /** The patterns for the files to be excluded. */
+    protected String[] excludes;
+
+    protected boolean isCaseSensitive = true;
+
+    /**
+     * Array of all include patterns that contain wildcards.
+     *
+     * <p>Gets lazily initialized on the first invocation of
+     * isIncluded or isExcluded and cleared at the end of the scan
+     * method (cleared in clearCaches, actually).</p>
+     *
+     * @since Ant 1.6.3
+     */
+    private String[] includePatterns;
+
+    /**
+     * Array of all exclude patterns that contain wildcards.
+     *
+     * <p>Gets lazily initialized on the first invocation of
+     * isIncluded or isExcluded and cleared at the end of the scan
+     * method (cleared in clearCaches, actually).</p>
+     *
+     * @since Ant 1.6.3
+     */
+    private String[] excludePatterns;
+
+    /**
+     * Have the non-pattern sets and pattern arrays for in- and
+     * excludes been initialized?
+     *
+     * @since Ant 1.6.3
+     */
+    private boolean areNonPatternSetsReady = false;
+    
+    /**
+     * Set of all include patterns that are full file names and don't
+     * contain any wildcards.
+     *
+     * <p>If this instance is not case sensitive, the file names get
+     * turned to lower case.</p>
+     *
+     * <p>Gets lazily initialized on the first invocation of
+     * isIncluded or isExcluded and cleared at the end of the scan
+     * method (cleared in clearCaches, actually).</p>
+     *
+     * @since Ant 1.6.3
+     */
+    private Set<String> includeNonPatterns = new HashSet<>();
+
+    /**
+     * Set of all include patterns that are full file names and don't
+     * contain any wildcards.
+     *
+     * <p>If this instance is not case sensitive, the file names get
+     * turned to lower case.</p>
+     *
+     * <p>Gets lazily initialized on the first invocation of
+     * isIncluded or isExcluded and cleared at the end of the scan
+     * method (cleared in clearCaches, actually).</p>
+     *
+     * @since Ant 1.6.3
+     */
+    private Set<String> excludeNonPatterns = new HashSet<>();
+
+    
+    public DynamicResourceFilter(Collection<String> inclusions, Collection<String> exclusions) {
+		if (inclusions != null && !inclusions.isEmpty()) {
+			setIncludes(inclusions.toArray(new String[inclusions.size()]));
+		} else {
+			setIncludes(new String[]{"**/**"}); //$NON-NLS-1$
+		}
+		if (exclusions != null && !exclusions.isEmpty()) {
+			addExcludes(exclusions.toArray(new String[exclusions.size()]));
+		}
+		addExcludes(DEFAULTEXCLUDES);
+	}
+    
+    public synchronized void setIncludes(String[] includes) {
+        if (includes == null) {
+            this.includes = null;
+        } else {
+            this.includes = new String[includes.length];
+            for (int i = 0; i < includes.length; i++) {
+                this.includes[i] = normalizePattern(includes[i]);
+            }
+        }
+    }
+
+    public synchronized void setExcludes(String[] excludes) {
+        if (excludes == null) {
+            this.excludes = null;
+        } else {
+            this.excludes = new String[excludes.length];
+            for (int i = 0; i < excludes.length; i++) {
+                this.excludes[i] = normalizePattern(excludes[i]);
+            }
+        }
+    }    
+  
+    public synchronized void addExcludes(String[] excludes) {
+        if (excludes != null && excludes.length > 0) {
+            if (this.excludes != null && this.excludes.length > 0) {
+                String[] tmp = new String[excludes.length
+                                          + this.excludes.length];
+                System.arraycopy(this.excludes, 0, tmp, 0,
+                                 this.excludes.length);
+                for (int i = 0; i < excludes.length; i++) {
+                    tmp[this.excludes.length + i] =
+                        normalizePattern(excludes[i]);
+                }
+                this.excludes = tmp;
+            } else {
+                setExcludes(excludes);
+            }
+        }
+    }
+    
+    private static String normalizePattern(String p) {
+        String pattern = PathUtil.useSystemSeparator(p);
+        if (pattern.endsWith(File.separator)) {
+            pattern += "**";//$NON-NLS-1$
+        }
+        return pattern;
+    }
+    
+    /**
+     * Ensure that the in|exclude &quot;patterns&quot;
+     * have been properly divided up.
+     *
+     * @since Ant 1.6.3
+     */
+    private synchronized void ensureNonPatternSetsReady() {
+        if (!areNonPatternSetsReady) {
+            includePatterns = fillNonPatternSet(includeNonPatterns, includes);
+            excludePatterns = fillNonPatternSet(excludeNonPatterns, excludes);
+            areNonPatternSetsReady = true;
+        }
+    }
+
+    /**
+     * Add all patterns that are not real patterns (do not contain
+     * wildcards) to the set and returns the real patterns.
+     *
+     * @param set Set to populate.
+     * @param patterns String[] of patterns.
+     * @since Ant 1.6.3
+     */
+    private String[] fillNonPatternSet(Set<String> set, String[] patterns) {
+        ArrayList<String> al = new ArrayList<>(patterns.length);
+        for (int i = 0; i < patterns.length; i++) {
+            if (!SelectorUtils.hasWildcards(patterns[i])) {
+                set.add(isCaseSensitive() ? patterns[i]
+                    : patterns[i].toUpperCase());
+            } else {
+                al.add(patterns[i]);
+            }
+        }
+        return set.size() == 0 ? patterns
+            : al.toArray(new String[al.size()]);
+    }
+    
+    private boolean isCaseSensitive() {
+		return isCaseSensitive;
+	}
+
+	/**
+     * Test whether or not a name matches against at least one exclude
+     * pattern.
+     *
+     * @param name The name to match. Must not be <code>null</code>.
+     * @return <code>true</code> when the name matches against at least one
+     *         exclude pattern, or <code>false</code> otherwise.
+     */
+    protected boolean isExcluded(String name) {
+        ensureNonPatternSetsReady();
+
+        if (isCaseSensitive()
+            ? excludeNonPatterns.contains(name)
+            : excludeNonPatterns.contains(name.toUpperCase())) {
+            return true;
+        }
+        for (int i = 0; i < excludePatterns.length; i++) {
+            if (matchPath(excludePatterns[i], name, isCaseSensitive())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Test whether or not a name matches against at least one include
+     * pattern.
+     *
+     * @param name The name to match. Must not be <code>null</code>.
+     * @return <code>true</code> when the name matches against at least one
+     *         include pattern, or <code>false</code> otherwise.
+     */
+    protected boolean isIncluded(String name) {
+        ensureNonPatternSetsReady();
+
+        if (isCaseSensitive()
+            ? includeNonPatterns.contains(name)
+            : includeNonPatterns.contains(name.toUpperCase())) {
+            return true;
+        }
+        for (int i = 0; i < includePatterns.length; i++) {
+            if (matchPath(includePatterns[i], name, isCaseSensitive())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    protected static boolean matchPath(String pattern, String str,
+            boolean isCaseSensitive) {
+    	return SelectorUtils.matchPath(pattern, str, isCaseSensitive);
+    }
+
+	@Override
+	public boolean accepts(String path, boolean isFile) {
+		if (path == null) return false;
+		path = PathUtil.useSystemSeparator(path);
+		boolean isIncluded = isIncluded(path) && ! isExcluded(path);
+		return isIncluded;
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/FileSystemResourceFilter.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/FileSystemResourceFilter.java
new file mode 100644
index 0000000..843b0e4
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/FileSystemResourceFilter.java
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.modulecore;
+
+import java.io.Externalizable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.tools.ant.DirectoryScanner;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.m2e.wtp.overlay.internal.OverlayPluginActivator;
+import org.eclipse.m2e.wtp.overlay.internal.utilities.PathUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Filter for FileSystem resources.
+ * 
+ * @provisional This class has been added as part of a work in progress. It is
+ *              not guaranteed to work or remain the same in future releases.
+ *              For more information contact <a
+ *              href="mailto:m2e-wtp-dev@eclipse.org"
+ *              >m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ * 
+ */
+public class FileSystemResourceFilter implements IResourceFilter {
+
+	private static final Logger LOG = LoggerFactory.getLogger(FileSystemResourceFilter.class);
+	
+	private SimpleScanner scanner;
+
+	public FileSystemResourceFilter(Collection<String> inclusions,
+			Collection<String> exclusions, IPath baseDirPath) {
+		scanner = new SimpleScanner(baseDirPath);
+		if (inclusions != null && !inclusions.isEmpty()) {
+			scanner.setIncludes(inclusions.toArray(new String[inclusions.size()]));
+		} else {
+			scanner.setIncludes(new String[] { "**/**" }); //$NON-NLS-1$
+		}
+		if (exclusions != null && !exclusions.isEmpty()) {
+			scanner.addExcludes(exclusions.toArray(new String[exclusions.size()]));
+		}
+		scanner.addDefaultExcludes();
+		scanner.scan();
+	}
+
+	@Override
+	public boolean accepts(String resourcePath, boolean isFile) {
+		return scanner.accepts(resourcePath, isFile);
+	}
+
+	static class SimpleScanner extends DirectoryScanner {
+
+		private ScanResult scanResult;
+
+		private String[] includePatterns;
+
+		private String[] excludePatterns;
+
+		@Override
+		public synchronized void setIncludes(String[] includes) {
+			includePatterns = setFileSeparator(includes);
+			super.setIncludes(includePatterns);
+		}
+
+		public String[] getIncludePatterns() {
+			return includePatterns;
+		}
+
+		public String[] getExcludePatterns() {
+			return excludePatterns;
+		}
+
+		public boolean accepts(String resourcePath, boolean isFile) {
+			if (scanResult != null) {
+				return scanResult.accepts(resourcePath, isFile);
+			}
+			return false;
+		}
+
+		@Override
+		public synchronized void setExcludes(String[] excludes) {
+			excludePatterns = setFileSeparator(excludes);
+			super.setExcludes(excludePatterns);
+		}
+
+		private String[] setFileSeparator(String[] patterns) {
+			if (patterns != null) {
+				for (int i = 0; i < patterns.length; i++) {
+					patterns[i] = PathUtil.useSystemSeparator(patterns[i]);
+				}
+			}
+			return patterns;
+		}
+
+		private String baseDirAsString;
+
+		private long folderTimestamp;
+
+		public SimpleScanner(IPath baseDirPath) {
+			this.baseDirAsString = baseDirPath.toOSString();
+			setBasedir(baseDirAsString);
+			// If folder timestamp changed, gen'd scanId will change (different
+			// hashcode)
+			folderTimestamp = basedir.lastModified();
+		}
+
+		@Override
+		public void scan() throws IllegalStateException {
+			String scanId = Integer.toString(hashCode());
+			scanResult = ScanResult.read(scanId);
+			if (scanResult == null) {
+				super.scan();
+				scanResult = new ScanResult(scanId, baseDirAsString,
+						getIncludedFiles(), getExcludedFiles(),
+						getIncludedDirectories(), getExcludedDirectories());
+				ScanResult.write(scanResult);
+			}
+
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime
+					* result
+					+ ((baseDirAsString == null) ? 0 : baseDirAsString
+							.hashCode());
+			result = prime * result + Arrays.hashCode(excludePatterns);
+			result = prime * result + Arrays.hashCode(includePatterns);
+			result = prime * result
+					+ (int) (folderTimestamp ^ (folderTimestamp >>> 32));
+			return result;
+		}
+
+	}
+
+	static class ScanResult implements Externalizable {
+
+		private static final String COLLECTION_SEPARATOR = ";"; //$NON-NLS-1$
+
+		private static final long serialVersionUID = 1L;
+
+		private String baseDirAsString;
+
+		private String scanId;
+
+		private Set<String> includedFiles;
+		private Set<String> excludedFiles;
+		private Set<String> includedFolders;
+		private Set<String> excludedFolders;
+
+		public ScanResult() {
+			includedFiles = new HashSet<>(0);
+			excludedFiles = new HashSet<>(0);
+			includedFolders = new HashSet<>(0);
+			excludedFolders = new HashSet<>(0);
+		}
+
+		public ScanResult(String scanId, String baseDirAsString,
+				String[] incFiles, String[] excFiles, String[] incDirs,
+				String[] excDirs) {
+			this.scanId = scanId;
+			this.baseDirAsString = baseDirAsString;
+			includedFiles = new HashSet<>(Arrays.asList(incFiles));
+			excludedFiles = new HashSet<>(Arrays.asList(excFiles));
+			includedFolders = new HashSet<>(Arrays.asList(incDirs));
+			excludedFolders = new HashSet<>(Arrays.asList(excDirs));
+			completeIncludedFolders();
+		}
+
+		public String getBaseDirAsString() {
+			return baseDirAsString;
+		}
+
+		public void setBaseDirAsString(String baseDirAsString) {
+			this.baseDirAsString = baseDirAsString;
+		}
+
+		public Set<String> getIncludedFiles() {
+			return includedFiles;
+		}
+
+		public void setIncludedFiles(Set<String> includedFiles) {
+			this.includedFiles = includedFiles;
+		}
+
+		public Set<String> getExcludedFiles() {
+			return excludedFiles;
+		}
+
+		public void setExcludedFiles(Set<String> excludedFiles) {
+			this.excludedFiles = excludedFiles;
+		}
+
+		public Set<String> getIncludedFolders() {
+			return includedFolders;
+		}
+
+		public void setIncludedFolders(Set<String> includedFolders) {
+			this.includedFolders = includedFolders;
+		}
+
+		public Set<String> getExcludedFolders() {
+			return excludedFolders;
+		}
+
+		public void setExcludedFolders(Set<String> excludedFolders) {
+			this.excludedFolders = excludedFolders;
+		}
+
+		private String getId() {
+			return scanId;
+		}
+
+		static File getScanResultFile(String scanResultId) {
+			IPath location = OverlayPluginActivator.getWorkspacePluginPath();
+			File root = location.toFile();
+			File scanFile = new File(root, scanResultId + ".scan"); //$NON-NLS-1$
+			return scanFile;
+		}
+
+		boolean accepts(String name, boolean isFile) {
+
+			name = PathUtil.useSystemSeparator(name);
+			if (name.startsWith(baseDirAsString)) {
+				name = name.substring(baseDirAsString.length() + 1);
+			}
+
+			boolean res;
+			if (isFile) {
+				res = includedFiles.contains(name)
+						&& !excludedFiles.contains(name);
+			} else {
+				res = includedFolders.contains(name)
+						&& !excludedFolders.contains(name);
+			}
+			return res;
+		}
+
+		private void completeIncludedFolders() {
+			Set<String> missingParentFolders = new HashSet<>();
+			for (String folder : includedFolders) {
+				IPath filePath = new Path(folder);
+				IPath parentPath = filePath.removeLastSegments(1);
+				while (parentPath.segmentCount() > 0) {
+					String pathAsString = parentPath.toOSString();
+					if (!includedFolders.contains(pathAsString)) {
+						missingParentFolders.add(pathAsString);
+					}
+					parentPath = parentPath.removeLastSegments(1);
+				}
+			}
+			includedFolders.addAll(missingParentFolders);
+
+			for (String file : includedFiles) {
+				// For /some/foo/bar/file.ext, we need to add
+				// /some/foo/bar/
+				// /some/foo/
+				// /some/
+				// as included folders
+
+				IPath filePath = new Path(file);
+				IPath parentPath = filePath.removeLastSegments(1);
+				while (parentPath.segmentCount() > 0) {
+					if (includedFolders.add(parentPath.toOSString())) {
+						parentPath = parentPath.removeLastSegments(1);
+					} else {
+						// Parent hierarchy already added
+						break;
+					}
+				}
+			}
+		}
+
+		@Override
+		public void writeExternal(ObjectOutput out) throws IOException {
+			out.writeUTF(scanId);
+			out.writeUTF(baseDirAsString);
+			out.writeObject(toString(includedFiles));
+			out.writeObject(toString(excludedFiles));
+			out.writeObject(toString(includedFolders));
+			out.writeObject(toString(excludedFolders));
+		}
+
+		@Override
+		public void readExternal(ObjectInput in) throws IOException,
+				ClassNotFoundException {
+			this.scanId = in.readUTF();
+			this.baseDirAsString = in.readUTF();
+			this.includedFiles = toSet((String)in.readObject());
+			this.excludedFiles = toSet((String)in.readObject());
+			this.includedFolders = toSet((String)in.readObject());
+			this.excludedFolders = toSet((String)in.readObject());
+		}
+
+		private Set<String> toSet(String arrayAsString) {
+			if (arrayAsString == null) {
+				return Collections.emptySet();
+			}
+			return new HashSet<>(Arrays.asList(arrayAsString.split(COLLECTION_SEPARATOR)));
+		}
+
+		private String toString(Set<String> stringSet) {
+			if (stringSet == null || stringSet.isEmpty()) {
+				return ""; //$NON-NLS-1$
+			}
+			StringBuilder sb = new StringBuilder();
+			for (String s : stringSet) {
+				sb.append(s).append(COLLECTION_SEPARATOR);	
+			}
+		    int lastSeparatorIdx = sb.lastIndexOf(COLLECTION_SEPARATOR);
+		    if (lastSeparatorIdx > -1) {
+		    	sb.deleteCharAt(lastSeparatorIdx);
+		    }
+			return sb.toString();
+		}
+
+		public static void write(ScanResult scanResult) {
+			File scanResultFile = getScanResultFile(scanResult.getId());
+			ObjectOutputStream oos = null;
+			try {
+				FileOutputStream fos = new FileOutputStream(scanResultFile);
+				oos = new ObjectOutputStream(fos);
+				scanResult.writeExternal(oos);
+				oos.flush();
+			} catch (Exception ex) {
+				LOG.error("Unable to serialize scan results", ex); //$NON-NLS-1$
+			} finally {
+				try {
+					if (oos != null) {
+						oos.close();
+					}
+				} catch (Exception ignore) {
+				}
+			}
+		}
+
+		public static ScanResult read(String scanResultId) {
+			File scanResultFile = getScanResultFile(scanResultId);
+			if (!scanResultFile.isFile()) {
+				return null;
+			}
+			ScanResult scanResult = null;
+			ObjectInputStream ois = null;
+			try {
+				FileInputStream fis = new FileInputStream(scanResultFile);
+				ois = new ObjectInputStream(fis);
+				scanResult = new ScanResult();
+				scanResult.readExternal(ois);
+
+			} catch (Exception ex) {
+				LOG.error("Unable to read scan results", ex); //$NON-NLS-1$
+				scanResultFile.delete();
+				scanResult = null;
+			} finally {
+				try {
+					if (ois != null) {
+						ois.close();
+					}
+				} catch (Exception ignore) {
+				}
+			}
+			return scanResult;
+		}
+
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/IFilteredVirtualFolder.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/IFilteredVirtualFolder.java
new file mode 100644
index 0000000..e0309f7
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/IFilteredVirtualFolder.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.modulecore;
+
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+
+/**
+ * Represents a {@link IVirtualFolder} that can be filtered out from some resources.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ * 
+ */
+public interface IFilteredVirtualFolder extends IVirtualFolder {
+
+	void setFilter(IResourceFilter filter);
+	
+	IResourceFilter getFilter();
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/IResourceFilter.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/IResourceFilter.java
new file mode 100644
index 0000000..1ed9a9e
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/IResourceFilter.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.modulecore;
+
+
+/**
+ * Represents a resource filter. A resource is filtered if it's path is not accepted.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ * 
+ */
+public interface IResourceFilter {
+
+	boolean accepts(String path, boolean isFile);
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/OverlaySelfComponent.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/OverlaySelfComponent.java
new file mode 100644
index 0000000..4d08eeb
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/OverlaySelfComponent.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.overlay.internal.modulecore;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.m2e.wtp.overlay.modulecore.IOverlayVirtualComponent;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+
+/**
+ * Overlay component pointing at it self referencing component.
+ *
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ * 
+ */
+public class OverlaySelfComponent extends OverlayVirtualComponent implements IOverlayVirtualComponent {
+
+	public OverlaySelfComponent(IProject aComponentProject) {
+		super(aComponentProject);
+	}
+
+	@Override
+	public IVirtualFolder getRootFolder() {
+		IVirtualComponent component = ComponentCore.createComponent(getProject());
+		IVirtualFolder root =null;
+		if (component != null) {
+			root = component.getRootFolder();
+		}
+		return root;
+	}
+	
+	@Override
+	public IVirtualReference[] getReferences(Map<String, Object> paramMap){
+		return new IVirtualReference[0];
+	}
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/OverlayVirtualArchiveComponent.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/OverlayVirtualArchiveComponent.java
new file mode 100644
index 0000000..640d696
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/OverlayVirtualArchiveComponent.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.overlay.internal.modulecore;
+
+import java.io.File;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.m2e.wtp.overlay.internal.Messages;
+import org.eclipse.m2e.wtp.overlay.modulecore.IOverlayVirtualComponent;
+import org.eclipse.m2e.wtp.overlay.modulecore.UnpackArchiveJob;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+
+/**
+ * Archive-based Overlay Virtual Component. 
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+public class OverlayVirtualArchiveComponent extends VirtualArchiveComponent implements IOverlayVirtualComponent {
+
+	protected IPath unpackDirPath;
+	
+	private Set<String> inclusions;
+	
+	private Set<String> exclusions;
+
+	private ResourceListVirtualFolder cachedRoot;
+
+	private long lastCacheUpdate;
+	
+	private static int MAX_CACHE = 2000;
+	
+	public OverlayVirtualArchiveComponent(IProject aComponentProject,
+			String archiveLocation, IPath unpackDirPath, IPath aRuntimePath) {
+		super(aComponentProject, archiveLocation, aRuntimePath);
+		this.unpackDirPath = unpackDirPath;
+	}
+
+	@Override
+	public void setInclusions(Set<String> inclusionPatterns) {
+		this.inclusions = inclusionPatterns;
+	}
+
+	@Override
+	public void setExclusions(Set<String> exclusionPatterns) {
+		this.exclusions = exclusionPatterns;
+	}
+	
+	@Override
+	public IVirtualFolder getRootFolder() {
+		IVirtualComponent component = ComponentCore.createComponent(getProject());
+		File archive = getArchive();
+		ResourceListVirtualFolder root =null;
+		if (component != null && archive != null) {
+			IFolder unpackedFolder = getUnpackedArchiveFolder(archive);
+			if (isUnpackNeeded(archive, unpackedFolder)) {
+			  Job[] currentJobs = Job.getJobManager().find(unpackedFolder);
+			  if (currentJobs.length == 0) {
+				  Job job = new UnpackArchiveJob(NLS.bind(Messages.OverlayVirtualArchiveComponent_Unpacking_Job,archive.getName()), archive, unpackedFolder);
+				  job.schedule();
+			  }
+			  root = new ResourceListVirtualFolder(getProject(), getRuntimePath(), new IContainer[] {}); 	
+			} else {
+			  	
+			  if (cachedRoot != null && (System.currentTimeMillis() - lastCacheUpdate) < MAX_CACHE){
+					return cachedRoot;
+			  } 
+				
+			  IContainer[] containers = new IContainer[] {unpackedFolder};
+			  root = new ResourceListVirtualFolder(getProject(), getRuntimePath(), containers);
+			  root.setFilter(new FileSystemResourceFilter(inclusions, exclusions, unpackedFolder.getLocation()));
+			  
+			  lastCacheUpdate = System.currentTimeMillis();
+			  cachedRoot = root;
+			}
+		}
+		return root;
+	}
+
+	protected IFolder getUnpackedArchiveFolder(File archive) {
+		IFolder overlaysFolder =  getProject().getFolder(unpackDirPath);
+		return overlaysFolder.getFolder(archive.getName());
+	}
+
+	private File getArchive() {
+		File archive = (File)getAdapter(File.class);
+		if (archive == null || !archive.exists() || !archive.canRead()) {
+			return null;
+			//TODO should raise an exception // throw new IOException("Unable to read "+ getArchivePath());
+		}
+		return archive;
+	}
+	
+	private boolean isUnpackNeeded(File archive, IFolder unpackFolder) {
+		if (!unpackFolder.exists()) {
+		  return true;
+		}
+		long lastUnpacked = new File(unpackFolder.getLocation().toOSString()).lastModified();
+		long lastModified = archive.lastModified();
+		return lastModified > lastUnpacked;
+	}
+
+	public IPath getUnpackFolderPath() {
+		return unpackDirPath;
+	}
+
+	@Override
+	public Set<String> getExclusions() {
+		return exclusions;
+	}
+
+	@Override
+	public Set<String> getInclusions() {
+		return inclusions;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result
+				+ ((exclusions == null) ? 0 : exclusions.hashCode());
+		result = prime * result
+				+ ((inclusions == null) ? 0 : inclusions.hashCode());
+		result = prime * result
+				+ ((unpackDirPath == null) ? 0 : unpackDirPath.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (!super.equals(obj))
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		OverlayVirtualArchiveComponent other = (OverlayVirtualArchiveComponent) obj;
+		if (!super.equals(obj)) {
+			return false;
+		}
+		if (exclusions == null) {
+			if (other.exclusions != null)
+				return false;
+		} else if (!exclusions.equals(other.exclusions))
+			return false;
+		if (inclusions == null) {
+			if (other.inclusions != null)
+				return false;
+		} else if (!inclusions.equals(other.inclusions))
+			return false;
+		if (unpackDirPath == null) {
+			if (other.unpackDirPath != null)
+				return false;
+		} else if (!unpackDirPath.equals(other.unpackDirPath))
+			return false;
+		return true;
+	}
+	
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/OverlayVirtualComponent.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/OverlayVirtualComponent.java
new file mode 100644
index 0000000..4bb34ef
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/OverlayVirtualComponent.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.overlay.internal.modulecore;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.common.internal.modulecore.AddClasspathFoldersParticipant;
+import org.eclipse.jst.common.internal.modulecore.AddClasspathLibReferencesParticipant;
+import org.eclipse.jst.common.internal.modulecore.AddMappedOutputFoldersParticipant;
+import org.eclipse.jst.common.internal.modulecore.IgnoreJavaInSourceFolderParticipant;
+import org.eclipse.jst.common.internal.modulecore.SingleRootExportParticipant;
+import org.eclipse.jst.j2ee.internal.common.exportmodel.JEEHeirarchyExportParticipant;
+import org.eclipse.jst.j2ee.internal.common.exportmodel.JavaEESingleRootCallback;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.wtp.overlay.modulecore.IOverlayVirtualComponent;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent;
+import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent.FlatComponentTaskModel;
+import org.eclipse.wst.common.componentcore.internal.flat.IFlattenParticipant;
+import org.eclipse.wst.common.componentcore.internal.resources.VirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+
+/**
+ * Project based Overlay Virtual Component.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+public class OverlayVirtualComponent extends VirtualComponent implements
+		IOverlayVirtualComponent {
+
+	protected IProject project;
+
+	protected Set<String> exclusionPatterns;
+	
+	protected Set<String> inclusionPatterns;
+	
+	protected Set<IVirtualReference> references;
+	
+	private CompositeVirtualFolder cachedRoot;
+	
+	private long lastCacheUpdate;
+	
+	private static int MAX_CACHE = 2000;
+	
+	public OverlayVirtualComponent(IProject project) {
+		super(project, ROOT);
+		this.project = project;
+	}
+
+	@Override
+	public IVirtualFolder getRootFolder() {
+		return getRoot();
+	}
+
+	private CompositeVirtualFolder getRoot() {
+		if (cachedRoot != null && (System.currentTimeMillis() - lastCacheUpdate) < MAX_CACHE){
+			return cachedRoot;
+		}
+		
+		if (project != null) {
+			IVirtualComponent component = ComponentCore.createComponent(project);
+			if (component != null) {
+				//FlatVirtualComponent will build the project structure from the definition in .component
+				FlatVirtualComponent flatVirtualComponent = new FlatVirtualComponent(component, getOptions());
+				IResourceFilter filter = new DynamicResourceFilter(getInclusions(), getExclusions()); 
+				cachedRoot = new CompositeVirtualFolder(flatVirtualComponent, ROOT, filter);
+			}
+		}
+		lastCacheUpdate = System.currentTimeMillis();
+		return cachedRoot;
+	}
+	
+	private FlatComponentTaskModel getOptions() {
+		FlatComponentTaskModel options = new FlatComponentTaskModel();
+		//Participants produce IFlatResources[]
+		//TODO Maybe deal with the inclusion/exclusion stuff on the participant level (using an Adapter or a Callback pattern)
+		IFlattenParticipant[] participants = new IFlattenParticipant[] { 
+	    	       new SingleRootExportParticipant(new JavaEESingleRootCallback()), 
+	    	       //JEEHeirarchyExportParticipant doesn't deploy utility java projects
+	    	       //if JEEHeirarchyExportParticipant  is skipped, utility java projects are deployed as exploded folders, 
+	    	       //only the sources, not classes; Should be deployed as zips. 
+	    	       new JEEHeirarchyExportParticipant() {
+	    	    	   @Override
+	    	    	protected boolean isApprovedNesting(String parentType,
+	    	    			String childType, boolean binary) {
+	    	    		   if( childType == null )
+	    	    				return false;
+	    	    			if( IJ2EEFacetConstants.UTILITY.equals(childType) && binary)
+	    	    				return false; // child utility project 
+	    	    			if( IJ2EEFacetConstants.WEBFRAGMENT.equals(childType) && binary)
+	    	    				return false; // child utility project 
+	    	    			return true;
+	    	    	}
+	    	       },
+	    	       new AddClasspathLibReferencesParticipant(), 
+	    	       new AddClasspathFoldersParticipant(), 
+	    	       new AddMappedOutputFoldersParticipant(),
+	    	       new IgnoreJavaInSourceFolderParticipant() 
+	    	       };
+		options.put(FlatVirtualComponent.PARTICIPANT_LIST, Arrays.asList(participants));
+		return options;
+	}
+
+	@Override
+	public void setInclusions(Set<String> inclusionPatterns) {
+		this.inclusionPatterns = inclusionPatterns;
+	}
+
+	@Override
+	public void setExclusions(Set<String> exclusionPatterns) {
+		this.exclusionPatterns = exclusionPatterns;
+	}
+
+	@Override
+	public Set<String> getExclusions() {
+		return exclusionPatterns;
+	}
+
+	@Override
+	public Set<String> getInclusions() {
+		return inclusionPatterns;
+	}
+	@Override
+	public IVirtualReference[] getReferences(Map<String, Object> paramMap){
+		CompositeVirtualFolder  root = getRoot(); 
+		if (root != null) {
+			try {
+				IVirtualReference[] references = root.getReferences(); 
+				return references;
+			} catch (Exception e) {
+				//TODO handle exception
+				e.printStackTrace();
+			}
+		}
+		return new IVirtualReference[0];
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime
+				* result
+				+ ((exclusionPatterns == null) ? 0 : exclusionPatterns
+						.hashCode());
+		result = prime
+				* result
+				+ ((inclusionPatterns == null) ? 0 : inclusionPatterns
+						.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (!super.equals(obj))
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		OverlayVirtualComponent other = (OverlayVirtualComponent) obj;
+		if (!super.equals(obj)) {
+			return false;
+		}
+		if (exclusionPatterns == null) {
+			if (other.exclusionPatterns != null)
+				return false;
+		} else if (!exclusionPatterns.equals(other.exclusionPatterns))
+			return false;
+		if (inclusionPatterns == null) {
+			if (other.inclusionPatterns != null)
+				return false;
+		} else if (!inclusionPatterns.equals(other.inclusionPatterns))
+			return false;
+		return true;
+	}
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/ResourceListVirtualFolder.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/ResourceListVirtualFolder.java
new file mode 100644
index 0000000..a480445
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/modulecore/ResourceListVirtualFolder.java
@@ -0,0 +1,217 @@
+/*************************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Red Hat, Inc. - Initial implementation.
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.modulecore;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.m2e.wtp.overlay.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.componentcore.internal.resources.VirtualFile;
+import org.eclipse.wst.common.componentcore.internal.resources.VirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Virtual Folder traversing the {@link IResource}s members of a {@link IVirtualComponent} 
+ * and mapping them as {@link IVirtualResource}.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ *
+ */
+@SuppressWarnings("restriction")
+public class ResourceListVirtualFolder extends VirtualFolder implements IFilteredVirtualFolder {
+
+	private static final Logger LOG = LoggerFactory.getLogger(ResourceListVirtualFolder.class);
+
+	private ArrayList<IResource> children;
+	private ArrayList<IContainer> underlying;
+	private IResourceFilter filter;
+	
+	public ResourceListVirtualFolder(
+			IProject aComponentProject,
+			IPath aRuntimePath) {
+		super(aComponentProject, aRuntimePath);
+		this.children = new ArrayList<>();
+		this.underlying = new ArrayList<>();
+	}
+
+	public ResourceListVirtualFolder(
+			IProject aComponentProject,
+			IPath aRuntimePath, IContainer[] underlyingContainers) {
+		this(aComponentProject, aRuntimePath);
+		addUnderlyingResource(underlyingContainers);
+	}
+
+	public ResourceListVirtualFolder(
+			IProject aComponentProject,
+			IPath aRuntimePath, IContainer[] underlyingContainers, 
+			IResource[] looseResources) {
+		this(aComponentProject, aRuntimePath, underlyingContainers);
+		addChildren(looseResources);
+	}
+
+	@Override
+	public void setFilter(IResourceFilter filter) {
+		this.filter = filter;
+	}
+	
+	protected void addUnderlyingResource(IResource resource) {
+		if( resource instanceof IContainer ) { 
+			underlying.add((IContainer)resource);
+			try {
+				IResource[] newChildren = ((IContainer)resource).members();
+				for( int i = 0; i < newChildren.length; i++ ) {
+					children.add(newChildren[i]);
+				}
+			} catch( CoreException ce) {
+				LOG.error(ce.getLocalizedMessage(), ce);
+			}
+		}
+	}
+
+	protected void addUnderlyingResource(IResource[] resources) {
+		for( int i = 0; i < resources.length; i++ ) {
+			addUnderlyingResource(resources[i]);
+		}
+	}
+	
+	protected void addChild(IResource resource) {
+		this.children.add(resource);
+	}
+
+	protected void addChildren(IResource[] resources) {
+		this.children.addAll(Arrays.asList(resources));
+	}
+	
+	@Override
+	public IResource getUnderlyingResource() {
+		return getUnderlyingFolder();
+	}
+	
+	@Override
+	public IResource[] getUnderlyingResources() {
+		return getUnderlyingFolders();
+	}
+
+	@Override
+	public IContainer getUnderlyingFolder() { 
+		return underlying.size() > 0 ? underlying.get(0) : null;
+	}
+	
+	@Override
+	public IContainer[] getUnderlyingFolders() {
+		return underlying.toArray(new IContainer[underlying.size()]);
+	}
+
+	@Override
+	public IVirtualResource[] members(int memberFlags) throws CoreException {
+		HashMap<String, IVirtualResource> virtualResources = new HashMap<String, IVirtualResource>(); // result
+		IResource[] resources = this.children.toArray(new IResource[this.children.size()]);
+		for( int i = 0; i < resources.length; i++ ) {
+			handleResource(resources[i], virtualResources, memberFlags);
+		}
+		Collection<IVirtualResource> c = virtualResources.values();
+		return c.toArray(new IVirtualResource[c.size()]);
+	}
+
+	protected void handleResource(final IResource resource, HashMap<String, IVirtualResource> map, int memberFlags) throws CoreException {
+		if (resource == null) {
+			return;
+		}
+		boolean isFile =  resource instanceof IFile;
+		String path = resource.getLocation().toPortableString();
+		if( filter != null && !filter.accepts(path, isFile)) {
+		  return;
+		}
+			
+		if( isFile) {
+			if( !map.containsKey(resource.getName()) ) {
+				IVirtualFile virtFile = new VirtualFile(getProject(), 
+						getRuntimePath().append(((IFile)resource).getName()), (IFile)resource) {
+					
+					@Override
+					public IPath getWorkspaceRelativePath() {
+						IPath wrp = resource.getFullPath(); 
+						return wrp;
+					}
+				};
+				map.put(resource.getName(), virtFile);
+				return;
+			} 
+		}// end file
+		else if( resource instanceof IContainer ) {
+			IContainer realContainer = (IContainer) resource;
+			IVirtualResource previousValue = map.get(resource.getName());
+			if( previousValue != null && previousValue instanceof ResourceListVirtualFolder ) {
+				((ResourceListVirtualFolder)previousValue).addUnderlyingResource(realContainer);
+			} else if( previousValue == null ) {
+				ResourceListVirtualFolder childFolder = 
+					new ResourceListVirtualFolder(getProject(), getRuntimePath().append(resource.getName()));
+				childFolder.addUnderlyingResource(realContainer);
+				if( filter != null )
+					childFolder.setFilter(filter);
+				map.put(resource.getName(), childFolder);
+			}
+		} // end container
+	}
+
+	@Override
+	public IResourceFilter getFilter() {
+		return filter;
+	}
+	
+	@Override
+	public IVirtualResource findMember(IPath path, int searchFlags) {
+		if (underlying == null || path == null) {
+			return null;
+		}
+		if (path.isAbsolute()) {
+			path = path.makeRelative();
+		}
+		for(IResource resource : underlying) {
+			if (resource instanceof IContainer) {
+				IContainer c = (IContainer) resource;
+				IResource candidate = c.findMember(path, true);
+				if (candidate != null && candidate.exists()) {
+					HashMap<String, IVirtualResource> map = new HashMap<String, IVirtualResource>(1);
+					try {
+						handleResource(candidate, map, 0);
+						if (!map.isEmpty()) {
+							IVirtualResource vr = map.values().iterator().next();
+							return vr;
+						}
+					} catch (CoreException e) {
+						String message = NLS.bind(Messages.ResourceListVirtualFolder_Error_Finding_Member, path, candidate);
+						LOG.error(message, e);
+					}
+				}
+			}
+		}
+    	return null;
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/preferences/OverlayPreferencesInitializer.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/preferences/OverlayPreferencesInitializer.java
new file mode 100644
index 0000000..c86aaa9
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/preferences/OverlayPreferencesInitializer.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.m2e.wtp.overlay.OverlayConstants;
+import org.eclipse.m2e.wtp.overlay.internal.OverlayPluginActivator;
+
+public class OverlayPreferencesInitializer extends AbstractPreferenceInitializer {
+
+  /**
+   * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+   */
+  @Override
+public void initializeDefaultPreferences() {
+    IEclipsePreferences store = DefaultScope.INSTANCE.getNode(OverlayPluginActivator.PLUGIN_ID);
+    store.putBoolean(OverlayConstants.P_REPUBLISH_ON_PROJECT_CHANGE, true);
+  }
+}
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/servers/OverlayResourceChangeListener.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/servers/OverlayResourceChangeListener.java
new file mode 100644
index 0000000..e250858
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/servers/OverlayResourceChangeListener.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.servers;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.m2e.wtp.overlay.OverlayConstants;
+import org.eclipse.m2e.wtp.overlay.internal.modulecore.OverlayVirtualComponent;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+import org.eclipse.wst.server.core.IModule;
+import org.eclipse.wst.server.core.IServer;
+import org.eclipse.wst.server.core.ServerCore;
+import org.eclipse.wst.server.core.internal.Server;
+
+/**
+ * Listens to overlaid project changes to force server redeployment.
+ * 
+ * @author Fred Bricon
+ *
+ */
+public class OverlayResourceChangeListener implements IResourceChangeListener {
+
+	@Override
+	public void resourceChanged(IResourceChangeEvent event) {
+		IResourceDelta delta =  event.getDelta();
+		if (delta == null) {
+			return;
+		}
+
+		IServer[] servers = ServerCore.getServers();
+		if (servers.length == 0) {
+			//No servers defined, so nothing to do
+			return;
+		}
+		
+		IResourceDelta[] projectDeltas = delta.getAffectedChildren();
+		if (projectDeltas == null || projectDeltas.length == 0) {
+			return;
+		}
+	   
+		boolean buildOccurred = hasBuildOccurred(event);
+	   	
+		Set<IProject> changedProjects  = getChangedProjects(projectDeltas);
+		if (changedProjects.isEmpty()) {
+			return;
+		}
+		
+		Map<IServer, List<IModule>> republishableServers = new HashMap<IServer, List<IModule>>(servers.length);
+		Map<IProject, Collection<IProject>> overlaidProjects = new HashMap<IProject, Collection<IProject>>();
+		
+		for (IServer server : servers) {
+			modules : for (IModule module : server.getModules()) {
+				if (server.getModulePublishState(new IModule[]{module}) == IServer.PUBLISH_STATE_INCREMENTAL) {
+					continue;
+				}
+				IProject moduleProject = module.getProject();
+				Collection<IProject> overlays = overlaidProjects.get(moduleProject);
+				if (overlays == null) {
+					overlays = new HashSet<>();
+					overlaidProjects.put(moduleProject, overlays);
+					Set<IProject> analyzedProjects = new HashSet<>();
+					analyzedProjects.add(moduleProject);
+					collectOverlays(moduleProject, overlays, analyzedProjects);
+				}
+				for (IProject changedProject : changedProjects) {
+					if (overlays.contains(changedProject)) {
+						List<IModule> republishableModules = republishableServers.get(server);
+						if (republishableModules == null) {
+							republishableModules = new ArrayList<>(server.getModules().length);
+							republishableServers.put(server, republishableModules);
+						}
+						republishableModules.add(module);
+						break modules;
+					}
+				}
+			}
+		}
+		
+		if (republishableServers.isEmpty()) {
+			return;
+		}
+		
+		boolean isPublishOverlaysEnabled = isPublishOverlaysEnabled();
+		for(Map.Entry<IServer, List<IModule>> entries : republishableServers.entrySet()) {
+			IServer iserver = entries.getKey();
+			boolean shouldPublish = isPublishOverlaysEnabled;
+			if (iserver instanceof Server) {
+				Server server = ((Server)iserver);
+				List<IModule> modules = entries.getValue();
+				IModule[] mod = new IModule[modules.size()];
+				modules.toArray(mod);
+				server.setModulePublishState(mod, IServer.PUBLISH_STATE_INCREMENTAL);
+				int autoPublishSetting = server.getAutoPublishSetting(); 
+				shouldPublish = shouldPublish && (autoPublishSetting == Server.AUTO_PUBLISH_RESOURCE || 
+						                (autoPublishSetting == Server.AUTO_PUBLISH_BUILD && buildOccurred));
+			}
+			if (shouldPublish && iserver.getServerState() == IServer.STATE_STARTED) {
+				iserver.publish(IServer.PUBLISH_INCREMENTAL, new NullProgressMonitor());
+			} 
+		}
+	}
+
+	private boolean isPublishOverlaysEnabled() {
+	  boolean isEnabled = InstanceScope.INSTANCE.getNode(OverlayConstants.PLUGIN_ID)
+	                      .getBoolean(OverlayConstants.P_REPUBLISH_ON_PROJECT_CHANGE, true);
+	  return isEnabled;
+	}
+
+	private Set<IProject> getChangedProjects(IResourceDelta[] projectDeltas) {
+		Set<IProject> projects = new HashSet<>();
+		if (projectDeltas != null) {
+			for (IResourceDelta delta : projectDeltas) {
+				IResource resource = delta.getResource();
+				if (resource instanceof IProject) {
+					projects.add((IProject) resource);
+				}
+			}
+		}
+		return projects;
+	}
+
+     private boolean hasBuildOccurred(IResourceChangeEvent event) {
+    	 if (event == null) {
+    		 return false;
+    	 }
+         int kind = event.getBuildKind();
+         return (kind == IncrementalProjectBuilder.INCREMENTAL_BUILD) ||
+                (kind == IncrementalProjectBuilder.FULL_BUILD) ||
+                ((kind == IncrementalProjectBuilder.AUTO_BUILD && ResourcesPlugin.getWorkspace().isAutoBuilding()));
+     }
+
+     private void collectOverlays(IProject project, Collection<IProject> overlays, Set<IProject> analyzedProjects) {
+       if (!ModuleCoreNature.isFlexibleProject(project)) {
+         return;
+       }
+       IVirtualComponent component = ComponentCore.createComponent(project);
+       if (component == null) {
+         return;
+       }
+       IVirtualReference[] references = component.getReferences();
+       if (references == null || references.length == 0) {
+         return;
+       }
+       for (IVirtualReference reference : references) {
+         IVirtualComponent vc = reference.getReferencedComponent();
+         IProject refProject = vc.getProject();
+         if(project == refProject) {
+           continue;
+         }
+         if (OverlayVirtualComponent.class.equals(vc.getClass())){
+           if (!overlays.contains(refProject)) {
+             overlays.add(refProject);
+           }
+         }
+         if (!analyzedProjects.contains(refProject)) {
+           analyzedProjects.add(refProject);
+           collectOverlays(refProject, overlays, analyzedProjects);
+         }
+       }
+     }
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/utilities/CompressionUtil.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/utilities/CompressionUtil.java
new file mode 100644
index 0000000..f1d0c6d
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/utilities/CompressionUtil.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Red Hat, Inc. - extracted unzip method out of the original code
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.utilities;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.util.FileUtils;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.m2e.wtp.overlay.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Compression utility class.
+ * 
+ * Most of the code is copied from <i>org.eclipse.gef.examples.ui.pde.internal.wizards.ProjectUnzipperNewWizard</i>
+ *  
+ * @author Fred Bricon
+ *
+ */
+public class CompressionUtil {
+	
+	private final static int BUFFER = 1024*4;
+	
+	private CompressionUtil() {}
+
+	/**
+	 * Unzips the platform formatted zip file to specified folder
+	 * 
+	 * @param zipFile
+	 *            The platform formatted zip file
+	 * @param projectFolderFile
+	 *            The folder where to unzip the archive
+	 * @param monitor
+	 *            Monitor to display progress and/or cancel operation
+	 * @throws IOException
+	 * @throws FileNotFoundException
+	 * @throws InterruptedException
+	 */
+	public static void unzip(File archive, File projectFolderFile,
+			IProgressMonitor monitor) throws IOException,
+			FileNotFoundException, InterruptedException {
+
+		initialize(projectFolderFile);
+		
+		ZipFile zipFile = new ZipFile(archive);
+		Enumeration<? extends ZipEntry> e = zipFile.entries();
+
+		if (monitor == null) {
+			monitor = new NullProgressMonitor();
+		}
+		
+		monitor.beginTask(Messages.CompressionUtil_Extracting_Task, zipFile.size());
+		try {
+			while (e.hasMoreElements()) {
+				ZipEntry zipEntry = e.nextElement();
+				File file = new File(projectFolderFile, zipEntry.getName());
+				
+				if (!zipEntry.isDirectory()) {
+					monitor.subTask(zipEntry.getName());
+								
+					File parentFile = file.getParentFile();
+					if (null != parentFile && !parentFile.exists()) {
+						parentFile.mkdirs();
+					}
+					
+					InputStream is = null;
+					OutputStream os = null;
+					
+					try {
+						is = zipFile.getInputStream(zipEntry);
+						os = new FileOutputStream(file);
+						
+						byte[] buffer = new byte[BUFFER];
+						while (true) {
+							int len = is.read(buffer);
+							if (len < 0)
+								break;
+							os.write(buffer, 0, len);
+						}
+					} finally {
+						FileUtils.close(is);
+						FileUtils.close(os);
+					}
+				}
+				
+				monitor.worked(1);
+				
+				if (monitor.isCanceled()) {
+					throw new InterruptedException(NLS.bind(Messages.CompressionUtil_Unzipping_Interrupted, archive.getAbsolutePath(), projectFolderFile.getAbsolutePath()));
+				}
+			}
+		} finally {
+			if (zipFile != null) {
+				try {
+					zipFile.close();
+				} catch (IOException ioe) {
+					//ignore
+				}
+			}
+		}
+	}
+
+	private static void initialize(File outputDirectory) throws IOException {
+      // Create output directory if needed
+      if (!outputDirectory.mkdirs() && !outputDirectory.exists())
+      {
+         throw new IOException(Messages.CompressionUtil_Unable_To_Create_Output_Dir + outputDirectory);
+      }
+      if (outputDirectory.isFile())
+      {
+         throw new IllegalArgumentException(NLS.bind(Messages.CompressionUtil_Unpacking_Unable,outputDirectory.getAbsolutePath()));
+      }
+	}
+	
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/utilities/PathUtil.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/utilities/PathUtil.java
new file mode 100644
index 0000000..c09f73b
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/internal/utilities/PathUtil.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.internal.utilities;
+
+import java.io.File;
+
+public class PathUtil {
+
+	public static String useSystemSeparator(String name) {
+		if (name == null) return null;
+		return name.replace('/', File.separatorChar)
+	            .replace('\\', File.separatorChar);
+	}
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/IOverlayVirtualComponent.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/IOverlayVirtualComponent.java
new file mode 100644
index 0000000..b0545e0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/IOverlayVirtualComponent.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.overlay.modulecore;
+
+import java.util.Set;
+
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+
+/**
+ * Represents an Overlay virtual component. This component's resources can be filtered out depending
+ * on its inclusion and exclusion patterns. 
+ *
+ * @author Fred Bricon
+ */
+public interface IOverlayVirtualComponent extends IVirtualComponent{
+
+	void setInclusions(Set<String> inclusionPatterns);
+	
+	void setExclusions(Set<String> inclusionPatterns);
+	
+	Set<String> getExclusions();
+
+	Set<String> getInclusions();
+
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/ModuleURIUtil.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/ModuleURIUtil.java
new file mode 100644
index 0000000..3a9ba23
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/ModuleURIUtil.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.modulecore;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility class to manipulate module URIs.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ *
+ */
+public class ModuleURIUtil {
+
+	public static final String URI_SEPARATOR = "&"; //$NON-NLS-1$
+	
+	public static Map<String, String> parseUri(String uri) {
+		if (uri == null || uri.length() == 0) {
+			return Collections.emptyMap();
+		}
+		Map<String, String> parameters = new HashMap<String, String>();
+		int start = uri.indexOf("?");  //$NON-NLS-1$
+		if (start > -1) {
+			uri = uri.substring(start+1);
+			String[] entries = uri.split(URI_SEPARATOR);
+			for (String entry : entries) {
+				if ("".equals(entry)) { //$NON-NLS-1$
+					continue;
+				}
+				String[] keyValue = entry.split("="); //$NON-NLS-1$
+				if (keyValue.length == 2) {
+					parameters.put(keyValue[0], keyValue[1]);
+				}
+			}
+		}
+		return parameters;
+	}
+	
+	public static String appendToUri(String uri, Map<String, String> parameters) {
+		if (parameters == null || parameters.isEmpty()) {
+			return uri;
+		}
+		StringBuilder sb = new StringBuilder(uri);
+		sb.append("?"); //$NON-NLS-1$
+		for (Map.Entry<String, String> entry : parameters.entrySet()) {
+			   sb.append(entry.getKey())
+			   .append("=") //$NON-NLS-1$
+			   .append(entry.getValue())
+			   .append(URI_SEPARATOR);
+		}
+		return sb.substring(0, sb.length()-1);
+	}
+	
+	public static String extractModuleName(String uri) {
+		if (uri != null && uri.indexOf("?") > 0) { //$NON-NLS-1$
+			return uri.substring(0,uri.indexOf("?")); //$NON-NLS-1$
+		}
+		return uri;
+	}
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/OverlayComponentCore.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/OverlayComponentCore.java
new file mode 100644
index 0000000..1bbc337
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/OverlayComponentCore.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.overlay.modulecore;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.m2e.wtp.overlay.internal.modulecore.OverlaySelfComponent;
+import org.eclipse.m2e.wtp.overlay.internal.modulecore.OverlayVirtualArchiveComponent;
+import org.eclipse.m2e.wtp.overlay.internal.modulecore.OverlayVirtualComponent;
+
+/**
+ * Overlay Component factory.
+ * 
+ * @author Fred Bricon
+ */
+public class OverlayComponentCore {
+	
+	public static IOverlayVirtualComponent createOverlayComponent(IProject aProject) {
+		return new OverlayVirtualComponent(aProject);
+	}
+
+	//TODO check and prevent circular references
+	public static IOverlayVirtualComponent createSelfOverlayComponent(IProject aProject) {
+		return new OverlaySelfComponent(aProject);
+	}
+
+	public static IOverlayVirtualComponent createOverlayArchiveComponent(IProject aComponentProject, String archiveLocation, IPath unpackDirPath, IPath aRuntimePath) throws CoreException {
+		final OverlayVirtualArchiveComponent component = new OverlayVirtualArchiveComponent(aComponentProject, archiveLocation, unpackDirPath, aRuntimePath);
+		return component;
+	}
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/OverlayReferenceResolver.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/OverlayReferenceResolver.java
new file mode 100644
index 0000000..76bf620
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/OverlayReferenceResolver.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.overlay.modulecore;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.m2e.wtp.overlay.internal.Messages;
+import org.eclipse.m2e.wtp.overlay.internal.modulecore.OverlaySelfComponent;
+import org.eclipse.m2e.wtp.overlay.internal.modulecore.OverlayVirtualArchiveComponent;
+import org.eclipse.m2e.wtp.overlay.internal.modulecore.OverlayVirtualComponent;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.internal.ComponentcorePackage;
+import org.eclipse.wst.common.componentcore.internal.DependencyType;
+import org.eclipse.wst.common.componentcore.internal.ReferencedComponent;
+import org.eclipse.wst.common.componentcore.resolvers.IReferenceResolver;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+
+/**
+ * Overlay Reference Resolver
+ *
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+public class OverlayReferenceResolver implements IReferenceResolver {
+
+  public static final String PROTOCOL = "module:/overlay/"; //$NON-NLS-1$
+  
+  public static final String PROJECT_PROTOCOL = PROTOCOL+"prj/"; //$NON-NLS-1$
+
+  public static final String VAR_ARCHIVE_PROTOCOL = PROTOCOL+"var/"; //$NON-NLS-1$
+
+  public static final String SELF_PROTOCOL = PROTOCOL+"slf/"; //$NON-NLS-1$
+
+  private static final String UNPACK_FOLDER = "unpackFolder"; //$NON-NLS-1$
+  
+  private static final String INCLUDES = "includes"; //$NON-NLS-1$
+
+  private static final String EXCLUDES = "excludes"; //$NON-NLS-1$
+
+  @Override
+public boolean canResolve(IVirtualComponent component, ReferencedComponent referencedComponent) {
+    URI uri = referencedComponent.getHandle();
+    return uri != null && (uri.segmentCount() > 2) && (uri.segment(0).equals("overlay")); //$NON-NLS-1$
+  }
+
+  @Override
+public IVirtualReference resolve(IVirtualComponent component, ReferencedComponent referencedComponent) {
+	String type = referencedComponent.getHandle().segment(1); 
+    IOverlayVirtualComponent comp = null;
+	String url = referencedComponent.getHandle().toString();
+	Map<String, String> parameters = ModuleURIUtil.parseUri(url);
+	
+	String moduleName = ModuleURIUtil.extractModuleName(url);
+	if (moduleName == null || moduleName.trim().length() == 0) {
+		throw new IllegalArgumentException(NLS.bind(Messages.OverlayReferenceResolver_Module_Name_Cant_Be_Inferred,url));
+	}
+	
+	if ("prj".equals(type)) { //$NON-NLS-1$
+		comp = createProjectComponent(component, moduleName.substring(PROJECT_PROTOCOL.length()));
+	} else if ("var".equals(type)) { //$NON-NLS-1$
+		String unpackFolder = parameters.get(UNPACK_FOLDER);
+		if (unpackFolder == null || unpackFolder.trim().length() == 0) {
+			throw new IllegalArgumentException(NLS.bind(Messages.OverlayReferenceResolver_Missing_Parameter, url, UNPACK_FOLDER));
+		}
+		comp = createArchivecomponent(component, 
+									  moduleName.substring(PROTOCOL.length()), 
+									  unpackFolder, 
+									  referencedComponent.getRuntimePath());
+		
+	} else if ("slf".equals(type)){ //$NON-NLS-1$
+		comp = createSelfComponent(component);
+	}
+	if (comp == null) {
+		throw new IllegalArgumentException(NLS.bind(Messages.OverlayReferenceResolver_Unresolveable,referencedComponent.getHandle()));
+	}
+	
+	comp.setInclusions(getPatternSet(parameters.get(INCLUDES)));
+	comp.setExclusions(getPatternSet(parameters.get(EXCLUDES)));
+
+	IVirtualReference ref = ComponentCore.createReference(component, comp);
+    ref.setArchiveName(referencedComponent.getArchiveName());
+    ref.setRuntimePath(referencedComponent.getRuntimePath());
+    ref.setDependencyType(referencedComponent.getDependencyType().getValue());
+    return ref;
+  }
+
+  private Set<String> getPatternSet(String patterns) {
+	if (patterns == null || patterns.trim().length() == 0) {
+		return Collections.emptySet();
+	}
+	Set<String> patternSet = new LinkedHashSet<>();
+	for (String pattern : patterns.split(";")) { //$NON-NLS-1$
+		patternSet.add(pattern);
+	}
+	return patternSet;
+  }
+
+  private IOverlayVirtualComponent createSelfComponent(IVirtualComponent component) {
+	  return new OverlaySelfComponent(component.getProject());
+  }
+
+  private IOverlayVirtualComponent createArchivecomponent(IVirtualComponent component, String url, String targetPath, IPath runtimePath) {
+  	return new OverlayVirtualArchiveComponent(component.getProject(), 
+  			url, 
+  			component.getProject().getFolder(targetPath).getProjectRelativePath(), 
+  			runtimePath);
+  }
+
+  private IOverlayVirtualComponent createProjectComponent(IVirtualComponent component, String name) {
+    IProject p = null;   
+	if("".equals(name)) { //$NON-NLS-1$
+      p = component.getProject();
+    } else {
+      p = ResourcesPlugin.getWorkspace().getRoot().getProject(name);    	
+    }
+	if (p == null) {
+		throw new IllegalArgumentException(NLS.bind(Messages.OverlayReferenceResolver_Not_Workspace_Project, name));
+	}
+	return new OverlayVirtualComponent(p);
+  }
+
+  @Override
+public boolean canResolve(IVirtualReference reference) {
+    return  reference != null && reference.getReferencedComponent() instanceof IOverlayVirtualComponent;
+  }
+
+  @Override
+public ReferencedComponent resolve(IVirtualReference reference) {
+    if(canResolve(reference)) {
+      IOverlayVirtualComponent comp = (IOverlayVirtualComponent)reference.getReferencedComponent();
+      ReferencedComponent rc = ComponentcorePackage.eINSTANCE.getComponentcoreFactory().createReferencedComponent();
+      rc.setArchiveName(reference.getArchiveName());
+      rc.setRuntimePath(reference.getRuntimePath());
+      URI handle;
+      Map<String, String> parameters = new LinkedHashMap<>(3);
+      if (comp instanceof OverlayVirtualArchiveComponent) {
+    	  OverlayVirtualArchiveComponent archivecomp = (OverlayVirtualArchiveComponent) comp;
+    	  handle = URI.createURI(VAR_ARCHIVE_PROTOCOL+archivecomp.getArchivePath().toPortableString());
+    	  parameters.put(UNPACK_FOLDER, archivecomp.getUnpackFolderPath().toPortableString());
+      } else {
+    	  IProject p = comp.getProject();
+    	  if (p.equals(reference.getEnclosingComponent().getProject())) {
+        	  handle = URI.createURI(SELF_PROTOCOL);
+    	  } else {
+        	  handle = URI.createURI(PROJECT_PROTOCOL+p.getName());
+    	  }
+      }
+      parameters.put(INCLUDES, flatten(comp.getInclusions()));
+      parameters.put(EXCLUDES, flatten(comp.getExclusions()));
+      handle = URI.createURI(ModuleURIUtil.appendToUri(handle.toString(), parameters));
+	  rc.setHandle(handle); 
+      rc.setDependencyType(DependencyType.CONSUMES_LITERAL);
+      return rc;
+    }
+    return null;
+  }
+
+	private String flatten(Set<String> patterns) {
+		StringBuilder sb = new StringBuilder();
+		if (patterns != null) {
+			boolean initialized = false;
+			for(String pattern : patterns) {
+				if (initialized) {
+					sb.append(";"); //$NON-NLS-1$
+				} else {
+					initialized = true;
+				}
+				sb.append(pattern);
+			}
+		}
+		return sb.toString();
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/UnpackArchiveJob.java b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/UnpackArchiveJob.java
new file mode 100644
index 0000000..9caab11
--- /dev/null
+++ b/org.eclipse.m2e.wtp.overlay/src/org/eclipse/m2e/wtp/overlay/modulecore/UnpackArchiveJob.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.overlay.modulecore;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.m2e.wtp.overlay.internal.Messages;
+import org.eclipse.m2e.wtp.overlay.internal.OverlayPluginActivator;
+import org.eclipse.m2e.wtp.overlay.internal.utilities.CompressionUtil;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Job unpacking a {@link File} to a destination {@link IFolder}.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ *
+ */
+public class UnpackArchiveJob extends WorkspaceJob {
+
+	private IFolder unpackFolder;
+	private File archive;
+
+	public UnpackArchiveJob(String name, File archive, IFolder unpackFolder) {
+		super(name);
+		assert unpackFolder != null;
+		assert archive != null && archive.exists() && archive.canRead();
+		this.unpackFolder = unpackFolder;
+		this.archive = archive;
+		setRule(unpackFolder);
+	}
+	
+	@Override
+	public boolean belongsTo(Object family) {
+		return unpackFolder.equals(family);
+	}
+
+	@Override
+	public IStatus runInWorkspace(IProgressMonitor monitor)
+			throws CoreException {
+		try {
+			if (unpackFolder.exists()) {
+	      		//delete members as deleting unpackFolder will use scheduling rule of its parent, so an IllegalArgumentException would be thrown otherwise
+				final IResource[] members = unpackFolder.members(IContainer.INCLUDE_HIDDEN | IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS);
+				for (final IResource member : members)
+				{
+					if (monitor.isCanceled()) {
+						return new Status(IStatus.ERROR, OverlayPluginActivator.PLUGIN_ID, NLS.bind(Messages.UnpackArchiveJob_Deleteing_was_cancelled, member.getName()));
+					}
+					member.delete(true, monitor);
+				}
+			}
+			unpack(archive, unpackFolder.getLocation().toOSString(), monitor);
+		} catch (IOException e) {
+			return new Status(IStatus.ERROR, OverlayPluginActivator.PLUGIN_ID, NLS.bind(Messages.UnpackArchiveJob_Error_Unpacking, archive.getName()), e);
+		} catch (InterruptedException e) {
+			return new Status(IStatus.ERROR, OverlayPluginActivator.PLUGIN_ID, NLS.bind(Messages.UnpackArchiveJob_Unpacking_Interrupted, archive.getName()) , e);
+		}
+		
+		//will run in scheduling rule of parent of unpackfolder, so should be run in a different job
+		new WorkspaceJob(NLS.bind(Messages.UnpackArchiveJob_Refreshing, unpackFolder.getLocation().toString())) {
+
+			@Override
+			public IStatus runInWorkspace(final IProgressMonitor monitor) throws CoreException
+			{
+				if (!monitor.isCanceled()) {
+					unpackFolder.refreshLocal(IFolder.DEPTH_INFINITE, monitor);
+				}
+				return Status.OK_STATUS;
+			}
+		}.schedule();
+
+		return Status.OK_STATUS;
+	}
+
+	protected void unpack(File archive, String unpackFolderPath, IProgressMonitor monitor) throws IOException, CoreException,
+			InterruptedException {
+		File unpackFolder = new File(unpackFolderPath);
+		CompressionUtil.unzip(archive, unpackFolder, monitor);
+		unpackFolder.setLastModified(archive.lastModified());
+	}
+}
diff --git a/org.eclipse.m2e.wtp.sdk.feature/.gitignore b/org.eclipse.m2e.wtp.sdk.feature/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/org.eclipse.m2e.wtp.sdk.feature/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/org.eclipse.m2e.wtp.sdk.feature/.project b/org.eclipse.m2e.wtp.sdk.feature/.project
new file mode 100644
index 0000000..4b92c20
--- /dev/null
+++ b/org.eclipse.m2e.wtp.sdk.feature/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp.sdk.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp.sdk.feature/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.sdk.feature/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.sdk.feature/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.sdk.feature/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.sdk.feature/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/org.eclipse.m2e.wtp.sdk.feature/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.sdk.feature/build.properties b/org.eclipse.m2e.wtp.sdk.feature/build.properties
new file mode 100644
index 0000000..6069b2b
--- /dev/null
+++ b/org.eclipse.m2e.wtp.sdk.feature/build.properties
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2012-2014 Red Hat, Inc.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#      Red Hat, Inc. - initial API and implementation
+#
+
+bin.includes = feature.xml,\
+               feature.properties
diff --git a/org.eclipse.m2e.wtp.sdk.feature/feature.properties b/org.eclipse.m2e.wtp.sdk.feature/feature.properties
new file mode 100644
index 0000000..78131a9
--- /dev/null
+++ b/org.eclipse.m2e.wtp.sdk.feature/feature.properties
@@ -0,0 +1,39 @@
+###############################################################################
+# Copyright (c) 2012 Red Hat, Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     Red Hat, Inc. - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=m2e-wtp - Maven Integration for WTP Developer Resources
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org - m2e-wtp
+
+# "updateSiteName" property - label for the update site
+#updateSiteName=The Eclipse Project Updates
+
+# "description" property - description of the feature
+description=Source code archives (SDK) for m2e-wtp core 
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2012-2014 Red Hat, Inc.\n\
+All rights reserved. This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License v1.0\n\
+which accompanies this distribution, and is available at\n\
+http://www.eclipse.org/legal/epl-v10.html\n\
+\n\
+Contributors:\n\
+     Red Hat, Inc. - initial API and implementation\n
+################ end of copyright property ####################################
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp.sdk.feature/feature.xml b/org.eclipse.m2e.wtp.sdk.feature/feature.xml
new file mode 100644
index 0000000..4e12d01
--- /dev/null
+++ b/org.eclipse.m2e.wtp.sdk.feature/feature.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.m2e.wtp.sdk.feature"
+      label="%featureName"
+      version="1.3.0.qualifier"
+      provider-name="%providerName"
+      license-feature="org.eclipse.license"
+      license-feature-version="0.0.0">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <includes
+         id="org.eclipse.m2e.wtp.feature"
+         version="0.0.0"/>
+
+   <plugin
+         id="org.eclipse.m2e.wtp.source"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.m2e.wtp.overlay.source"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.m2e.wtp.overlay.ui.source"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/org.eclipse.m2e.wtp.sdk.feature/pom.xml b/org.eclipse.m2e.wtp.sdk.feature/pom.xml
new file mode 100644
index 0000000..09fc7c8
--- /dev/null
+++ b/org.eclipse.m2e.wtp.sdk.feature/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2008 Sonatype, Inc.
+  All rights reserved. This program and the accompanying materials
+  are made available under the terms of the Eclipse Public License v1.0
+  which accompanies this distribution, and is available at
+  http://www.eclipse.org/legal/epl-v10.html
+-->
+<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>
+    <groupId>org.eclipse.m2e.wtp</groupId>
+    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.m2e.wtp.sdk.feature</artifactId>
+  <packaging>eclipse-feature</packaging>
+
+  <name>M2E-WTP :: Core SDK Feature (Optional)</name>
+
+</project>
diff --git a/org.eclipse.m2e.wtp.jpa.site/.gitignore b/org.eclipse.m2e.wtp.site/.gitignore
similarity index 100%
rename from org.eclipse.m2e.wtp.jpa.site/.gitignore
rename to org.eclipse.m2e.wtp.site/.gitignore
diff --git a/org.eclipse.m2e.wtp.site/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.site/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp.site/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.site/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.site/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..5492efb
--- /dev/null
+++ b/org.eclipse.m2e.wtp.site/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,5 @@
+#Fri Jul 15 14:36:05 CEST 2011
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.site/category.xml b/org.eclipse.m2e.wtp.site/category.xml
new file mode 100644
index 0000000..5f4c342
--- /dev/null
+++ b/org.eclipse.m2e.wtp.site/category.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <description name="Maven Integration for WTP">
+      m2e-wtp - Maven Integration for WTP
+   </description>
+   <category name="m2e-wtp"/>
+
+   <feature url="features/org.eclipse.m2e.wtp.feature_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.feature" version="0.0.0">
+      <category name="m2e-wtp"/>
+   </feature>
+   <feature url="features/org.eclipse.m2e.wtp.jaxrs.feature_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.jaxrs.feature" version="0.0.0">
+      <category name="m2e-wtp"/>
+   </feature>
+   <feature url="features/org.eclipse.m2e.wtp.jsf.feature_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.jsf.feature" version="0.0.0">
+      <category name="m2e-wtp"/>
+   </feature>
+   <feature url="features/org.eclipse.m2e.wtp.jpa.feature_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.jpa.feature" version="0.0.0">
+      <category name="m2e-wtp"/>
+   </feature>
+   <category-def name="m2e-wtp" label="Maven Integration for WTP"/>
+
+   <category name="maven-archiver"/>
+
+   <feature url="features/org.sonatype.m2e.mavenarchiver.feature_0.0.0.qualifier.jar" id="org.sonatype.m2e.mavenarchiver.feature" version="0.0.0">
+      <category name="maven-archiver"/>
+   </feature>
+
+   <category-def name="maven-archiver" label="M2E Maven Archiver Connector (3rd party)"/>
+
+   <category name="m2e-wtp-sdk"/>
+
+   <feature url="features/org.eclipse.m2e.wtp.sdk.feature_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.sdk.feature" version="0.0.0">
+      <category name="m2e-wtp-sdk"/>
+   </feature>
+   <feature url="features/org.eclipse.m2e.wtp.jsf.feature.source_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.jsf.feature.source" version="0.0.0">
+      <category name="m2e-wtp-sdk"/>
+   </feature>
+   <feature url="features/org.eclipse.m2e.wtp.jaxrs.feature.source_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.jaxrs.feature.source" version="0.0.0">
+      <category name="m2e-wtp-sdk"/>
+   </feature>
+   <feature url="features/org.eclipse.m2e.wtp.jpa.feature.source_0.0.0.qualifier.jar" id="org.eclipse.m2e.wtp.jpa.feature.source" version="0.0.0">
+      <category name="m2e-wtp-sdk"/>
+   </feature>
+   <category-def name="m2e-wtp-sdk" label="Maven Integration for WTP - SDK"/>
+
+
+</site>
diff --git a/org.eclipse.m2e.wtp.jpa.site/index.html b/org.eclipse.m2e.wtp.site/index.html
similarity index 97%
rename from org.eclipse.m2e.wtp.jpa.site/index.html
rename to org.eclipse.m2e.wtp.site/index.html
index 05a8dba..110e3ab 100644
--- a/org.eclipse.m2e.wtp.jpa.site/index.html
+++ b/org.eclipse.m2e.wtp.site/index.html
@@ -1,6 +1,6 @@
 <html>
 <head>
-<title>org.eclipse.m2e.wtp.jpa.site</title>
+<title>org.eclipse.m2e.wtp.site</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <style>@import url("web/site.css");</style>
 <script type="text/javascript">
diff --git a/org.eclipse.m2e.wtp.jpa.site/pom.xml b/org.eclipse.m2e.wtp.site/pom.xml
similarity index 83%
rename from org.eclipse.m2e.wtp.jpa.site/pom.xml
rename to org.eclipse.m2e.wtp.site/pom.xml
index 0f0dd91..4bbb61b 100644
--- a/org.eclipse.m2e.wtp.jpa.site/pom.xml
+++ b/org.eclipse.m2e.wtp.site/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  Copyright (c) 2008 Sonatype, Inc.
+  Copyright (c) 2008-2014 Sonatype, Inc. and others.
   All rights reserved. This program and the accompanying materials
   are made available under the terms of the Eclipse Public License v1.0
   which accompanies this distribution, and is available at
@@ -11,14 +11,14 @@
 
   <parent>
     <groupId>org.eclipse.m2e.wtp</groupId>
-    <artifactId>org.eclipse.m2e.wtp.jpa.parent</artifactId>
+    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
     <version>1.3.0-SNAPSHOT</version>
   </parent>
 
-  <artifactId>org.eclipse.m2e.wtp.jpa.site</artifactId>
+  <artifactId>org.eclipse.m2e.wtp.site</artifactId>
   <packaging>eclipse-repository</packaging>
 
-  <name>M2E-WTP :: JPA Support Update Site</name>
+  <name>M2E-WTP :: Update Site</name>
 
   <build>
     <plugins>
diff --git a/org.eclipse.m2e.wtp.jpa.site/web/site.css b/org.eclipse.m2e.wtp.site/web/site.css
similarity index 100%
rename from org.eclipse.m2e.wtp.jpa.site/web/site.css
rename to org.eclipse.m2e.wtp.site/web/site.css
diff --git a/org.eclipse.m2e.wtp.jpa.site/web/site.xsl b/org.eclipse.m2e.wtp.site/web/site.xsl
similarity index 98%
rename from org.eclipse.m2e.wtp.jpa.site/web/site.xsl
rename to org.eclipse.m2e.wtp.site/web/site.xsl
index a319764..9fdaa3a 100644
--- a/org.eclipse.m2e.wtp.jpa.site/web/site.xsl
+++ b/org.eclipse.m2e.wtp.site/web/site.xsl
@@ -5,11 +5,11 @@
 <xsl:for-each select="site">
 	<html>
 	<head>
-	<title>org.eclipse.m2e.wtp.jpa.site</title>
+	<title>org.eclipse.m2e.wtp.site</title>
 	<style>@import url("web/site.css");</style>
 	</head>
 	<body>
-	<h1 class="title">org.eclipse.m2e.wtp.jpa.site</h1>
+	<h1 class="title">org.eclipse.m2e.wtp.site</h1>
 	<p class="bodyText"><xsl:value-of select="description"/></p>
 	<table width="100%" border="0" cellspacing="1" cellpadding="2">
 	<xsl:for-each select="category-def">
diff --git a/org.eclipse.m2e.wtp.target-platform/.gitignore b/org.eclipse.m2e.wtp.target-platform/.gitignore
new file mode 100644
index 0000000..4dc0091
--- /dev/null
+++ b/org.eclipse.m2e.wtp.target-platform/.gitignore
@@ -0,0 +1,2 @@
+/target
+/bin
diff --git a/org.eclipse.m2e.wtp.target-platform/.project b/org.eclipse.m2e.wtp.target-platform/.project
new file mode 100644
index 0000000..cb73ba5
--- /dev/null
+++ b/org.eclipse.m2e.wtp.target-platform/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp.target-platform</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp.target-platform/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp.target-platform/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..15c43a1
--- /dev/null
+++ b/org.eclipse.m2e.wtp.target-platform/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Tue Sep 27 17:26:51 CEST 2011
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp.target-platform/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp.target-platform/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..c9fb79c
--- /dev/null
+++ b/org.eclipse.m2e.wtp.target-platform/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,5 @@
+#Wed Apr 06 19:19:46 CEST 2011
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp.target-platform/.settings/org.maven.ide.eclipse.prefs b/org.eclipse.m2e.wtp.target-platform/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 0000000..80f63e7
--- /dev/null
+++ b/org.eclipse.m2e.wtp.target-platform/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,9 @@
+#Mon Aug 02 18:56:49 CEST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/org.eclipse.m2e.wtp.target-platform/m2e-wtp-e36.target b/org.eclipse.m2e.wtp.target-platform/m2e-wtp-e36.target
new file mode 100644
index 0000000..dbc81ef
--- /dev/null
+++ b/org.eclipse.m2e.wtp.target-platform/m2e-wtp-e36.target
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde version="3.6"?>
+
+<target name="m2e-wtp-e36" sequenceNumber="3">
+<locations>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.sdk.ide" version="3.6.2.M20110210-1200"/>
+<unit id="org.eclipse.emf.common.feature.group" version="2.6.0.v20100914-1218"/>
+<unit id="org.eclipse.wst.common.emf" version="1.2.3.v201012100400"/>
+<unit id="org.eclipse.wst.sse.core" version="1.1.504.v201102160550"/>
+<unit id="org.eclipse.wst.xml.core" version="1.1.503.v201102102045"/>
+<unit id="org.eclipse.wst.sse.ui" version="1.2.3.v201102102045"/>
+<unit id="org.eclipse.emf.ecore.edit.feature.group" version="2.6.0.v20100914-1218"/>
+<unit id="org.eclipse.emf.edit.ui.feature.group" version="2.6.0.v20100914-1218"/>
+<unit id="org.eclipse.wst.xsd.core" version="1.1.503.v201011121919"/>
+<unit id="org.eclipse.epp.usagedata.feature.feature.group" version="1.3.1.R201102081640"/>
+<unit id="org.eclipse.equinox.p2.sdk.feature.group" version="3.6.2.R36x_v20110120-9I7VGEAG438GhnfSLuLz0FXP9NYJ"/>
+<unit id="org.eclipse.wst.common.fproj.feature.group" version="3.2.3.v201101121727-377AC8s73543C6H4A5H"/>
+<unit id="org.eclipse.jst.common.fproj.enablement.jdt.feature.group" version="3.2.2.v201008170019-377AB8s73533J5J759F"/>
+<unit id="org.eclipse.jst.enterprise_ui.feature.feature.group" version="3.2.3.v201011031800-7b7GHfIFSK2WBRT6E1mcyFXGPnSh"/>
+<unit id="org.eclipse.wst.web_ui.feature.feature.group" version="3.2.3.v201102160541-7O7CFbWEMf84qYjGDyP3DNEwcgFU"/>
+<unit id="org.eclipse.wst.xml_ui.feature.feature.group" version="3.2.3.v201102160550-7H7AFUWDxumQJOi9ghcTb5YgkwEZ"/>
+<unit id="org.eclipse.wst.xsl.feature.feature.group" version="1.1.3.v201102102045-7S7WFASFIpS-21NUD58xfPVDTLR"/>
+<unit id="org.eclipse.wst.jsdt.feature.feature.group" version="1.2.3.v201102160540-7C78FGUF9JgLWNO2UCNqfa"/>
+<unit id="org.eclipse.jsf.feature.feature.group" version="3.2.3.v201101112207-7E7I7BF9JgLWPMz0VyDEHH"/>
+<unit id="org.eclipse.jst.ws.jaxws.dom.feature.feature.group" version="1.0.0.v201005241530-5--AkF7B77NBZBgBg"/>
+<unit id="org.eclipse.jst.ws.jaxws.feature.feature.group" version="1.0.1.v201008232129-7E777CF8NcJSSK-UBTwXn"/>
+<unit id="org.eclipse.jst.server_adapters.ext.feature.feature.group" version="3.2.3.v20110111-777HFGSCcNBDjBdHV4BA8"/>
+<unit id="org.eclipse.jst.server_adapters.feature.feature.group" version="3.2.0.v201005241530-208Z7w31211419"/>
+<unit id="org.eclipse.jst.server_ui.feature.feature.group" version="3.2.2.v20100908-7A5FEi9xFc7RCJMToAIOJC43A"/>
+<unit id="org.eclipse.jst.web_ui.feature.feature.group" version="3.2.3.v201101262333-7F77FJ_C25TkfyypjhqQuxNYsMrJ"/>
+<unit id="org.eclipse.jst.webpageeditor.feature.feature.group" version="2.3.2.v201101112207-4619oB5865D8I2331"/>
+<unit id="org.eclipse.wst.server_adapters.feature.feature.group" version="3.2.0.v201005241510-51EoAkF77g8HBSc"/>
+<repository location="http://download.eclipse.org/releases/helios"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.swtbot.eclipse.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.eclipse.gef.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.ide.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.eclipse.test.junit3.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.eclipse.test.junit4.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.forms.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<repository location="http://download.eclipse.org/technology/swtbot/helios/dev-build/update-site/"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="ch.qos.logback.core" version="1.0.0.v20111214-2030"/>
+<unit id="org.slf4j.api" version="1.6.4.v20120130-2120"/>
+<unit id="org.apache.commons.io" version="2.0.1.v201105210651" />
+<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20120308061416/repository/"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.m2e.sdk.feature.feature.group" version="1.1.0.20120315-1002"/>
+<unit id="org.eclipse.m2e.feature.feature.group" version="1.1.0.20120315-1002"/>
+<unit id="org.eclipse.m2e.logback.feature.feature.group" version="1.1.0.20120315-1002"/>
+<repository location="https://repository.sonatype.org/content/sites/forge-sites/m2e/1.1.0/N/1.1.0.20120315-1002/"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature.group" version="3.2.2.v201008170019-777DBo9tKEKIGLHXGCHk6K86AG"/>
+<unit id="org.eclipse.wst.common.fproj.sdk.feature.group" version="3.2.3.v201101121727-787HDRApOGNMIOLdFKGq7I5B6I"/>
+<unit id="org.eclipse.wst.xml_sdk.feature.feature.group" version="3.2.3.v201102160550-7A5788DXHQZiYiLFP5QqwKhexZqF"/>
+<unit id="org.eclipse.jsf_sdk.feature.feature.group" version="3.2.3.v201101112207-773584JAMBEJDNlQZZP7HfHNSZTK"/>
+<unit id="org.eclipse.jst.enterprise_sdk.feature.feature.group" version="3.2.3.v201011031800-773584gAKKjMIYODZETckOL5KHY-"/>
+<unit id="org.eclipse.jst.server_adapters.ext.sdk.feature.feature.group" version="3.2.3.v20110111-773584CALJJWGgPLNtVv_z-Jq_ME"/>
+<unit id="org.eclipse.jst.server_adapters.sdk.feature.feature.group" version="3.2.2.v20100908-773-8-5BcAz-B6959A4B319_8x42"/>
+<unit id="org.eclipse.jst.server_sdk.feature.feature.group" version="3.2.2.v20100909-773384F8JHlLz0QeHdKadD-8a1Tf"/>
+<unit id="org.eclipse.jst.web_sdk.feature.feature.group" version="3.2.3.v201102090654-7B777899ZHQb_ipXUyXLSEW4URSo"/>
+<unit id="org.eclipse.jst.webpageeditor_sdk.feature.feature.group" version="2.3.2.v201101112207-55381B4DsE9CAAIBS4AC5ApC6976"/>
+<unit id="org.eclipse.wst.server_adapters.sdk.feature.feature.group" version="3.2.0.v201005241510-773-826HsDnNCEkGLEUk2FpBlG88"/>
+<unit id="org.eclipse.wst.web_sdk.feature.feature.group" version="3.2.3.v201102160541-7E797E8SxYiH8uYBmdHB0hOFSy2c"/>
+<unit id="org.eclipse.wst.xsl_sdk.feature.feature.group" version="1.1.3.v201101212242-528k98jYhYxz-WdHiZXZlQj3R98g"/>
+<repository location="http://download.eclipse.org/webtools/repository/helios/"/>
+</location>
+
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.sonatype.m2e.mavenarchiver.feature.feature.group" version="0.15.0.201202141716"/>
+<repository location="https://repository.sonatype.org/content/sites/forge-sites/m2e-extras/0.15.0/N/0.15.0.201202141716/"/>
+</location>
+
+<!--location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.sonatype.m2e.antlr.feature.feature.group" version="0.13.0.20110622-1538"/>
+<unit id="org.sonatype.m2e.buildhelper.feature.feature.group" version="0.13.0.20110622-1538"/>
+<unit id="org.sonatype.m2e.mavenarchiver.pomproperties.feature.feature.group" version="0.13.0.20110622-1538"/>
+<unit id="org.sonatype.m2e.modello.feature.feature.group" version="0.13.0.20110622-1538"/>
+<unit id="org.sonatype.m2e.plexus.annotations.feature.feature.group" version="0.13.0.20110622-1538"/>
+<repository location="https://repository.sonatype.org/content/sites/forge-sites/m2e-extras/0.13.0/S/0.13.0.20110622-1538/"/>
+</location-->
+</locations>
+</target>
diff --git a/org.eclipse.m2e.wtp.target-platform/m2e-wtp-e371.target b/org.eclipse.m2e.wtp.target-platform/m2e-wtp-e371.target
new file mode 100644
index 0000000..04e3556
--- /dev/null
+++ b/org.eclipse.m2e.wtp.target-platform/m2e-wtp-e371.target
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde version="3.6"?>
+
+<target name="m2e-wtp-e371" sequenceNumber="29">
+<locations>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="ch.qos.logback.core" version="1.0.0.v20111214-2030"/>
+<unit id="org.slf4j.api" version="1.6.4.v20120130-2120"/>
+<unit id="org.apache.commons.io" version="2.0.1.v201105210651" />
+<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20120308061416/repository/"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.platform.sdk" version="3.7.1.M20110909-1335"/>
+<repository location="http://download.eclipse.org/eclipse/updates/3.7"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.m2e.sdk.feature.feature.group" version="1.1.0.20120315-1002"/>
+<unit id="org.eclipse.m2e.feature.feature.group" version="1.1.0.20120315-1002"/>
+<unit id="org.eclipse.m2e.logback.feature.feature.group" version="1.1.0.20120315-1002"/>
+<repository location="https://repository.sonatype.org/content/sites/forge-sites/m2e/1.1.0/N/1.1.0.20120315-1002/"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.sonatype.m2e.mavenarchiver.feature.feature.group" version="0.15.0.201202141716"/>
+<repository location="https://repository.sonatype.org/content/sites/forge-sites/m2e-extras/0.15.0/N/0.15.0.201202141716/"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.wst.common.fproj.feature.group" version="3.3.0.v201102150115-377DF8s7355397B4B9B"/>
+<unit id="org.eclipse.jst.common.fproj.enablement.jdt.feature.group" version="3.3.0.v201102200555-377DF8s73543E5I5768"/>
+<unit id="org.eclipse.jst.enterprise_ui.feature.feature.group" version="3.3.1.v201107072200-7b7II1PFSK2WIlPwJBmNz-VWwVsTn"/>
+<unit id="org.eclipse.jst.web_ui.feature.feature.group" version="3.3.1.v201108102009-7F7AFO3C25TohHcojh0Zyz-B7FyifIcGz-xuz-_W"/>
+<unit id="org.eclipse.wst.web_ui.feature.feature.group" version="3.3.1.v201107072200-7O7IFhREMiB5vNoYqf01XHTvUndyz-yx-9kUyXXL"/>
+<unit id="org.eclipse.jst.server_adapters.feature.feature.group" version="3.2.100.v20110303-208Z7w31211419"/>
+<unit id="org.eclipse.jst.server_adapters.ext.feature.feature.group" version="3.3.1.v20110729_1216-777HFHyCcNBDjBfJa4BA8"/>
+<unit id="org.eclipse.wst.server_adapters.feature.feature.group" version="3.2.100.v20110303-51EoAkF77g8HBSc"/>
+<repository location="http://download.eclipse.org/webtools/repository/indigo/"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.swtbot.eclipse.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.eclipse.gef.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.ide.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.eclipse.test.junit3.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.eclipse.test.junit4.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.forms.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<unit id="org.eclipse.swtbot.feature.group" version="2.0.5.20111003_1754-3676ac8-dev-e36"/>
+<repository location="http://download.eclipse.org/technology/swtbot/helios/dev-build/update-site/"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.emf.common.feature.group" version="2.6.0.v20100914-1218"/>
+<unit id="org.eclipse.emf.edit.feature.group" version="2.6.0.v20100914-1218"/>
+<repository location="http://download.jboss.org/jbosstools/updates/requirements/emf/2.6/"/>
+</location>
+<location includeAllPlatforms="false" includeMode="planner" includeSource="true" type="InstallableUnit">
+<unit id="org.eclipse.draw2d.feature.group" version="3.7.1.v20110830-1143-4607w3122194102254"/>
+<unit id="org.eclipse.gef.feature.group" version="3.7.1.v20110830-1143-777D181B3Bz06C853D8863365"/>
+<repository location="http://download.eclipse.org/tools/gef/updates/releases"/>
+</location>
+</locations>
+</target>
diff --git a/org.eclipse.m2e.wtp.target-platform/pom.xml b/org.eclipse.m2e.wtp.target-platform/pom.xml
new file mode 100644
index 0000000..29ad285
--- /dev/null
+++ b/org.eclipse.m2e.wtp.target-platform/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+  <!--
+    Copyright (c) 2008 Sonatype, Inc. All rights reserved. This program
+    and the accompanying materials are made available under the terms of
+    the Eclipse Public License v1.0 which accompanies this distribution,
+    and is available at http://www.eclipse.org/legal/epl-v10.html
+  -->
+<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>
+    <groupId>org.eclipse.m2e.wtp</groupId>
+    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+    <version>0.16.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>org.eclipse.m2e.wtp.target-platform</artifactId>
+  <packaging>pom</packaging>
+
+  <name>M2E-WTP :: Target Platform</name>
+
+  <build>
+    <plugins>
+      <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>build-helper-maven-plugin</artifactId>
+          <version>1.3</version>
+          <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <phase>package</phase>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>m2e-wtp-e371.target</file>
+                  <type>target</type>
+                  <classifier>m2e-wtp-e371</classifier>
+                </artifact>		
+                <artifact>
+                  <file>m2e-wtp-e36.target</file>
+                  <type>target</type>
+                  <classifier>m2e-wtp-e36</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/org.eclipse.m2e.wtp/.classpath b/org.eclipse.m2e.wtp/.classpath
new file mode 100644
index 0000000..06011f6
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry exported="true" kind="lib" path="jars/maven-war-plugin-2.1.1.jar"/>
+	<classpathentry kind="src" path="src/"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/org.eclipse.m2e.wtp/.gitignore b/org.eclipse.m2e.wtp/.gitignore
new file mode 100644
index 0000000..4dc0091
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.gitignore
@@ -0,0 +1,2 @@
+/target
+/bin
diff --git a/org.eclipse.m2e.wtp/.project b/org.eclipse.m2e.wtp/.project
new file mode 100644
index 0000000..e78f80f
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.m2e.wtp</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.m2e.wtp/.settings/org.eclipse.core.resources.prefs b/org.eclipse.m2e.wtp/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.m2e.wtp/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.m2e.wtp/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d17b672
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/org.eclipse.m2e.wtp/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.m2e.wtp/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..9f6df4b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,10 @@
+#Fri Jul 29 18:15:57 CEST 2011
+eclipse.preferences.version=1
+formatter_profile=_m2 plugin
+formatter_settings_version=12
+org.eclipse.jdt.ui.exception.name=ex
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.javadoc=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=false
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return Returns the ${bare_field_name}.\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} The ${bare_field_name} to set.\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/*******************************************************************************&\#13;\n * Copyright (c) 2011 Red Hat, Inc.&\#13;\n * All rights reserved. This program and the accompanying materials&\#13;\n * are made available under the terms of the Eclipse Public License v1.0&\#13;\n * which accompanies this distribution, and is available at&\#13;\n * http\://www.eclipse.org/legal/epl-v10.html&\#13;\n *******************************************************************************/&\#13;\n</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * ${type_name}\n *\n * @author ${user}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="false" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\nlogger.error(${exception_var});</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method ${enclosing_method}\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created JavaScript files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for vars" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding function" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Jsdoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate functions" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created function stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated function stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.wst.jsdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
diff --git a/org.eclipse.m2e.wtp/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.m2e.wtp/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..08d14a1
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,5 @@
+#Wed Apr 06 19:19:49 CEST 2011
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.m2e.wtp/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.m2e.wtp/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000..fd2bc34
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Thu Aug 28 19:42:02 EDT 2008
+eclipse.preferences.version=1
+project.repository.kind=jira
+project.repository.url=http\://jira.codehaus.org
diff --git a/org.eclipse.m2e.wtp/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.m2e.wtp/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000..3671e85
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,3 @@
+#Thu Aug 28 19:42:02 EDT 2008
+commit.comment.template=${task.key}\: ${task.description}
+eclipse.preferences.version=1
diff --git a/org.eclipse.m2e.wtp/.settings/org.jboss.ide.eclipse.as.core.prefs b/org.eclipse.m2e.wtp/.settings/org.jboss.ide.eclipse.as.core.prefs
new file mode 100644
index 0000000..cf3aa3a
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.settings/org.jboss.ide.eclipse.as.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.jboss.ide.eclipse.as.core.singledeployable.deployableList=
diff --git a/org.eclipse.m2e.wtp/.settings/org.maven.ide.eclipse.prefs b/org.eclipse.m2e.wtp/.settings/org.maven.ide.eclipse.prefs
new file mode 100644
index 0000000..445a799
--- /dev/null
+++ b/org.eclipse.m2e.wtp/.settings/org.maven.ide.eclipse.prefs
@@ -0,0 +1,9 @@
+#Thu Feb 04 09:56:35 EST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/org.eclipse.m2e.wtp/META-INF/MANIFEST.MF b/org.eclipse.m2e.wtp/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..cc97e71
--- /dev/null
+++ b/org.eclipse.m2e.wtp/META-INF/MANIFEST.MF
@@ -0,0 +1,54 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Maven Integration for Eclipse WTP
+Bundle-SymbolicName: org.eclipse.m2e.wtp;singleton:=true
+Bundle-Version: 1.3.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.core.commands,
+ org.eclipse.jface,
+ org.eclipse.ui.navigator,
+ org.eclipse.ui.workbench,
+ org.eclipse.jdt.core,
+ org.eclipse.jst.j2ee.web,
+ org.eclipse.jst.common.project.facet.core,
+ org.eclipse.jst.common.frameworks,
+ org.eclipse.jst.j2ee,
+ org.eclipse.jst.j2ee.core,
+ org.eclipse.jst.j2ee.ejb,
+ org.eclipse.wst.common.frameworks,
+ org.eclipse.wst.common.modulecore;visibility:=reexport,
+ org.eclipse.wst.common.project.facet.core,
+ org.eclipse.m2e.maven.runtime;bundle-version="[1.6.0,2.0.0)",
+ org.eclipse.m2e.core;bundle-version="[1.6.0,2.0.0)",
+ org.eclipse.m2e.jdt;bundle-version="[1.6.0,2.0.0)",
+ org.eclipse.ui.console,
+ org.eclipse.emf.ecore,
+ org.eclipse.jem.util,
+ org.eclipse.wst.common.emfworkbench.integration,
+ org.eclipse.jst.jee,
+ org.eclipse.jst.j2ee.jca,
+ org.slf4j.api;bundle-version="1.5.11",
+ org.eclipse.ui.ide,
+ org.eclipse.m2e.wtp.overlay;visibility:=reexport,
+ org.eclipse.wst.server.core,
+ org.sonatype.m2e.mavenarchiver;bundle-version="0.17.0",
+ org.eclipse.jdt.launching,
+ org.eclipse.jst.jee.web,
+ org.eclipse.jst.jee.ejb,
+ org.eclipse.wst.validation
+Bundle-Vendor: Eclipse.org - m2e-wtp
+Export-Package: org.eclipse.m2e.wtp;x-friends:="org.eclipse.m2e.wtp.te
+ sts"; uses:="org.eclipse.core.runtime,  org.apache.maven.artifact.res
+ olver.filter,  org.codehaus.plexus.util.xml,  org.apache.maven.projec
+ t,  org.eclipse.jdt.core,  org.apache.maven.artifact,  org.apache.mav
+ en.model,  org.eclipse.core.resources,  org.eclipse.wst.common.projec
+ t.facet.core,  org.apache.maven.plugin",org.eclipse.m2e.wtp.facets,or
+ g.eclipse.m2e.wtp.internal;x-friends:="org.eclipse.m2e.wtp.tests",org
+ .eclipse.m2e.wtp.preferences
+Bundle-Activator: org.eclipse.m2e.wtp.MavenWtpPlugin
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Bundle-ClassPath: jars/maven-war-plugin-2.1.1.jar,
+ .
diff --git a/org.eclipse.m2e.wtp/NOTICE b/org.eclipse.m2e.wtp/NOTICE
new file mode 100644
index 0000000..b077840
--- /dev/null
+++ b/org.eclipse.m2e.wtp/NOTICE
@@ -0,0 +1,6 @@
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Maven WAR Plugin
+Copyright 2002-2010 The Apache Software Foundation
+
diff --git a/org.eclipse.m2e.wtp/about.html b/org.eclipse.m2e.wtp/about.html
new file mode 100644
index 0000000..99de9d4
--- /dev/null
+++ b/org.eclipse.m2e.wtp/about.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>October 29, 2010</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+
+<h3>Third Party Content</h3>
+
+<p>
+The Content includes items that have been sourced from third parties as set out below. If you 
+did not receive this Content directly from the Eclipse Foundation, the following is provided 
+for informational purposes only, and you should look to the Redistributor&rsquo;s license for 
+terms and conditions of use.
+</p>
+
+<h4>maven-war-plugin 2.1.1</h4>
+<p>
+This software contains the maven-war-plugin-2.1.1.jar from the Apache Maven project.</p>
+<p>
+Your use of maven-war-plugin in source or binary code form is subject to the terms and conditions of the 
+The Apache Software License, Version 2.0 (&quot;ASL&quot;).  
+A copy of the ASL is available at <a href="http://maven.apache.org/license.html">http://maven.apache.org/license.html</a>.
+(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>)
+</p>
+
+<h4>maven-ear-plugin 2.6 (Derivative work)</h4>
+<p>
+This software contains the following classes, derived from the maven-ear-plugin-2.6.jar from the Apache Maven project.
+ <ul>
+<li>org.eclipse.m2e.wtp.earmodules.AbstractEarModule derived from  org.apache.maven.plugin.ear.AbstractEarModule 
+</li><li>org.eclipse.m2e.wtp.namemapping.StandardFileNameMapping derived from org.apache.maven.plugin.ear.output.StandardFileNameMapping 
+</li><li>org.eclipse.m2e.wtp.earmodules.AppClientModule derived from org.apache.maven.plugin.ear.AppClientModule
+</li><li>org.eclipse.m2e.wtp.earmodules.ArtifactRepository derived from org.apache.maven.plugin.ear.util.ArtifactRepository
+</li><li>org.eclipse.m2e.wtp.earmodules.ArtifactTypeMappingService derived from org.apache.maven.plugin.ear.util.ArtifactTypeMappingService
+</li><li>org.eclipse.m2e.wtp.earmodules.EarModule derived from org.apache.maven.plugin.ear.EarModule
+</li><li>org.eclipse.m2e.wtp.earmodules.EarModuleFactory derived from org.apache.maven.plugin.ear.EarModuleFactory
+</li><li>org.eclipse.m2e.wtp.earmodules.EarPluginException derived from org.apache.maven.plugin.ear.EarPluginException
+</li><li>org.eclipse.m2e.wtp.earmodules.EjbClientModule derived from org.apache.maven.plugin.ear.EjbClientModule
+</li><li>org.eclipse.m2e.wtp.earmodules.EjbModule derived from org.apache.maven.plugin.ear.EjbModule
+</li><li>org.eclipse.m2e.wtp.earmodules.HarModule derived from org.apache.maven.plugin.ear.HarModule
+</li><li>org.eclipse.m2e.wtp.earmodules.JarModule derived from org.apache.maven.plugin.ear.JarModule
+</li><li>org.eclipse.m2e.wtp.earmodules.JbossEarModule derived from org.apache.maven.plugin.ear.JbossEarModule 
+</li><li>org.eclipse.m2e.wtp.earmodules.ParModule derived from org.apache.maven.plugin.ear.ParModule
+</li><li>org.eclipse.m2e.wtp.earmodules.RarModule derived from org.apache.maven.plugin.ear.RarModule
+</li><li>org.eclipse.m2e.wtp.earmodules.SarModule derived from org.apache.maven.plugin.ear.SarModule
+</li><li>org.eclipse.m2e.wtp.earmodules.SecurityRoleKey derived from  org.apache.maven.plugin.ear.SecurityRole
+</li><li>org.eclipse.m2e.wtp.earmodules.UnknownArtifactTypeException derived from org.apache.maven.plugin.ear.UnknownArtifactTypeException
+</li><li>org.eclipse.m2e.wtp.earmodules.WebModule derived from  org.apache.maven.plugin.ear.WebModule
+</li><li>org.eclipse.m2e.wtp.earmodules.WsrModule derived from  org.apache.maven.plugin.ear.WsrModule
+</li><li>org.eclipse.m2e.wtp.namemapping.AbstractFileNameMapping derived from  org.apache.maven.plugin.ear.output.AbstractFileNameMapping 
+</li><li>org.eclipse.m2e.wtp.namemapping.FileNameMapping derived from org.apache.maven.plugin.ear.output.FileNameMapping 
+</li><li>org.eclipse.m2e.wtp.namemapping.FileNameMappingFactory derived from  org.apache.maven.plugin.ear.output.FileNameMapping 
+</li><li>org.eclipse.m2e.wtp.namemapping.FullFileNameMapping derived from org.apache.maven.plugin.ear.output.FullFileNameMapping 
+</li><li>org.eclipse.m2e.wtp.namemapping.NoVersionFileNameMapping derived from org.apache.maven.plugin.ear.output.NoVersionFileNameMapping 
+</li>
+ 
+ </ul>
+ </p>
+<p>
+Your use of maven-ear-plugin in source or binary code form is subject to the terms and conditions of the 
+The Apache Software License, Version 2.0 (&quot;ASL&quot;).  
+A copy of the ASL is available at <a href="http://maven.apache.org/license.html">http://maven.apache.org/license.html</a>.
+(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>)
+</p>
+
+
+<h4>Spring Core (Derivative work)</h4>
+<p>
+This software is based in part on the work of The SpringSource on the Spring Core project.</p>
+<p>The org.eclipse.m2e.wtp.internal.AntPathMatcher class is copied from the following class from the Spring Core project :</p>
+<ul>
+<li>org.springframework.util.AntPathMatcher</li>
+</ul>
+<p>
+Your use of Spring Core in source or binary code form is subject to the terms and conditions of the 
+The Apache Software License, Version 2.0 (&quot;ASL&quot;).  
+A copy of the ASL is available at <a href="http://maven.apache.org/license.html">http://maven.apache.org/license.html</a>.
+(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>)
+</p>
+
+
+</body>
+</html>
diff --git a/org.eclipse.m2e.wtp/about.ini b/org.eclipse.m2e.wtp/about.ini
new file mode 100644
index 0000000..46e77bd
--- /dev/null
+++ b/org.eclipse.m2e.wtp/about.ini
@@ -0,0 +1,17 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%blurb
+
+# Property "featureImage" contains path to feature image (32x32)
+featureImage=m2e-wtp_icon_32px.png
+
+# Property "appName" contains name of the application (translated)
+appName=%featureName
+
+# Property "welcomePage" contains path to welcome page (special XML-based format)
+# welcomePage=$nl$/welcome.xml
diff --git a/org.eclipse.m2e.wtp/about.properties b/org.eclipse.m2e.wtp/about.properties
new file mode 100644
index 0000000..59c7741
--- /dev/null
+++ b/org.eclipse.m2e.wtp/about.properties
@@ -0,0 +1,2 @@
+blurb=m2e-wtp - Maven Integration for Eclipse WTP \n\nVersion\: {featureVersion}\n\n(c) Copyright Eclipse contributors and others 2008 - 2014.  All rights reserved.\nVisit http\://www.eclipse.org/m2e-wtp
+
diff --git a/org.eclipse.m2e.wtp/about_files/LICENSE-2.0.txt b/org.eclipse.m2e.wtp/about_files/LICENSE-2.0.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/org.eclipse.m2e.wtp/about_files/LICENSE-2.0.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/org.eclipse.m2e.wtp/about_files/NOTICE b/org.eclipse.m2e.wtp/about_files/NOTICE
new file mode 100644
index 0000000..467627e
--- /dev/null
+++ b/org.eclipse.m2e.wtp/about_files/NOTICE
@@ -0,0 +1,13 @@
+   =========================================================================
+   ==  NOTICE file corresponding to the section 4 d of                    ==
+   ==  the Apache License, Version 2.0,                                   ==
+   ==  in this case for the maven-war-plugin, maven-ear-plugin            ==
+   ==  and spring-core distributions.                                     ==
+   =========================================================================
+
+   This product includes software developed by :
+   The Apache Software Foundation (http://www.apache.org/) 
+   SpringSource (http://www.springsource.org/) 
+
+   Please read the different LICENSE files present in the root directory of
+   this distribution.
diff --git a/org.eclipse.m2e.wtp/build.properties b/org.eclipse.m2e.wtp/build.properties
new file mode 100644
index 0000000..980cb28
--- /dev/null
+++ b/org.eclipse.m2e.wtp/build.properties
@@ -0,0 +1,20 @@
+source.. = src/
+output.. = target/classes/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               icons/,\
+               schema/,\
+               lifecycle-mapping-metadata.xml,\
+               about.html,\
+               about.ini,\
+               about.properties,\
+               jars/maven-war-plugin-2.1.1.jar,\
+               about_files/,\
+               m2e-wtp_icon_32px.png,\
+               NOTICE,\
+               plugin.properties
+src.includes = about.html,\
+               about.ini,\
+               about.properties,\
+               about_files/
diff --git a/org.eclipse.m2e.wtp/icons/ear-resources.gif b/org.eclipse.m2e.wtp/icons/ear-resources.gif
new file mode 100644
index 0000000..2eeb3ef
--- /dev/null
+++ b/org.eclipse.m2e.wtp/icons/ear-resources.gif
Binary files differ
diff --git a/org.eclipse.m2e.wtp/icons/web-resources.gif b/org.eclipse.m2e.wtp/icons/web-resources.gif
new file mode 100644
index 0000000..274d361
--- /dev/null
+++ b/org.eclipse.m2e.wtp/icons/web-resources.gif
Binary files differ
diff --git a/org.eclipse.m2e.wtp/jars/maven-war-plugin-2.1.1.jar b/org.eclipse.m2e.wtp/jars/maven-war-plugin-2.1.1.jar
new file mode 100644
index 0000000..82d9427
--- /dev/null
+++ b/org.eclipse.m2e.wtp/jars/maven-war-plugin-2.1.1.jar
Binary files differ
diff --git a/org.eclipse.m2e.wtp/lifecycle-mapping-metadata.xml b/org.eclipse.m2e.wtp/lifecycle-mapping-metadata.xml
new file mode 100644
index 0000000..50834bd
--- /dev/null
+++ b/org.eclipse.m2e.wtp/lifecycle-mapping-metadata.xml
@@ -0,0 +1,306 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lifecycleMappingMetadata>
+  <lifecycleMappings>
+
+    <!--  javaee packaging types -->
+    <lifecycleMapping>
+      <packagingType>war</packagingType>
+      <lifecycleMappingId>org.maven.ide.eclipse.wtp.WarLifecycleMapping</lifecycleMappingId>
+      <pluginExecutions>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-war-plugin</artifactId>
+            <versionRange>[2.0.1,)</versionRange>
+            <goals>
+              <goal>war</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-war-plugin</artifactId>
+            <versionRange>[2.0.1,)</versionRange>
+            <goals>
+              <goal>war</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.warmanifest.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>           
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-war-plugin</artifactId>
+            <versionRange>[0.0.1,2.0.1)</versionRange>
+            <goals>
+              <goal>war</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+          	<error>
+          		<message>maven-war-plugin prior to 2.0.1 is not supported by m2e-wtp. Use maven-war-plugin version 2.0.1 or later</message>
+          	</error>
+          </action>
+        </pluginExecution>           
+		<pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-war-plugin</artifactId>
+            <versionRange>[2.0.1,)</versionRange>
+            <goals>
+              <goal>war</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.overlay.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>       
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-war-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>inplace</goal>
+              <goal>exploded</goal>
+              <goal>manifest</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+          	<ignore>
+          		<message>maven-war-plugin goals "inplace", "exploded", "manifest" are ignored by m2e</message>
+          	</ignore>
+          </action>
+        </pluginExecution>
+      </pluginExecutions>
+    </lifecycleMapping>
+    <lifecycleMapping>
+      <packagingType>ejb</packagingType>
+      <lifecycleMappingId>org.maven.ide.eclipse.wtp.EjbLifecycleMapping</lifecycleMappingId>
+      <pluginExecutions>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-ejb-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>ejb</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>
+      <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-ejb-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>ejb</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.ejbmanifest.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>          
+      </pluginExecutions>
+    </lifecycleMapping>
+    
+    
+    <lifecycleMapping>
+      <packagingType>ear</packagingType>
+      <lifecycleMappingId>org.maven.ide.eclipse.wtp.EarLifecycleMapping</lifecycleMappingId>
+      <pluginExecutions>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-ear-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>generate-application-xml</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-ear-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>ear</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.earmanifest.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-ear-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>generate-application-xml</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.java.unsupportedDependencyTypeConfigurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>  
+      </pluginExecutions>
+    </lifecycleMapping>
+    <lifecycleMapping>
+      <packagingType>rar</packagingType>
+      <lifecycleMappingId>org.maven.ide.eclipse.wtp.RarLifecycleMapping</lifecycleMappingId>
+      <pluginExecutions>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-rar-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>rar</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-rar-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>rar</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.rarmanifest.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>       
+      </pluginExecutions>
+    </lifecycleMapping>
+    <lifecycleMapping>
+      <packagingType>app-client</packagingType>
+      <lifecycleMappingId>org.maven.ide.eclipse.wtp.AcrLifecycleMapping</lifecycleMappingId>
+      <pluginExecutions>
+        <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-acr-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>acr</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>
+      <pluginExecution>
+          <pluginExecutionFilter>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-acr-plugin</artifactId>
+            <versionRange>[1.0,)</versionRange>
+            <goals>
+              <goal>acr</goal>
+            </goals>
+          </pluginExecutionFilter>
+          <action>
+            <configurator>
+              <id>org.maven.ide.eclipse.configuration.wtp.acrmanifest.configurator</id>
+            </configurator>
+          </action>
+        </pluginExecution>
+      </pluginExecutions>
+    </lifecycleMapping>
+    
+  </lifecycleMappings>
+  <pluginExecutions>
+	<pluginExecution>
+		<pluginExecutionFilter>
+			<groupId>org.apache.maven.plugins</groupId>
+			<artifactId>maven-compiler-plugin</artifactId>
+			<versionRange>[2.0,)</versionRange>
+			<goals>
+				<goal>compile</goal>
+				<goal>testCompile</goal>
+			</goals>
+		</pluginExecutionFilter>
+		<action>
+			<configurator>
+				<id>org.maven.ide.eclipse.configuration.wtp.webfragment.configurator</id>
+			</configurator>
+		</action>
+	</pluginExecution>
+	<pluginExecution>
+		<pluginExecutionFilter>
+			<groupId>org.apache.maven.plugins</groupId>
+			<artifactId>maven-compiler-plugin</artifactId>
+			<versionRange>[2.0,)</versionRange>
+			<goals>
+				<goal>compile</goal>
+				<goal>testCompile</goal>
+			</goals>
+		</pluginExecutionFilter>
+		<action>
+			<configurator>
+				<id>org.maven.ide.eclipse.configuration.wtp.utility.configurator</id>
+			</configurator>
+		</action>
+	</pluginExecution>
+	
+	<pluginExecution>
+		<pluginExecutionFilter>
+			<groupId>org.apache.maven.plugins</groupId>
+			<artifactId>maven-compiler-plugin</artifactId>
+			<versionRange>[2.0,)</versionRange>
+			<goals>
+				<goal>compile</goal>
+				<goal>testCompile</goal>
+			</goals>
+		</pluginExecutionFilter>
+		<action>
+			<configurator>
+				<id>org.maven.ide.eclipse.configuration.wtp.java.unsupportedDependencyTypeConfigurator</id>
+			</configurator>
+		</action>
+	</pluginExecution>
+
+
+  </pluginExecutions>
+
+</lifecycleMappingMetadata>
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp/m2e-wtp_icon_32px.png b/org.eclipse.m2e.wtp/m2e-wtp_icon_32px.png
new file mode 100644
index 0000000..2d37574
--- /dev/null
+++ b/org.eclipse.m2e.wtp/m2e-wtp_icon_32px.png
Binary files differ
diff --git a/org.eclipse.m2e.wtp/plugin.properties b/org.eclipse.m2e.wtp/plugin.properties
new file mode 100644
index 0000000..5d4a8c4
--- /dev/null
+++ b/org.eclipse.m2e.wtp/plugin.properties
@@ -0,0 +1,4 @@
+template.contextRootProperty.name=m2e-wtp's specific context root property
+template.contextRootProperty.description=Sets the Web Project's context root, overriding pom.xml's <warName> and <finalName>.
+template.m2eWtpActivationProperty.name=m2e-wtp activation
+template.m2eWtpActivationProperty.description=Enable or disable m2e-wtp configuration
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp/plugin.xml b/org.eclipse.m2e.wtp/plugin.xml
new file mode 100644
index 0000000..6d0502d
--- /dev/null
+++ b/org.eclipse.m2e.wtp/plugin.xml
@@ -0,0 +1,421 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+
+   <extension-point id="javaeeConfiguratorEnabler" name="Java EE Configurator Enablers" schema="schema/javaeeConfiguratorEnablers.exsd"/>
+
+   <extension
+         point="org.eclipse.m2e.core.lifecycleMappingMetadataSource">
+   </extension>
+  <extension
+    point="org.eclipse.m2e.core.lifecycleMappings">
+    <lifecycleMapping
+      class="org.eclipse.m2e.wtp.internal.lifecycle.WarLifecycleMapping"
+      id="org.maven.ide.eclipse.wtp.WarLifecycleMapping"
+      name="War Build Lifecycle Mapping">
+    </lifecycleMapping>
+    <lifecycleMapping
+      class="org.eclipse.m2e.wtp.internal.lifecycle.EjbLifecycleMapping"
+      id="org.maven.ide.eclipse.wtp.EjbLifecycleMapping"
+      name="Ejb Build Lifecycle Mapping">
+    </lifecycleMapping>
+    <lifecycleMapping
+      class="org.eclipse.m2e.wtp.internal.lifecycle.EarLifecycleMapping"
+      id="org.maven.ide.eclipse.wtp.EarLifecycleMapping"
+      name="Ear Build Lifecycle Mapping">
+    </lifecycleMapping>
+    <lifecycleMapping
+      class="org.eclipse.m2e.wtp.internal.lifecycle.RarLifecycleMapping"
+      id="org.maven.ide.eclipse.wtp.RarLifecycleMapping"
+      name="Rar Build Lifecycle Mapping">
+    </lifecycleMapping>
+    <lifecycleMapping
+      class="org.eclipse.m2e.wtp.internal.lifecycle.AcrLifecycleMapping"
+      id="org.maven.ide.eclipse.wtp.AcrLifecycleMapping"
+      name="Application Client Build Lifecycle Mapping">
+    </lifecycleMapping>    
+  </extension>
+  
+   <extension-point id="dependencyConfigurators" name="Dependency Configurators" schema="schema/dependencyConfigurators.exsd"/>
+   <extension-point id="facetDetectors" name="Project Facet detectors" schema="schema/facetDetectors.exsd"/>
+
+   <extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.configurator"
+          class="org.eclipse.m2e.wtp.WTPProjectConfigurator"
+          name="WTP" />
+   </extension>
+	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.overlay.configurator"
+          class="org.eclipse.m2e.wtp.OverlayConfigurator"
+          name="Overlay" 
+          runsAfter="org.maven.ide.eclipse.configuration.wtp.configurator"/>
+    </extension>        
+	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.warmanifest.configurator"
+          class="org.eclipse.m2e.wtp.internal.mavenarchiver.WarMavenArchiverConfigurator"
+          name="WarManifestConfigurator" 
+          runsAfter="org.maven.ide.eclipse.configuration.wtp.configurator"
+          />
+    </extension>  
+   	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.ejbmanifest.configurator"
+          class="org.eclipse.m2e.wtp.internal.mavenarchiver.EjbMavenArchiverConfigurator"
+          name="EjbManifestConfigurator" 
+          runsAfter="org.maven.ide.eclipse.configuration.wtp.configurator"
+          />
+    </extension> 
+	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.earmanifest.configurator"
+          class="org.eclipse.m2e.wtp.internal.mavenarchiver.EarMavenArchiverConfigurator"
+          name="EarManifestConfigurator" 
+          />
+    </extension>
+	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.rarmanifest.configurator"
+          class="org.eclipse.m2e.wtp.internal.mavenarchiver.RarMavenArchiverConfigurator"
+          name="RarManifestConfigurator" 
+          runsAfter="org.maven.ide.eclipse.configuration.wtp.configurator"
+          />
+    </extension>  
+	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.acrmanifest.configurator"
+          class="org.eclipse.m2e.wtp.internal.mavenarchiver.AcrMavenArchiverConfigurator"
+          name="AcrManifestConfigurator" 
+          runsAfter="org.maven.ide.eclipse.configuration.wtp.configurator"
+          />
+    </extension>                    
+    
+  	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.webfragment.configurator"
+          class="org.eclipse.m2e.wtp.WebFragmentProjectConfigurator"
+          name="WebFragmentConfigurator" 
+          runsAfter="org.eclipse.m2e.jdt.javaConfigurator"
+          />
+    </extension> 
+    
+  	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.utility.configurator"
+          class="org.eclipse.m2e.wtp.UtilityProjectConfigurator"
+          name="UtilityConfigurator" 
+          runsAfter="org.eclipse.m2e.jdt.javaConfigurator"
+          />
+    </extension>     
+
+  	<extension point="org.eclipse.m2e.core.projectConfigurators">
+      <configurator 
+          id="org.maven.ide.eclipse.configuration.wtp.java.unsupportedDependencyTypeConfigurator"
+          class="org.eclipse.m2e.wtp.UnsupportedDependencyTypeProjectConfigurator"
+          name="Unsupported Dependency Type Project Configurator" 
+          runsAfter="org.eclipse.m2e.jdt.javaConfigurator?,org.maven.ide.eclipse.configuration.wtp.configurator?"
+          />
+    </extension>
+
+   <!-- A workaround to allow to uninstall WTP facets -->   
+   <extension point="org.eclipse.wst.common.project.facet.core.facets">
+      <action type="uninstall" facet="jst.ear" version="[1.2-7.0]">
+         <delegate class="org.eclipse.m2e.wtp.internal.facets.EarUninstallDelegate"/>
+      </action>
+      <action type="uninstall" facet="jst.ejb" version="[1.1-3.2]">
+         <delegate class="org.eclipse.m2e.wtp.internal.facets.EjbUninstallDelegate"/>
+      </action>
+      <action type="uninstall" facet="jst.web" version="[2.2-3.1]">
+         <delegate class="org.eclipse.m2e.wtp.internal.facets.WarUninstallDelegate"/>
+      </action>
+      <action type="uninstall" facet="jst.connector" version="[1.0-1.7]">
+         <delegate class="org.eclipse.m2e.wtp.internal.facets.RarUninstallDelegate"/>
+      </action>
+      <action type="uninstall" facet="jst.appclient" version="[1.0-7.0]">
+         <delegate class="org.eclipse.m2e.wtp.internal.facets.AppClientUninstallDelegate"/>
+      </action>
+   </extension>
+   <extension
+        point="org.eclipse.wst.common.project.facet.core.listeners">
+     <listener
+           class="org.eclipse.m2e.wtp.internal.facets.EarVersionChangeListener"
+           eventTypes="POST_VERSION_CHANGE">
+     </listener>
+     <listener
+           class="org.eclipse.m2e.wtp.internal.facets.EjbVersionChangeListener"
+           eventTypes="POST_VERSION_CHANGE">
+     </listener>
+     <listener
+           class="org.eclipse.m2e.wtp.internal.facets.WarVersionChangeListener"
+           eventTypes="POST_VERSION_CHANGE">
+     </listener>
+     <listener
+           class="org.eclipse.m2e.wtp.internal.facets.RarVersionChangeListener"
+           eventTypes="POST_VERSION_CHANGE">
+     </listener>
+     <listener
+           class="org.eclipse.m2e.wtp.internal.facets.AppClientVersionChangeListener"
+           eventTypes="POST_VERSION_CHANGE">
+     </listener>
+  </extension>
+   
+   <!-- Project Explorer extensions --> 
+   <extension point="org.eclipse.ui.navigator.navigatorContent">
+      <navigatorContent id="org.maven.ide.eclipse.wtp.navigatorContent"
+            contentProvider="org.eclipse.m2e.wtp.internal.WTPResourcesContentProvider"
+            labelProvider="org.eclipse.m2e.wtp.internal.WTPResourcesLabelProvider"
+            name="Deployed Resources"
+            icon="icons/web-resources.gif"
+            activeByDefault="true"
+            priority="normal">
+       
+        <override suppressedExtensionId="org.eclipse.ui.navigator.resourceContent"        
+                  policy="InvokeOnlyIfSuppressedExtAlsoVisibleAndActive"/>
+          
+        <triggerPoints>
+          <instanceof value="org.eclipse.core.resources.IProject"/>
+        </triggerPoints>
+        
+        <possibleChildren>
+          <instanceof value="org.eclipse.m2e.wtp.internal.WTPResourcesNode"/>
+        </possibleChildren>
+      
+        <commonSorter id="org.maven.ide.eclipse.wtp.sorter"
+                      class="org.eclipse.m2e.wtp.internal.WTPResourcesSorter">
+          <parentExpression>
+	           <or>         
+	             <instanceof value="org.eclipse.core.resources.IProject"/>
+	             <instanceof value="org.eclipse.m2e.wtp.internal.WTPResourcesNode"/>
+	             <instanceof value="org.eclipse.core.resources.IFolder"/>
+	             <instanceof value="org.eclipse.core.resources.IFile"/>
+	           </or>
+          </parentExpression>
+        </commonSorter>
+      </navigatorContent>
+   </extension>
+      
+   <extension point="org.eclipse.ui.navigator.viewer">
+      <viewerActionBinding viewerId="org.eclipse.ui.navigator.ProjectExplorer">
+         <includes>
+           <actionExtension pattern="org.maven.ide.eclipse.wtp.actionProvider"/>
+         </includes>
+      </viewerActionBinding>
+      
+      <viewerContentBinding viewerId="org.eclipse.ui.navigator.ProjectExplorer">
+         <includes>
+            <contentExtension pattern="org.maven.ide.eclipse.wtp.navigatorContent"/>
+         </includes>
+      </viewerContentBinding>
+   </extension> 
+
+   <extension point="org.eclipse.core.runtime.preferences">
+      <initializer class="org.eclipse.m2e.wtp.internal.preferences.MavenWtpPreferenceInitializer"/>
+   </extension>
+  
+   <extension point="org.eclipse.ui.preferencePages">
+      <page id="org.eclipse.m2e.wtp.preferences.MavenWtpPreferencePage"
+         category="org.eclipse.m2e.core.preferences.Maven2PreferencePage"
+         class="org.eclipse.m2e.wtp.internal.preferences.MavenWtpPreferencePage"
+         name="Java EE Integration">
+         <keywordReference id="org.eclipse.m2e.core.maven"/>
+      </page>
+   </extension>
+   <extension
+         point="org.eclipse.ui.propertyPages">
+      
+      <page id="org.maven.ide.eclipse.wtp.preferences.MavenWtpPropertyPage"
+            class="org.eclipse.m2e.wtp.internal.preferences.MavenWtpPreferencePage"
+            name="Java EE Integration"
+            category="org.eclipse.m2e.core.MavenProjectPreferencePage">
+            <enabledWhen>
+               <and>
+                    <instanceof
+                          value="org.eclipse.core.resources.IProject">
+                    </instanceof>
+                   <test
+                        property="org.eclipse.core.resources.projectNature"
+                        value="org.eclipse.m2e.core.maven2Nature">
+                   </test>
+                   <test
+                        property="org.eclipse.core.resources.projectNature"
+                        value="org.eclipse.wst.common.modulecore.ModuleCoreNature">
+                   </test>
+                </and>
+            </enabledWhen>
+      </page>
+   </extension>
+   
+   <extension point="org.eclipse.core.resources.markers"
+         id="org.eclipse.m2e.core.maven2Problem.wtp.overlayError"
+         name="Maven Java EE Configuration Problem">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension point="org.eclipse.core.resources.markers"
+         id="org.eclipse.m2e.core.maven2Problem.wtp.manifestError"
+         name="Maven Java EE Configuration Problem">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension point="org.eclipse.core.resources.markers"
+         id="org.eclipse.m2e.core.maven2Problem.wtp.configuration"
+         name="Maven Java EE Configuration Problem">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension point="org.eclipse.core.resources.markers"
+         id="org.eclipse.m2e.core.maven2Problem.wtp.unsupportedDependencyProblem"
+         name="Maven Java EE Dependency Problem">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension point="org.eclipse.core.resources.markers"
+         id="org.eclipse.m2e.core.maven2Problem.wtp.applicationXmlError"
+         name="Maven Java EE Configuration Problem">
+      <super type="org.eclipse.m2e.core.maven2Problem.wtp.configuration"/>
+      <persistent value="true"/>
+   </extension>
+   <extension point="org.eclipse.core.resources.markers"
+         id="org.eclipse.m2e.core.maven2Problem.wtp.failOnMissingWebXml"
+         name="Maven Java EE Configuration Problem">
+      <super type="org.eclipse.m2e.core.maven2Problem.wtp.configuration"/>
+      <persistent value="true"/>
+   </extension>
+   <extension point="org.eclipse.core.resources.markers"
+         id="org.eclipse.m2e.core.maven2Problem.wtp.filteringError"
+         name="Maven Java EE Configuration Problem">
+      <super type="org.eclipse.m2e.core.maven2Problem.wtp.configuration"/>
+      <persistent value="true"/>
+   </extension>   
+    <extension point="org.eclipse.ui.perspectiveExtensions">
+ 	    <perspectiveExtension
+ 	 	    targetID="org.eclipse.jst.j2ee.J2EEPerspective">
+ 	 	    <newWizardShortcut
+ 	 	         id="org.eclipse.m2e.core.wizards.Maven2ProjectWizard">
+ 	 	    </newWizardShortcut>
+ 	 	</perspectiveExtension>
+   </extension>
+ 	
+   <extension
+         point="org.eclipse.m2e.core.projectConversionParticipants" >
+         
+         	  <!-- m2e 1.3 requires all 3rd party plugins to register compatible packagings -->
+      <conversionParticipantConfiguration 
+      		conversionParticipantId="org.eclipse.m2e.jdt.javaProjectConversionParticipant"
+      		compatiblePackagings="war,ejb,rar,app-client" 
+      	 />
+  
+      <conversionParticipantConfiguration 
+      		conversionParticipantId="org.eclipse.m2e.wtp.conversion.WebProjectConverter"
+      		compatiblePackagings="war" 
+      	 />
+      <conversionParticipantConfiguration 
+      		conversionParticipantId="org.eclipse.m2e.wtp.conversion.EjbProjectConverter"
+      		compatiblePackagings="ejb" 
+      	 />     
+      <conversionParticipantConfiguration 
+      		conversionParticipantId="org.eclipse.m2e.wtp.conversion.ConnectorProjectConverter"
+      		compatiblePackagings="rar" 
+      	 />     
+      <conversionParticipantConfiguration 
+      		conversionParticipantId="org.eclipse.m2e.wtp.conversion.AppClientProjectConverter"
+      		compatiblePackagings="app-client" 
+      	 />     
+      <conversionParticipantConfiguration 
+      		conversionParticipantId="org.eclipse.m2e.wtp.conversion.EarProjectConverter"
+      		compatiblePackagings="ear" 
+      	 />     
+         
+         
+      <projectConversionParticipant
+            class="org.eclipse.m2e.wtp.internal.conversion.WebProjectConverter"
+            id="org.eclipse.m2e.wtp.conversion.WebProjectConverter"
+            name="Dynamic Web Project conversion participant"
+            nature="org.eclipse.wst.common.modulecore.ModuleCoreNature">
+      </projectConversionParticipant>   
+      <projectConversionParticipant
+            class="org.eclipse.m2e.wtp.internal.conversion.EjbProjectConverter"
+            id="org.eclipse.m2e.wtp.conversion.EjbProjectConverter"
+            name="WTP EJB Project conversion participant"
+            nature="org.eclipse.wst.common.modulecore.ModuleCoreNature">
+      </projectConversionParticipant>   
+      <projectConversionParticipant
+            class="org.eclipse.m2e.wtp.internal.conversion.EarProjectConverter"
+            id="org.eclipse.m2e.wtp.conversion.EarProjectConverter"
+            name="WTP EAR Project conversion participant"
+            nature="org.eclipse.wst.common.modulecore.ModuleCoreNature">
+      </projectConversionParticipant>   
+      <projectConversionParticipant
+            class="org.eclipse.m2e.wtp.internal.conversion.AppClientProjectConverter"
+            id="org.eclipse.m2e.wtp.conversion.AppClientProjectConverter"
+            name="WTP Application Client Project conversion participant"
+            nature="org.eclipse.wst.common.modulecore.ModuleCoreNature">
+      </projectConversionParticipant>   
+      <projectConversionParticipant
+            class="org.eclipse.m2e.wtp.internal.conversion.ConnectorProjectConverter"
+            id="org.eclipse.m2e.wtp.conversion.ConnectorProjectConverter"
+            name="WTP Connector Project conversion participant"
+            nature="org.eclipse.wst.common.modulecore.ModuleCoreNature">
+      </projectConversionParticipant>
+
+      	      
+    </extension>
+   <extension
+         point="org.eclipse.m2e.jdt.classifierClasspathProviders">
+      <classifierClasspathProvider
+            class="org.eclipse.m2e.wtp.internal.jdt.launch.WarClassesClassifierClasspathProvider"
+            id="org.eclipse.m2e.wtp.warClassesClassifierClasspathProvider"
+            name="War classes Classpath Provider">
+      </classifierClasspathProvider>
+      <classifierClasspathProvider
+            class="org.eclipse.m2e.wtp.internal.jdt.launch.EjbClientClassifierClasspathProvider"
+            id="org.eclipse.m2e.wtp.ejbClientClassifierClasspathProvider"
+            name="EJB Client Classpath Provider">
+      </classifierClasspathProvider>
+   </extension>    
+   <extension
+         point="org.eclipse.m2e.core.conversionEnabler">
+      <enabler
+            class="org.eclipse.m2e.wtp.internal.conversion.WebProjectConversionEnabler"
+            id="org.eclipse.m2e.wtp.conversion.web.enabler"
+            weight="50">
+      </enabler>
+      <enabler
+            class="org.eclipse.m2e.wtp.internal.conversion.EarProjectConversionEnabler"
+            id="org.eclipse.m2e.wtp.conversion.ear.enabler"
+            weight="50">
+      </enabler>
+      <enabler
+            class="org.eclipse.m2e.wtp.internal.conversion.EjbProjectConversionEnabler"
+            id="org.eclipse.m2e.wtp.conversion.ejb.enabler"
+            weight="50">
+      </enabler>
+      <enabler
+            class="org.eclipse.m2e.wtp.internal.conversion.AppClientProjectConversionEnabler"
+            id="org.eclipse.m2e.wtp.conversion.appclient.enabler"
+            weight="50">
+      </enabler>
+      <enabler
+            class="org.eclipse.m2e.wtp.internal.conversion.ConnectorProjectConversionEnabler"
+            id="org.eclipse.m2e.wtp.conversion.connector.enabler"
+            weight="50">
+      </enabler>
+   </extension>
+
+  <extension point="org.eclipse.ui.editors.templates">
+    <template id="org.eclipse.m2e.wtp.xml.templates.contextRootProperty"
+         contextTypeId="org.eclipse.m2e.editor.xml.templates.contextType.properties"
+         name="%template.contextRootProperty.name" 
+         description="%template.contextRootProperty.description">
+      <pattern>&lt;m2eclipse.wtp.contextRoot&gt;${cursor}&lt;/m2eclipse.wtp.contextRoot&gt;</pattern>
+    </template>
+    <template id="org.eclipse.m2e.wtp.xml.templates.m2eWtpActivationProperty"
+         contextTypeId="org.eclipse.m2e.editor.xml.templates.contextType.properties"
+         name="%template.m2eWtpActivationProperty.name" 
+         description="%template.m2eWtpActivationProperty.description">
+      <pattern>&lt;m2e.wtp.activation&gt;${cursor}${false}&lt;/m2e.wtp.activation&gt;</pattern>
+    </template>
+   </extension> 
+</plugin>
diff --git a/org.eclipse.m2e.wtp/pom.xml b/org.eclipse.m2e.wtp/pom.xml
new file mode 100644
index 0000000..0cc41e4
--- /dev/null
+++ b/org.eclipse.m2e.wtp/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (c) 2008 Sonatype, Inc. All rights reserved. This program 
+	and the accompanying materials are made available under the terms of the 
+	Eclipse Public License v1.0 which accompanies this distribution, and is available 
+	at http://www.eclipse.org/legal/epl-v10.html -->
+<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>
+		<groupId>org.eclipse.m2e.wtp</groupId>
+		<artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+		<version>1.3.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>org.eclipse.m2e.wtp</artifactId>
+	<packaging>eclipse-plugin</packaging>
+
+	<name>M2E-WTP :: Core</name>
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.maven.plugins</groupId>
+			<artifactId>maven-war-plugin</artifactId>
+			<type>maven-plugin</type>
+			<version>2.1.1</version>
+		</dependency>
+	</dependencies>
+
+</project>
diff --git a/org.eclipse.m2e.wtp/schema/dependencyConfigurators.exsd b/org.eclipse.m2e.wtp/schema/dependencyConfigurators.exsd
new file mode 100644
index 0000000..d31042e
--- /dev/null
+++ b/org.eclipse.m2e.wtp/schema/dependencyConfigurators.exsd
@@ -0,0 +1,138 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.m2e.wtp" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.m2e.wtp" id="dependencyConfigurators" name="Dependency Configurators"/>
+      </appinfo>
+      <documentation>
+         Dependency Configurators
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence minOccurs="1" maxOccurs="unbounded">
+            <element ref="configurator"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="configurator">
+      <annotation>
+         <documentation>
+            Dependency configurator
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Unique configurator id
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Configurator implementation
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.m2e.wtp.AbstractDependencyConfigurator:"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  Configurator name, eg. &quot;Flex&quot;, etc.
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="priority" type="string">
+            <annotation>
+               <documentation>
+                  Priority of given configurator. Smaller number correspond to higher priority
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         0.9.4
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2007, 2008 Sonatype, Inc.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.m2e.wtp/schema/facetDetectors.exsd b/org.eclipse.m2e.wtp/schema/facetDetectors.exsd
new file mode 100644
index 0000000..9805b24
--- /dev/null
+++ b/org.eclipse.m2e.wtp/schema/facetDetectors.exsd
@@ -0,0 +1,135 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.m2e.wtp" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.m2e.wtp" id="facetDetectors" name="Project Facet Detectors"/>
+      </appInfo>
+      <documentation>
+         Detects the Project Facet version for a maven project
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appInfo>
+            <meta.element />
+         </appInfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="facetDetector" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="facetDetector">
+      <complexType>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  Id of this facet detector
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="facetId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The Facet id this detector applies to
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The class implementing the Facet detection mechanism
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.m2e.wtp.facets.AbstractFacetDetector:"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="priority" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The priority (must be an int.) in which this detector should be invoked. Smaller number corresponds to a higher priority.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         0.18.0
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiinfo"/>
+      </appInfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2013 Red Hat, Inc.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.m2e.wtp/schema/javaeeConfiguratorEnablers.exsd b/org.eclipse.m2e.wtp/schema/javaeeConfiguratorEnablers.exsd
new file mode 100644
index 0000000..59e18c5
--- /dev/null
+++ b/org.eclipse.m2e.wtp/schema/javaeeConfiguratorEnablers.exsd
@@ -0,0 +1,136 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.m2e.wtp" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.m2e.wtp" id="javaeeConfiguratorEnabler" name="Java EE Configurator Enablers"/>
+      </appinfo>
+      <documentation>
+         Java EE Configurator Enablers
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence minOccurs="1" maxOccurs="unbounded">
+            <element ref="javaeeConfiguratorEnabler"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="javaeeConfiguratorEnabler">
+      <annotation>
+         <documentation>
+            Java EE Configurator Enabler
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Unique project configurator enabler id
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="label" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Label of the Configurator.
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="description" type="string">
+            <annotation>
+               <documentation>
+                  Description of the Java EE configurator this enabler targets, used as tooltip in the preference page. 
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="configuratorIds" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Comma-separated list of projectConfigurator ids this enabler targets.
+               </documentation>
+            </annotation>
+         </attribute>
+         
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         0.17.0
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2013 Red Hat, Inc.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AbstractDependencyConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AbstractDependencyConfigurator.java
new file mode 100644
index 0000000..ae33e20
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AbstractDependencyConfigurator.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.m2e.core.embedder.MavenRuntimeManager;
+import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager;
+import org.eclipse.m2e.core.project.IMavenProjectRegistry;
+
+/**
+* Base class to configure dependent worskpace projects.
+* 
+* @provisional This class has been added as part of a work in progress. 
+* It is not guaranteed to work or remain the same in future releases. 
+* For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+* 
+* @author Eugene Kuleshov
+*/
+public abstract class AbstractDependencyConfigurator {
+
+  public static final String ATTR_ID = "id"; //$NON-NLS-1$
+  
+  public static final String ATTR_PRIORITY = "priority"; //$NON-NLS-1$
+
+  public static final String ATTR_NAME = "name"; //$NON-NLS-1$
+  
+  public static final String ATTR_CLASS = "class"; //$NON-NLS-1$
+  
+  private int priority;
+  private String id;
+  private String name;
+
+  protected IMavenProjectRegistry projectManager;
+  protected MavenRuntimeManager runtimeManager;
+  protected IMavenMarkerManager markerManager; 
+  
+  public void setProjectManager(IMavenProjectRegistry projectManager) {
+    this.projectManager = projectManager;
+  }
+  
+  public void setRuntimeManager(MavenRuntimeManager runtimeManager) {
+    this.runtimeManager = runtimeManager;
+  }
+
+  public void setMarkerManager(IMavenMarkerManager markerManager) {
+    this.markerManager = markerManager;
+  }
+  
+  public abstract void configureDependency(MavenProject mavenProject, IProject mavenIProject, MavenProject dependencyProject, 
+      IProject dependencyIProject, IProgressMonitor monitor) throws MarkedException;
+
+  public void setInitializationData(IConfigurationElement config, String propertyName, Object data) {
+    this.id = config.getAttribute(ATTR_ID);
+    this.name = config.getAttribute(ATTR_NAME);
+    String priorityString = config.getAttribute(ATTR_PRIORITY);
+    try {
+      priority = Integer.parseInt(priorityString);
+    } catch (Exception ex) {
+      priority = Integer.MAX_VALUE;
+    }
+  }
+
+  protected void addNature(IProject project, String natureId, IProgressMonitor monitor) throws CoreException {
+    if (!project.hasNature(natureId)) {
+      IProjectDescription description = project.getDescription();
+      String[] prevNatures = description.getNatureIds();
+      String[] newNatures = new String[prevNatures.length + 1];
+      System.arraycopy(prevNatures, 0, newNatures, 1, prevNatures.length);
+      newNatures[0] = natureId;
+      description.setNatureIds(newNatures);
+      project.setDescription(description, monitor);
+    }
+  }
+
+  @Override
+  public String toString() {
+    return id + ":" + name + "(" + priority + ")";   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+  }
+
+  public void init() {
+    //do nothing here, extenders may override
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AbstractFilteringSupportMavenPlugin.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AbstractFilteringSupportMavenPlugin.java
new file mode 100644
index 0000000..a10f58e
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AbstractFilteringSupportMavenPlugin.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.m2e.wtp.internal.StringUtils;
+
+/**
+ * Base class for Maven plugin models supporting resource filtering.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ *
+ * @author Fred Bricon
+ */
+public abstract class AbstractFilteringSupportMavenPlugin {
+  
+  private Xpp3Dom configuration;
+
+  public final void setConfiguration(Xpp3Dom configuration) {
+    this.configuration = configuration;
+  }
+
+  public Xpp3Dom getConfiguration() {
+    return configuration;
+  }
+  
+  public String getEscapeString() {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      return DomUtils.getChildValue(config, "escapeString"); //$NON-NLS-1$
+    }
+    return null;
+  }
+
+  public Xpp3Dom[] getNonfilteredExtensions() {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom extensionsNode = config.getChild("nonFilteredFileExtensions"); //$NON-NLS-1$
+      if (extensionsNode != null && extensionsNode.getChildCount() > 0) {
+        return extensionsNode.getChildren();
+      }
+    }
+    return new Xpp3Dom[0];
+  }
+  
+  public Collection<String> getFilters() {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom filtersNode = config.getChild("filters"); //$NON-NLS-1$
+      if (filtersNode != null && filtersNode.getChildCount() > 0) {
+        List<String> filters = new ArrayList<>(filtersNode.getChildCount());
+        for (Xpp3Dom filterNode : filtersNode.getChildren("filter")) { //$NON-NLS-1$
+          String  filter = filterNode.getValue();
+          if (!StringUtils.nullOrEmpty(filter)) {
+            filters.add(filter);
+          }
+        }
+        return filters;
+      }
+    }
+    return Collections.emptyList();
+  }  
+  
+  public boolean isFilteringDeploymentDescriptorsEnabled()  {
+    Xpp3Dom configuration = getConfiguration();
+    if(configuration == null) {
+      return false;
+    }
+    return DomUtils.getBooleanChildValue(configuration, getFilteringAttribute());
+  }
+
+  protected abstract String getFilteringAttribute();
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AbstractProjectConfiguratorDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AbstractProjectConfiguratorDelegate.java
new file mode 100644
index 0000000..827e4a7
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AbstractProjectConfiguratorDelegate.java
@@ -0,0 +1,403 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import static org.eclipse.m2e.wtp.internal.StringUtils.joinAsString;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.internal.MavenPluginActivator;
+import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager;
+import org.eclipse.m2e.core.internal.markers.SourceLocation;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.IMavenProjectRegistry;
+import org.eclipse.m2e.core.project.MavenProjectUtils;
+import org.eclipse.m2e.jdt.IClasspathDescriptor;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.internal.utilities.DebugUtilities;
+import org.eclipse.m2e.wtp.internal.webfragment.WebFragmentUtil;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.internal.StructureEdit;
+import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Base class to configure JavaEE projects
+ * 
+ * @author Igor Fedorenko
+ * @author Fred Bricon
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ */
+abstract class AbstractProjectConfiguratorDelegate implements IProjectConfiguratorDelegate {
+
+  private static final Logger LOG = LoggerFactory.getLogger(AbstractProjectConfiguratorDelegate.class); 
+  
+  static final IClasspathAttribute NONDEPENDENCY_ATTRIBUTE = JavaCore.newClasspathAttribute(
+      IClasspathDependencyConstants.CLASSPATH_COMPONENT_NON_DEPENDENCY, ""); //$NON-NLS-1$
+
+  protected static final IPath ROOT_PATH = new Path("/");  //$NON-NLS-1$
+
+  protected final IMavenProjectRegistry projectManager;
+
+  protected final IMavenMarkerManager mavenMarkerManager;
+
+  AbstractProjectConfiguratorDelegate() {
+    this.projectManager = MavenPlugin.getMavenProjectRegistry();
+    this.mavenMarkerManager = MavenPluginActivator.getDefault().getMavenMarkerManager();
+  }
+  
+  @Override
+public void configureProject(IProject project, MavenProject mavenProject, IProgressMonitor monitor) throws MarkedException {
+    try {
+      mavenMarkerManager.deleteMarkers(project,MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID);
+      configure(project, mavenProject, monitor);
+    } catch (CoreException cex) {
+      //TODO Filter out constraint violations
+      mavenMarkerManager.addErrorMarkers(project, MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID, cex);
+      throw new MarkedException(NLS.bind(Messages.AbstractProjectConfiguratorDelegate_Unable_To_Configure_Project,project.getName()), cex);
+    }
+  }
+ 
+  protected abstract void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException;
+
+  protected List<IMavenProjectFacade> getWorkspaceDependencies(IProject project, MavenProject mavenProject) {
+    Set<IProject> projects = new HashSet<>();
+    List<IMavenProjectFacade> dependencies = new ArrayList<>();
+    Set<Artifact> artifacts = mavenProject.getArtifacts();
+    for(Artifact artifact : artifacts) {
+      IMavenProjectFacade dependency = projectManager.getMavenProject(artifact.getGroupId(), artifact.getArtifactId(),
+          artifact.getVersion());
+      
+      if((Artifact.SCOPE_COMPILE.equals(artifact.getScope()) 
+          || Artifact.SCOPE_RUNTIME.equals(artifact.getScope())) //MNGECLIPSE-1578 Runtime dependencies should be deployed 
+          && dependency != null && !dependency.getProject().equals(project) && dependency.getFullPath(artifact.getFile()) != null
+          && projects.add(dependency.getProject())) {
+        dependencies.add(dependency);
+      }
+    }
+    return dependencies;
+  }
+
+  protected void configureWtpUtil(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
+    // Adding utility facet on JEE projects is not allowed
+    IProject project = facade.getProject();
+    MavenProject mavenProject = facade.getMavenProject();
+    if(  !WTPProjectsUtil.isJavaProject(facade)
+       || WTPProjectsUtil.isJavaEEProject(project) 
+       || WebFragmentUtil.isQualifiedAsWebFragment(facade)) {
+      return;
+    }
+    
+    //MECLIPSEWTP-66 delete extra MANIFEST.MF
+    IPath[] sourceRoots = MavenProjectUtils.getSourceLocations(project, mavenProject.getCompileSourceRoots());
+    IPath[] resourceRoots = MavenProjectUtils.getResourceLocations(project, mavenProject.getResources());
+    
+    //MECLIPSEWTP-182 check if the Java Project configurator has been successfully run before doing anything : 
+    if (!checkJavaConfiguration(project, sourceRoots, resourceRoots)) {
+      LOG.warn(NLS.bind(Messages.AbstractProjectConfiguratorDelegate_Error_Inconsistent_Java_Configuration, project.getName()));
+      return;
+    }
+
+    boolean isDebugEnabled = DebugUtilities.isDebugEnabled();
+    if (isDebugEnabled) {
+      DebugUtilities.debug(DebugUtilities.dumpProjectState("Before configuration ",project)); //$NON-NLS-1$
+    }
+
+    // 2 - check if the manifest already exists, and its parent folder
+    
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
+    Set<Action> actions = new LinkedHashSet<>();
+    installJavaFacet(actions, project, facetedProject);
+
+    if(!facetedProject.hasProjectFacet(WTPProjectsUtil.UTILITY_FACET)) {
+      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, WTPProjectsUtil.UTILITY_10, null));
+    } else if(!facetedProject.hasProjectFacet(WTPProjectsUtil.UTILITY_10)) {
+      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, WTPProjectsUtil.UTILITY_10,
+          null));
+    }
+    
+    if (!actions.isEmpty()) {
+      ResourceCleaner fileCleaner = new ResourceCleaner(project);
+      try {
+        addFoldersToClean(fileCleaner, facade);
+        facetedProject.modify(actions, monitor);      
+      } finally {
+        //Remove any unwanted MANIFEST.MF the Facet installation has created
+        fileCleaner.cleanUp();
+      } 
+    }
+    
+    fixMissingModuleCoreNature(project, monitor);
+    
+    if (isDebugEnabled) {
+      DebugUtilities.debug(DebugUtilities.dumpProjectState("after configuration ",project)); //$NON-NLS-1$
+    }
+    //MNGECLIPSE-904 remove tests folder links for utility jars
+    removeTestFolderLinks(project, mavenProject, monitor, "/"); //$NON-NLS-1$
+    
+    //Remove "library unavailable at runtime" warning.
+    if (isDebugEnabled) {
+      DebugUtilities.debug(DebugUtilities.dumpProjectState("after removing test folders ",project)); //$NON-NLS-1$
+    }
+
+    setNonDependencyAttributeToContainer(project, monitor);
+    
+    WTPProjectsUtil.removeWTPClasspathContainer(project);
+  }
+
+  /**
+   * Checks the maven source folders are correctly added to the project classpath
+   */
+  private boolean checkJavaConfiguration(IProject project, IPath[] sourceRoots, IPath[] resourceRoots) throws JavaModelException {
+    IJavaProject javaProject = JavaCore.create(project);
+    if (javaProject == null) {
+      return false;
+    }
+    IClasspathEntry[] cpEntries = javaProject.getRawClasspath();
+    if (cpEntries == null) {
+      return false;
+    }
+    Set<IPath> currentPaths = new HashSet<>();
+    for (IClasspathEntry entry  : cpEntries) {
+      if (IClasspathEntry.CPE_SOURCE == entry.getEntryKind()){
+        currentPaths.add(entry.getPath().makeRelativeTo(project.getFullPath()));
+      }
+    }
+    for(IPath mavenSource : sourceRoots) {
+        if (mavenSource != null && !mavenSource.isEmpty()) {
+          IFolder sourceFolder = project.getFolder(mavenSource);
+          if (sourceFolder.exists() && !currentPaths.contains(mavenSource)) {
+            return false;
+          }
+        }
+    }
+    for(IPath mavenSource : resourceRoots) {
+      if (mavenSource != null && !mavenSource.isEmpty()) {
+        IFolder resourceFolder = project.getFolder(mavenSource);
+        if (resourceFolder.exists() && !currentPaths.contains(mavenSource)) {
+          return false;
+        }
+      }
+  }
+    return true;
+  }
+
+  /**
+   * Add the ModuleCoreNature to a project, if necessary.
+   * 
+   * @param project An accessible project.
+   * @param monitor A progress monitor to track the time to completion
+   * @throws CoreException if the ModuleCoreNature cannot be added
+   */
+  protected void fixMissingModuleCoreNature(IProject project, IProgressMonitor monitor) throws CoreException {
+    WTPProjectsUtil.fixMissingModuleCoreNature(project, monitor);
+  }
+
+  protected void installJavaFacet(Set<Action> actions, IProject project, IFacetedProject facetedProject) {
+    WTPProjectsUtil.installJavaFacet(actions, project, facetedProject);
+  }
+
+  protected void removeTestFolderLinks(IProject project, MavenProject mavenProject, IProgressMonitor monitor,
+      String folder) throws CoreException {
+    WTPProjectsUtil.removeTestFolderLinks(project, mavenProject, monitor, folder);
+  }
+
+  protected void addContainerAttribute(IProject project, IClasspathAttribute attribute, IProgressMonitor monitor)
+      throws JavaModelException {
+    updateContainerAttributes(project, attribute, null, monitor);
+  }
+
+  protected void setNonDependencyAttributeToContainer(IProject project, IProgressMonitor monitor) throws JavaModelException {
+    WTPProjectsUtil.updateContainerAttributes(project, NONDEPENDENCY_ATTRIBUTE, IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY, monitor);
+  }
+
+  protected void updateContainerAttributes(IProject project, IClasspathAttribute attributeToAdd, String attributeToDelete, IProgressMonitor monitor)
+  throws JavaModelException {
+    WTPProjectsUtil.updateContainerAttributes(project, attributeToAdd, attributeToDelete, monitor);
+  }
+
+  /**
+   * @param dependencyMavenProjectFacade
+   * @param monitor
+   * @return
+   * @throws CoreException
+   */
+  protected IProject preConfigureDependencyProject(IMavenProjectFacade dependencyMavenProjectFacade, IProgressMonitor monitor) throws CoreException {
+    IProject dependency = dependencyMavenProjectFacade.getProject();
+    String depPackaging = dependencyMavenProjectFacade.getPackaging();
+    //jee dependency has not been configured yet - i.e. it has no JEE facet-
+    if(!JEEPackaging.isJEEPackaging(depPackaging)) {
+      // XXX Probably should create a UtilProjectConfiguratorDelegate
+      configureWtpUtil(dependencyMavenProjectFacade, monitor);
+    }
+    return dependency;
+  }
+
+  @SuppressWarnings("restriction")
+  protected void configureDeployedName(IProject project, String deployedFileName) {
+    //We need to remove the file extension from deployedFileName 
+    int extSeparatorPos  = deployedFileName.lastIndexOf('.');
+    String deployedName = extSeparatorPos > -1? deployedFileName.substring(0, extSeparatorPos): deployedFileName;
+    //From jerr's patch in MNGECLIPSE-965
+    IVirtualComponent projectComponent = ComponentCore.createComponent(project);
+    if(projectComponent != null && !deployedName.equals(projectComponent.getDeployedName())){//MNGECLIPSE-2331 : Seems projectComponent.getDeployedName() can be null 
+      StructureEdit moduleCore = null;
+      try {
+        moduleCore = StructureEdit.getStructureEditForWrite(project);
+        if (moduleCore != null){
+          WorkbenchComponent component = moduleCore.getComponent();
+          if (component != null) {
+            component.setName(deployedName);
+            moduleCore.saveIfNecessary(null);
+          }
+        }
+      } finally {
+        if (moduleCore != null) {
+          moduleCore.dispose();
+        }
+      }
+    }  
+  }
+
+  /**
+   * Link a project's file to a specific deployment destination. Existing links will be deleted beforehand. 
+   * @param project 
+   * @param sourceFile the existing file to deploy
+   * @param targetRuntimePath the target runtime/deployment location of the file
+   * @param monitor
+   * @throws CoreException
+   */
+  protected void linkFileFirst(IProject project, String sourceFile, String targetRuntimePath, IProgressMonitor monitor) throws CoreException {
+      IPath runtimePath = new Path(targetRuntimePath);
+      //We first delete any existing links
+      WTPProjectsUtil.deleteLinks(project, runtimePath, monitor);
+      if (sourceFile != null) {
+        //Create the new link
+        WTPProjectsUtil.insertLinkFirst(project, new Path(sourceFile), new Path(targetRuntimePath), monitor);
+      }
+  }
+
+  @Deprecated
+  protected boolean hasChanged(IVirtualReference[] existingRefs, IVirtualReference[] refArray) {
+      return WTPProjectsUtil.hasChanged(existingRefs, refArray);
+  }
+
+  @Override
+public void configureClasspath(IProject project, MavenProject mavenProject, IClasspathDescriptor classpath,
+      IProgressMonitor monitor) throws CoreException {
+    // do nothing
+  }
+
+  @Override
+public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+    // do nothing
+  }
+  
+  protected void addFoldersToClean(ResourceCleaner fileCleaner, IMavenProjectFacade facade) {
+    for (IPath p : facade.getCompileSourceLocations()) {
+      if (p != null) {
+        fileCleaner.addFiles(p.append("META-INF/MANIFEST.MF")); //$NON-NLS-1$
+        fileCleaner.addFolder(p);
+      }
+    }
+    for (IPath p : facade.getResourceLocations()) {
+      if (p != null) {
+        fileCleaner.addFiles(p.append("META-INF/MANIFEST.MF")); //$NON-NLS-1$
+        fileCleaner.addFolder(p);
+      }
+    }
+    // add default resource folder
+    IPath defaultResource = new Path("src/main/resources"); //$NON-NLS-1$
+    fileCleaner.addFiles(defaultResource.append("META-INF/MANIFEST.MF")); //$NON-NLS-1$
+    fileCleaner.addFolder(defaultResource);
+    
+    for (IPath p : facade.getTestCompileSourceLocations()) {
+      if (p != null) fileCleaner.addFolder(p);
+    }
+    for (IPath p : facade.getTestResourceLocations()) {
+      if (p != null) fileCleaner.addFolder(p);
+    }
+  }
+  
+  /**
+   * Add inclusion/exclusion patterns to .component metadata. WTP server adapters can use that information to 
+   * include/exclude resources from deployment accordingly. This is currently implemented in the JBoss AS server adapter.
+   * @throws CoreException 
+   */
+  protected void addComponentExclusionPatterns(IVirtualComponent component, IMavenPackageFilter filter)  {
+    String[] warSourceIncludes = filter.getSourceIncludes();
+    String[] packagingIncludes = filter.getPackagingIncludes();
+    String[] warSourceExcludes = filter.getSourceExcludes();
+    String[] packagingExcludes = filter.getPackagingExcludes();
+    
+    if (warSourceIncludes.length > 0 && packagingIncludes.length >0) {
+      IResource pomFile = component.getProject().getFile(IMavenConstants.POM_FILE_NAME);
+      // We might get bad pattern overlapping (**/* + **/*.html would return everything, 
+      // when maven would only package html files) . 
+      // So we arbitrary (kinda) keep the packaging patterns only. But this can lead to other funny discrepancies 
+      // things like **/pages/** + **/*.html should return only html files from the pages directory, but here, will return
+      // every html files.
+      SourceLocation sourceLocation = filter.getSourceLocation();
+      if (sourceLocation != null) {
+        mavenMarkerManager.addMarker(pomFile, 
+                                   MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID,
+                                   NLS.bind(Messages.markers_inclusion_patterns_problem, filter.getSourceIncludeParameterName()), 
+                                   sourceLocation.getLineNumber(), 
+                                   IMarker.SEVERITY_WARNING);
+      }
+      warSourceIncludes = null;
+    }
+    String componentInclusions = joinAsString(warSourceIncludes, packagingIncludes);
+    String componentExclusions = joinAsString(warSourceExcludes, packagingExcludes);
+    Properties props = component.getMetaProperties();
+    if (!componentInclusions.equals(props.getProperty(MavenWtpConstants.COMPONENT_INCLUSION_PATTERNS, ""))) { //$NON-NLS-1$
+      component.setMetaProperty(MavenWtpConstants.COMPONENT_INCLUSION_PATTERNS, componentInclusions);
+    }
+    if (!componentExclusions.equals(props.getProperty(MavenWtpConstants.COMPONENT_EXCLUSION_PATTERNS, ""))) { //$NON-NLS-1$
+      component.setMetaProperty(MavenWtpConstants.COMPONENT_EXCLUSION_PATTERNS, componentExclusions);
+    }
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AcrPluginConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AcrPluginConfiguration.java
new file mode 100644
index 0000000..11e6855
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AcrPluginConfiguration.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.MavenProjectUtils;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * maven-acr-plugin (application client maven plugin) configuration model.
+ *
+ * @see <a href="http://maven.apache.org/plugins/maven-acr-plugin/acr-mojo.html">http://maven.apache.org/plugins/maven-acr-plugin/acr-mojo.html</a>
+ *
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class AcrPluginConfiguration extends AbstractFilteringSupportMavenPlugin {
+  
+  private static final IProjectFacetVersion DEFAULT_APPCLIENT_FACET_VERSION = IJ2EEFacetConstants.APPLICATION_CLIENT_50;
+  
+  private static final int JEE_7_0_ID = 70;
+
+  private static final Logger LOG = LoggerFactory.getLogger(AcrPluginConfiguration.class);
+  
+  final IMavenProjectFacade mavenProjectFacade;
+
+  public AcrPluginConfiguration(IMavenProjectFacade facade) throws CoreException {
+
+    MavenProject mavenProject = facade.getMavenProject(new NullProgressMonitor());
+    if (JEEPackaging.APP_CLIENT != JEEPackaging.getValue(mavenProject.getPackaging())) {
+    	throw new IllegalArgumentException(Messages.AcrPluginConfiguration_Error_Project_Not_appclient);
+    }
+    
+    this.mavenProjectFacade = facade;
+    Plugin plugin = mavenProject.getPlugin("org.apache.maven.plugins:maven-acr-plugin"); //$NON-NLS-1$
+    if (plugin != null) {
+      setConfiguration((Xpp3Dom) plugin.getConfiguration()); 
+    }
+  }
+
+  public IProjectFacetVersion getFacetVersion() {
+    IFile applicationClientXml = getApplicationClientXml();
+
+    if(applicationClientXml != null && applicationClientXml.isAccessible()) {
+      try {
+        InputStream is = applicationClientXml.getContents();
+        try {
+          JavaEEQuickPeek jqp = new JavaEEQuickPeek(is);
+          switch(jqp.getVersion()) {
+            case J2EEVersionConstants.J2EE_1_2_ID:
+              return IJ2EEFacetConstants.APPLICATION_CLIENT_12;
+            case J2EEVersionConstants.J2EE_1_3_ID:
+              return IJ2EEFacetConstants.APPLICATION_CLIENT_13;
+            case J2EEVersionConstants.J2EE_1_4_ID:
+              return IJ2EEFacetConstants.APPLICATION_CLIENT_14;
+            case J2EEVersionConstants.JEE_5_0_ID:
+              return IJ2EEFacetConstants.APPLICATION_CLIENT_50;
+            case J2EEVersionConstants.JEE_6_0_ID:
+              return IJ2EEFacetConstants.APPLICATION_CLIENT_60;
+            case JEE_7_0_ID:
+            	//This can only happen when run in WTP >= 3.5
+            	//Don't use/create a static 1.7 facet version, it'd blow up WTP < 3.5
+                return IJ2EEFacetConstants.APPLICATION_CLIENT_FACET.getVersion("7.0"); //$NON-NLS-1$
+          }
+        } finally {
+          is.close();
+        }
+      } catch(IOException ex) {
+        // expected
+      } catch(CoreException ex) {
+        // expected
+      }
+    }
+   
+    IProject project = mavenProjectFacade.getProject();
+    //If no application-client.xml found, don't change existing facet version
+    try {
+        IFacetedProject fProject = ProjectFacetsManager.create(project);
+        if (fProject != null && fProject.hasProjectFacet(IJ2EEFacetConstants.APPLICATION_CLIENT_FACET)) {
+          return fProject.getProjectFacetVersion(IJ2EEFacetConstants.APPLICATION_CLIENT_FACET);
+        }
+    } catch (Exception e) {
+        LOG.warn(NLS.bind(Messages.Error_Reading_Project_Facet, project.getName()), e); 
+    }      
+
+    
+    //If no application-client.xml found and the project depends on some java EE 6 jar then set application client facet to 6.0
+    //FIXME this is totally arbitrary. Need to find a better solution.
+    if (WTPProjectsUtil.hasInClassPath(mavenProjectFacade.getProject(), "javax.servlet.annotation.WebServlet")) { //$NON-NLS-1$
+      return IJ2EEFacetConstants.APPLICATION_CLIENT_60;
+    }
+    
+    return DEFAULT_APPCLIENT_FACET_VERSION; 
+  }
+  
+  /**
+   * @return the first application-client.xml file found under META-INF, in all the resource folders.
+   */
+  public IFile getApplicationClientXml() {
+    IProject project = mavenProjectFacade.getProject();
+    String contentDir = null;
+    for (IPath path : mavenProjectFacade.getResourceLocations()) {
+      contentDir = path.toPortableString()+"/META-INF"; //$NON-NLS-1$
+      IFile applicationClientXml = project.getFolder(contentDir).getFile("application-client.xml"); //$NON-NLS-1$
+      if (applicationClientXml.exists()) {
+        return applicationClientXml;
+      }
+    }
+    return null;
+  }
+  
+  /**
+   * @return the first resource location directory declared in pom.xml
+   */
+  public String getContentDirectory(IProject project) {
+    IPath[] resources = MavenProjectUtils.getResourceLocations(project, mavenProjectFacade.getMavenProject().getResources());
+    return resources[0].toPortableString();
+  }
+  
+  @Override
+protected String getFilteringAttribute() {
+    return "filterDeploymentDescriptor"; //$NON-NLS-1$
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AppClientProjectConfiguratorDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AppClientProjectConfiguratorDelegate.java
new file mode 100644
index 0000000..8a4a15a
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/AppClientProjectConfiguratorDelegate.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeConflictingFacets;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jst.j2ee.project.facet.AppClientFacetInstallDataModelProvider;
+import org.eclipse.jst.j2ee.project.facet.IAppClientFacetInstallDataModelProperties;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetInstallDataModelProperties;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+
+/**
+ *  Configures Application Client projects based on their maven-acr-plugin configuration.
+ * 
+ * @author Fred Bricon
+ */
+class AppClientProjectConfiguratorDelegate extends AbstractProjectConfiguratorDelegate {
+
+  @Override
+protected void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+   
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
+
+    Set<Action> actions = new LinkedHashSet<>();
+    installJavaFacet(actions, project, facetedProject);
+
+    IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project.getFile(IMavenConstants.POM_FILE_NAME), true, monitor);
+    //Reading content directory, used by WTP to create META-INF/manifest.mf, application-client.xml
+    AcrPluginConfiguration config = new AcrPluginConfiguration(facade);
+    String contentDir = config.getContentDirectory(project);
+    IProjectFacetVersion fv = config.getFacetVersion();
+    
+    if(!facetedProject.hasProjectFacet(WTPProjectsUtil.APP_CLIENT_FACET)) {
+      removeConflictingFacets(facetedProject, fv, actions);
+      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, fv, getAppClientDataModel(contentDir)));
+    } else {
+      IProjectFacetVersion projectFacetVersion = facetedProject.getProjectFacetVersion(WTPProjectsUtil.APP_CLIENT_FACET);     
+      if(fv.getVersionString() != null && !fv.getVersionString().equals(projectFacetVersion.getVersionString())){
+          actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, fv, getAppClientDataModel(contentDir)));
+      } 
+    }
+
+    if(!actions.isEmpty()) {
+      ResourceCleaner fileCleaner = new ResourceCleaner(project);
+      try {
+        addFoldersToClean(fileCleaner, facade);
+        
+        facetedProject.modify(actions, monitor);
+      } finally {
+        //Remove any unwanted MANIFEST.MF the Facet installation has created
+        fileCleaner.cleanUp();
+      }
+    }
+
+    //Add the moduleCoreNature, in case it's missing 
+    fixMissingModuleCoreNature(project, monitor);
+    
+    //Remove test folder links to prevent exporting them when packaging the project
+    removeTestFolderLinks(project, mavenProject, monitor, "/"); //$NON-NLS-1$
+    
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    if (component != null) {
+      IPath contentDirPath = new Path("/").append(contentDir); //$NON-NLS-1$
+      WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(component.getRootFolder(), contentDirPath, monitor);
+    }
+    
+    //Remove "library unavailable at runtime" warning.
+    setNonDependencyAttributeToContainer(project, monitor);
+    
+    //Remove WTP classpath libraries conflicting with the Maven one
+    WTPProjectsUtil.removeWTPClasspathContainer(project);
+}
+
+  private IDataModel getAppClientDataModel(String contentDir) {
+    IDataModel appClientModelCfg = DataModelFactory.createDataModel(new AppClientFacetInstallDataModelProvider());
+    appClientModelCfg.setProperty(IAppClientFacetInstallDataModelProperties.CONFIG_FOLDER, contentDir);
+    appClientModelCfg.setProperty(IAppClientFacetInstallDataModelProperties.CREATE_DEFAULT_MAIN_CLASS, false);
+    appClientModelCfg.setProperty(IJ2EEFacetInstallDataModelProperties.GENERATE_DD, false);
+    appClientModelCfg.setBooleanProperty(IAppClientFacetInstallDataModelProperties.ADD_TO_EAR, false);    
+    return appClientModelCfg;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ArtifactHelper.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ArtifactHelper.java
new file mode 100644
index 0000000..8d9d462
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ArtifactHelper.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.util.Collection;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.embedder.ArtifactKey;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.jdt.internal.BuildPathManager;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
+
+/**
+ * Helper for Maven artifacts
+ *
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+//XXX Should probably be refactored to another Maven helper class.
+@SuppressWarnings("restriction")
+public class ArtifactHelper {
+
+  private static final String M2_REPO_PREFIX = VirtualArchiveComponent.VARARCHIVETYPE + IPath.SEPARATOR
+  + BuildPathManager.M2_REPO + IPath.SEPARATOR;
+
+  /**
+   * Returns an artifact's path relative to the local repository
+   */
+  //XXX Does maven API provide that kind of feature? 
+  public static IPath getLocalRepoRelativePath(Artifact artifact) {
+    if (artifact == null) {
+      throw new IllegalArgumentException(Messages.ArtifactHelper_Error_Artifact_Must_Not_Be_Null);
+    }
+    
+    IPath m2repo = JavaCore.getClasspathVariable(BuildPathManager.M2_REPO); //always set
+    IPath absolutePath = new Path(artifact.getFile().getAbsolutePath());
+    IPath relativePath = absolutePath.removeFirstSegments(m2repo.segmentCount()).makeRelative().setDevice(null);
+    return relativePath;
+  }
+  
+  /**
+   * Returns an IProject from a maven artifact
+   * @param artifact
+   * @return an IProject if the artifact is a workspace project or null
+   */
+  public static IProject getWorkspaceProject(Artifact artifact) {
+    IMavenProjectFacade facade = getWorkspaceProjectMavenFacade(artifact);
+    return (facade == null)?null:facade.getProject();
+  }
+
+  /**
+   * Returns an IMavenProjectFacade from a maven artifact
+   * @param artifact
+   * @return an IMavenProjectFacade if the artifact is a workspace project or null
+   */
+  public static IMavenProjectFacade getWorkspaceProjectMavenFacade(Artifact artifact) {
+    IMavenProjectFacade workspaceProject = MavenPlugin.getMavenProjectRegistry()
+    .getMavenProject(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
+
+    if(workspaceProject != null && workspaceProject.getFullPath(artifact.getFile()) != null) {
+      return workspaceProject;
+    }
+    return null;
+  }
+
+  /**
+   * Returns the M2_REPO variable path for an artifact. ex : var/M2_REPO/groupid/artifactid/version/filename
+   * @param artifact
+   * @return the M2_REPO variable path for the artifact, null if the artifact is a workspace project
+   */
+  public static String getM2REPOVarPath(Artifact artifact)
+  {
+    if (getWorkspaceProject(artifact) != null)
+    {
+     return null; 
+    }
+    return M2_REPO_PREFIX + ArtifactHelper.getLocalRepoRelativePath(artifact).toPortableString();
+  }
+
+  /**
+   * Temporary fix for app-client type artifacts, where the artifactHandler is not correctly loaded 
+   * thus the extension and the addtoclasspath value are incorrect.
+   * @param artifactHandler
+   */
+  @Deprecated
+  public static void fixArtifactHandler(ArtifactHandler artifactHandler) {
+	  if ("app-client".equals(artifactHandler.getExtension()) && artifactHandler instanceof DefaultArtifactHandler) { //$NON-NLS-1$
+		  ((DefaultArtifactHandler)artifactHandler).setExtension("jar"); //$NON-NLS-1$
+		  ((DefaultArtifactHandler)artifactHandler).setAddedToClasspath(true);
+	  }
+  }
+  
+  public static Artifact getArtifact(Collection<Artifact> artifacts, ArtifactKey key) {
+    if (artifacts == null || key == null || artifacts.isEmpty()) {
+      return null;
+    }
+    for (Artifact a : artifacts) {
+      ArtifactKey ak = toArtifactKey(a);
+      if (key.equals(ak)) {
+        return a;
+      }
+    }
+    return null;
+  }
+  
+  /**
+   * Gets an ArtifactKey from an Artifact. This method fixes the flawed ArtifactKey(Artifact a) constructor
+   * which doesn't copy the artifact classifier; 
+   */
+  public static ArtifactKey toArtifactKey(Artifact a) {
+    return new ArtifactKey(a.getGroupId(), a.getArtifactId(), a.getBaseVersion(), a.getClassifier());
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ConnectorProjectConfiguratorDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ConnectorProjectConfiguratorDelegate.java
new file mode 100644
index 0000000..84cda81
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ConnectorProjectConfiguratorDelegate.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2014 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeConflictingFacets;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jst.j2ee.jca.project.facet.ConnectorFacetInstallDataModelProvider;
+import org.eclipse.jst.j2ee.jca.project.facet.IConnectorFacetInstallDataModelProperties;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.MavenProjectUtils;
+import org.eclipse.m2e.wtp.namemapping.FileNameMappingFactory;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * Configures Connector (RAR) projects based on their maven-rar-plugin configuration.
+ *
+ * @author Fred Bricon
+ */
+class ConnectorProjectConfiguratorDelegate extends AbstractProjectConfiguratorDelegate{
+
+  public static final ArtifactFilter SCOPE_FILTER_RUNTIME = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME);
+
+  /* (non-Javadoc)
+   * @see org.eclipse.m2e.wtp.AbstractProjectConfiguratorDelegate#configure(org.eclipse.core.resources.IProject, org.apache.maven.project.MavenProject, org.eclipse.core.runtime.IProgressMonitor)
+   */
+  @Override
+protected void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException {
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
+    if (facetedProject == null) {
+      return;
+    }
+
+    Set<Action> actions = new LinkedHashSet<>();
+    installJavaFacet(actions, project, facetedProject);
+
+    IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project, monitor);
+    RarPluginConfiguration config = new RarPluginConfiguration(facade);
+    
+    String contentDir = config.getRarContentDirectory();
+
+    IProjectFacetVersion connectorFv = config.getConnectorFacetVersion();
+
+    IDataModel rarModelCfg = DataModelFactory.createDataModel(new ConnectorFacetInstallDataModelProvider());
+
+    IFolder contentFolder = project.getFolder(contentDir);
+    if(!facetedProject.hasProjectFacet(WTPProjectsUtil.JCA_FACET)) {
+
+      // Configuring content directory, used by WTP to create META-INF/manifest.mf, ra.xml
+     
+      rarModelCfg.setProperty(IConnectorFacetInstallDataModelProperties.CONFIG_FOLDER, contentDir);
+      //Don't generate ra.xml by default - Setting will be ignored for JCA 1.6
+      rarModelCfg.setProperty(IConnectorFacetInstallDataModelProperties.GENERATE_DD, false);
+      rarModelCfg.setBooleanProperty(IConnectorFacetInstallDataModelProperties.ADD_TO_EAR, false);
+
+      removeConflictingFacets(facetedProject, connectorFv, actions);
+
+      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, connectorFv, rarModelCfg));
+    } else {
+      IProjectFacetVersion projectFacetVersion = facetedProject.getProjectFacetVersion(WTPProjectsUtil.JCA_FACET);     
+      
+      if(projectFacetVersion.getVersionString() != null && !projectFacetVersion.getVersionString().equals(projectFacetVersion.getVersionString())){
+
+        removeConflictingFacets(facetedProject, connectorFv, actions);
+
+        actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, connectorFv, rarModelCfg));
+      } 
+    }
+    String customRaXml = config.getCustomRaXml();
+    
+    if(!actions.isEmpty()) {
+      ResourceCleaner fileCleaner = new ResourceCleaner(project);
+      try {
+        addFoldersToClean(fileCleaner, facade);
+        fileCleaner.addFiles(contentFolder.getFile("META-INF/MANIFEST.MF").getProjectRelativePath()); //$NON-NLS-1$
+        if (customRaXml != null) {
+          fileCleaner.addFiles(contentFolder.getFile("META-INF/ra.xml").getProjectRelativePath()); //$NON-NLS-1$
+        }
+        
+        facetedProject.modify(actions, monitor);
+      } finally {
+        //Remove any unwanted MANIFEST.MF the Facet installation has created
+        fileCleaner.cleanUp();
+      }
+    }
+
+    //MECLIPSEWTP-41 Fix the missing moduleCoreNature
+    fixMissingModuleCoreNature(project, monitor);
+    
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    if (component != null) {
+
+      if (config.isJarIncluded()) {
+        addSourceLinks(component, mavenProject, monitor);
+      } else {
+        //project classes won't be jar'ed in the resulting rar.
+        removeSourceLinks(component, mavenProject, monitor);
+      }
+      
+      removeTestFolderLinks(project, mavenProject, monitor, "/");  //$NON-NLS-1$
+      
+      linkFileFirst(project, customRaXml, "META-INF/ra.xml", monitor); //$NON-NLS-1$
+
+      IPath contentDirPath = new Path("/").append(contentDir); //$NON-NLS-1$
+      
+      if (!WTPProjectsUtil.hasLink(project, ROOT_PATH, contentDirPath, monitor)) {
+        component.getRootFolder().createLink(contentDirPath, IVirtualResource.NONE, monitor); 
+      }
+      
+      WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(component.getRootFolder(), contentDirPath, monitor);
+    }
+
+    setNonDependencyAttributeToContainer(project, monitor);
+
+    //Remove "library unavailable at runtime" warning. TODO is it relevant for connector projects?
+    WTPProjectsUtil.removeWTPClasspathContainer(project);
+    
+    setModuleDependencies(project, mavenProject, monitor);
+    
+  }
+
+  private void addSourceLinks(IVirtualComponent component, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException {
+    IProject project = component.getProject();
+    IPath classesPath = MavenProjectUtils.getProjectRelativePath(project, mavenProject.getBuild().getOutputDirectory());
+    if (classesPath != null) {
+      for(IPath location : MavenProjectUtils.getSourceLocations(project, mavenProject.getCompileSourceRoots())) {
+        addLinkIfNecessary(component, location, monitor);
+      }
+      for(IPath location : MavenProjectUtils.getResourceLocations(project, mavenProject.getResources())) {
+        addLinkIfNecessary(component, location, monitor);
+      }
+    }
+  }
+
+  private void addLinkIfNecessary(IVirtualComponent component, IPath location, IProgressMonitor monitor) throws CoreException {
+    IProject project = component.getProject();
+    if (location!=null && !WTPProjectsUtil.hasLink(project, ROOT_PATH, location, monitor)) {
+      if (project.getFolder(location).isAccessible()) {
+        component.getRootFolder().createLink(location, IVirtualResource.NONE, monitor); 
+      }
+    }
+  }
+
+  
+  
+  private void removeSourceLinks(IVirtualComponent component, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException {
+      IVirtualFolder jsrc = component.getRootFolder();
+      IProject project = component.getProject();
+      for(IPath location : MavenProjectUtils.getSourceLocations(project, mavenProject.getCompileSourceRoots())) {
+        jsrc.removeLink(location, 0, monitor);
+      }
+      for(IPath location : MavenProjectUtils.getResourceLocations(project, mavenProject.getResources())) {
+        jsrc.removeLink(location, 0, monitor);
+      }
+  }
+  
+
+  
+  /**
+   * @see org.eclipse.m2e.wtp.IProjectConfiguratorDelegate#setModuleDependencies(org.eclipse.core.resources.IProject, org.apache.maven.project.MavenProject, org.eclipse.core.runtime.IProgressMonitor)
+   */
+  @Override
+public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+
+    IVirtualComponent rarComponent = ComponentCore.createComponent(project);
+    
+    Set<IVirtualReference> newRefs = new LinkedHashSet<>();
+    
+    Set<Artifact> artifacts =  mavenProject.getArtifacts();
+    
+    //Adding artifact references in .component. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=297777#c1
+    for(Artifact artifact : artifacts) {
+    	ArtifactHelper.fixArtifactHandler(artifact.getArtifactHandler());
+      //Don't deploy pom, non runtime or optional dependencies
+      if("pom".equals(artifact.getType()) || !SCOPE_FILTER_RUNTIME.include(artifact) || artifact.isOptional()) { //$NON-NLS-1$
+        continue;
+      }
+      
+      IMavenProjectFacade workspaceDependency = projectManager.getMavenProject(artifact.getGroupId(), artifact
+          .getArtifactId(), artifact.getVersion());
+
+      if(workspaceDependency != null && !workspaceDependency.getProject().equals(project)
+          && workspaceDependency.getFullPath(artifact.getFile()) != null) {
+        //artifact dependency is a workspace project
+        IProject depProject = preConfigureDependencyProject(workspaceDependency, monitor);
+        if (ModuleCoreNature.isFlexibleProject(depProject)) {
+          newRefs.add(createReference(rarComponent, depProject, artifact));
+        }
+      } else {
+        //artifact dependency should be added as a JEE module, referenced with M2_REPO variable 
+        newRefs.add(createReference(rarComponent, artifact));
+      }
+    }
+
+    IVirtualReference[] newRefsArray = new IVirtualReference[newRefs.size()];
+    newRefs.toArray(newRefsArray);
+    
+    //Only change the project references if they've changed
+    IVirtualReference[] references = WTPProjectsUtil.extractHardReferences(rarComponent, false);
+    if (WTPProjectsUtil.hasChanged(references, newRefsArray)) {
+      rarComponent.setReferences(newRefsArray);
+    }
+  }
+
+  private IVirtualReference createReference(IVirtualComponent rarComponent, IProject project, Artifact artifact) {
+    IVirtualComponent depComponent = ComponentCore.createComponent(project);
+    IVirtualReference depRef = ComponentCore.createReference(rarComponent, depComponent);
+    String deployedFileName = FileNameMappingFactory.getDefaultFileNameMapping().mapFileName(artifact);
+    depRef.setArchiveName(deployedFileName);
+    return depRef;
+  }
+  
+  private IVirtualReference createReference(IVirtualComponent rarComponent, Artifact artifact) {
+      //Create dependency component, referenced from the local Repo.
+      String artifactPath = ArtifactHelper.getM2REPOVarPath(artifact);
+      IVirtualComponent depComponent = ComponentCore.createArchiveComponent(rarComponent.getProject(), artifactPath);
+      return ComponentCore.createReference(rarComponent, depComponent);
+  }
+
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/DeploymentDescriptorManagement.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/DeploymentDescriptorManagement.java
new file mode 100644
index 0000000..9ba4bfa
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/DeploymentDescriptorManagement.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Management of EAR deployment descriptors
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public interface DeploymentDescriptorManagement {
+
+  static final DeploymentDescriptorManagement INSTANCE = new MavenDeploymentDescriptorManagement();
+  
+  void updateConfiguration(IProject project, MavenProject mavenProject, EarPluginConfiguration plugin, boolean useBuildDirectory, IProgressMonitor monitor) throws CoreException;
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/DomUtils.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/DomUtils.java
new file mode 100644
index 0000000..5f0eb09
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/DomUtils.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.runtime.Assert;
+
+/**
+ * Utility class for {@link Xpp3Dom} manipulations.
+ * 
+ * @provisional This class has been added as part of a work in progress. It is not guaranteed to work or remain the same
+ *              in future releases. For more information contact <a
+ *              href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * @author Fred Bricon
+ */
+public class DomUtils {
+
+  /**
+   * Return the value of a child node.
+   * 
+   * @param parent - the parent node.
+   * @param childName - the child node name.
+   * @return the child node value or null if it doesn't exist.
+   */
+  public static final String getChildValue(Xpp3Dom parent, String childName) {
+    String result = null;
+    if(parent != null && childName != null) {
+      Xpp3Dom dom = parent.getChild(childName);
+      if(dom != null && dom.getValue() != null) {//MNGECLIPSE-2328 add null-safety in case of <somenode/> 
+        result = dom.getValue().trim();
+      }
+    }
+    return result;
+  }
+
+  public static final String getChildValue(Xpp3Dom parent, String childName, String defaultValue) {
+    String result = getChildValue(parent, childName);
+    return StringUtils.defaultString(result, defaultValue);
+  }
+
+  public static final boolean getBooleanChildValue(Xpp3Dom parent, String childName) {
+    return Boolean.valueOf(getChildValue(parent, childName));
+  }
+
+  public static final boolean getBooleanChildValue(Xpp3Dom parent, String childName, boolean defaultValue) {
+	  String result = getChildValue(parent, childName);
+	  if (result == null) {
+		  return defaultValue;
+	  }
+	  return Boolean.valueOf(result);
+  }
+
+  /**
+   * @param node
+   */
+  public static final void removeChildren(Xpp3Dom node) {
+    if(node == null)
+      return;
+    for(int i = node.getChildCount() - 1; i > -1; i-- ) {
+      node.removeChild(i);
+    }
+  }
+
+  public static String[] getChildrenAsStringArray(Xpp3Dom root, String childName) {
+    String[] values = null;
+    if(root != null) {
+      Xpp3Dom[] children = root.getChildren(childName);
+      if(children != null) {
+        values = new String[children.length];
+        int i = 0;
+        for(Xpp3Dom child : children) {
+          values[i++ ] = child.getValue();
+        }
+      }
+    }
+    return values;
+  }
+
+  public static String[] getPatternsAsArray(Xpp3Dom config, String patternParameterName) {
+    if(config != null) {
+      Xpp3Dom excl = config.getChild(patternParameterName);
+      if(excl != null && excl.getValue() != null) {
+        return org.eclipse.m2e.wtp.internal.StringUtils.tokenizeToStringArray(excl.getValue(), ","); //$NON-NLS-1$
+      }
+    }
+    return new String[0];
+  }
+
+  public static final Xpp3Dom getOrCreateChildNode(Xpp3Dom parent, String childName) {
+    Assert.isNotNull(parent);
+    Assert.isNotNull(childName);
+    Xpp3Dom dom = parent.getChild(childName);
+    if(dom == null) {
+      dom = new Xpp3Dom(childName);
+      parent.addChild(dom);
+    }
+    return dom;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EarPluginConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EarPluginConfiguration.java
new file mode 100644
index 0000000..78cc227
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EarPluginConfiguration.java
@@ -0,0 +1,444 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2012 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.core.internal.markers.SourceLocation;
+import org.eclipse.m2e.core.internal.markers.SourceLocationHelper;
+import org.eclipse.m2e.wtp.earmodules.ArtifactTypeMappingService;
+import org.eclipse.m2e.wtp.earmodules.EarModule;
+import org.eclipse.m2e.wtp.earmodules.EarModuleFactory;
+import org.eclipse.m2e.wtp.earmodules.EarPluginException;
+import org.eclipse.m2e.wtp.earmodules.SecurityRoleKey;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.namemapping.AbstractFileNameMapping;
+import org.eclipse.m2e.wtp.namemapping.FileNameMapping;
+import org.eclipse.m2e.wtp.namemapping.FileNameMappingFactory;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * maven-ear-plugin configuration model.
+ * 
+ * @see http://maven.apache.org/plugins/maven-ear-plugin/
+ * @see http://maven.apache.org/plugins/maven-ear-plugin/modules.html
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class EarPluginConfiguration extends AbstractFilteringSupportMavenPlugin implements IMavenPackageFilter {
+
+  private static final Logger LOG = LoggerFactory.getLogger(EarPluginConfiguration.class);
+
+  //Careful : This has a different meaning from the default library directory (/lib)
+  private static final String EAR_DEFAULT_BUNDLE_DIR = "/";  //$NON-NLS-1$
+
+  private static final String EAR_DEFAULT_CONTENT_DIR = "src/main/application"; // J2EEConstants.EAR_DEFAULT_LIB_DIR //$NON-NLS-1$
+
+  // Default EAR version produced by the maven-ear-plugin
+  private static final IProjectFacetVersion DEFAULT_EAR_FACET = IJ2EEFacetConstants.ENTERPRISE_APPLICATION_13;
+
+  private final MavenProject mavenProject;
+
+  /**
+   * directory where jars will be deployed.
+   */
+  private String libDirectory;
+
+  // private String contentDirectory;
+
+  // XXX see if Lazy loading / caching the different factories and services is relevant.
+  private ArtifactTypeMappingService typeMappingService;
+
+  private Set<EarModule>  earModules;
+  
+  private boolean supportsUseBaseVersion = false;
+  
+  public EarPluginConfiguration(MavenProject mavenProject) {
+    if(JEEPackaging.EAR != JEEPackaging.getValue(mavenProject.getPackaging())) {
+      throw new IllegalArgumentException(Messages.EarPluginConfiguration_Project_Must_Have_ear_Packaging);
+    }
+
+    this.mavenProject = mavenProject;
+    Plugin plugin = getPlugin();
+    try {
+    	VersionRange ear_2_9 = VersionRange.createFromVersionSpec("[2.9,)"); //$NON-NLS-1$
+    	if(ear_2_9.containsVersion(new DefaultArtifactVersion(plugin.getVersion()))) {
+    		supportsUseBaseVersion = true;
+    	}
+    } catch(Exception ex) {
+        //Can't happen
+    }
+    
+    setConfiguration((Xpp3Dom)plugin.getConfiguration());
+  }
+
+  public Plugin getPlugin() {
+    return mavenProject.getPlugin("org.apache.maven.plugins:maven-ear-plugin"); //$NON-NLS-1$
+  }
+
+
+  /**
+   * Gets an IProjectFacetVersion version from maven-ear-plugin configuration.
+   * 
+   * @return the facet version of the project, Maven defaults to (Java EE) 1.3
+   */
+  public IProjectFacetVersion getEarFacetVersion() {
+    Xpp3Dom config = getConfiguration();
+    if(config == null) {
+      return DEFAULT_EAR_FACET;
+    }
+
+    Xpp3Dom domVersion = config.getChild("version"); //$NON-NLS-1$
+    if(domVersion != null) {
+      String sVersion = domVersion.getValue();
+      try {
+        double version = Double.parseDouble(sVersion); // transforms version 5 to 5.0
+        sVersion = Double.toString(version);
+        try {
+          return IJ2EEFacetConstants.ENTERPRISE_APPLICATION_FACET.getVersion(sVersion);
+        } catch (Exception e) {
+          //If Ear Version > 5.0 and WTP < 3.2, downgrade to Ear facet 5.0
+          LOG.warn(e.getMessage());
+          if (version > 5.0){
+            return IJ2EEFacetConstants.ENTERPRISE_APPLICATION_FACET.getVersion("5.0"); //$NON-NLS-1$
+          }
+        }
+        } catch(NumberFormatException nfe) {
+        LOG.error(NLS.bind(Messages.EarPluginConfiguration_Error_Reading_EAR_Version,sVersion), nfe);
+        return DEFAULT_EAR_FACET;
+      }
+    }
+    return DEFAULT_EAR_FACET;
+  }
+
+  /**
+   * Gets the ear content directory of the project from pom.xml configuration.
+   * 
+   *  @return the contents of the earSourceDirectory element. If earSourceDirectory is not specified
+   *          in pom.xml, the default value src/main/application is returned. 
+   */
+  public String getEarContentDirectory(IProject project) {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom contentDirDom = config.getChild("earSourceDirectory"); //$NON-NLS-1$
+      if(contentDirDom != null && contentDirDom.getValue() != null) {
+        String contentDir = contentDirDom.getValue().trim();
+        
+        //MNGECLIPSE-1600 fixed absolute earSourceDirectory
+        if(project != null) {
+          IPath projectLocationPath = project.getLocation();
+          if(projectLocationPath != null) {
+            String projectLocation = projectLocationPath.toOSString();
+            if(contentDir.startsWith(projectLocation)) {
+              return contentDir.substring(projectLocation.length());
+            }
+          }
+        }
+        contentDir = (contentDir.length() == 0) ? EAR_DEFAULT_CONTENT_DIR : contentDir;
+        return contentDir;
+      }
+    }
+
+    return EAR_DEFAULT_CONTENT_DIR;
+  }
+
+  /**
+   * Return the default bundle directory, where jars will be deployed.
+   */
+  public String getDefaultBundleDirectory() {
+    if(libDirectory == null) {
+      Xpp3Dom config = getConfiguration();
+      if(config != null) {
+        Xpp3Dom libDom = config.getChild("defaultLibBundleDir"); //$NON-NLS-1$
+        if(libDom != null && libDom.getValue() != null) {
+          String libDir = libDom.getValue().trim();
+          libDirectory = (libDir.length() == 0) ? EAR_DEFAULT_BUNDLE_DIR : libDir;
+        }
+      }
+      libDirectory = (libDirectory  == null)?EAR_DEFAULT_BUNDLE_DIR:libDirectory;
+    }
+    return libDirectory;
+  }
+
+  
+  /**
+   * Reads maven-ear-plugin configuration to build a set of EarModule.
+   * 
+   * @see org.apache.maven.plugin.ear.AbstractEarMojo
+   * @return an unmodifiable set of EarModule
+   */
+  public Set<EarModule> getEarModules() throws EarPluginException {
+    if (earModules == null) {
+      //Lazy load modules
+      earModules = collectEarModules();
+      
+      //Remove excluded artifacts 
+      Iterator<EarModule> modulesIterator = earModules.iterator();
+      while (modulesIterator.hasNext())
+      {
+        EarModule module = modulesIterator.next();
+        if (module.isExcluded())
+        {
+          modulesIterator.remove();  
+        }
+      }
+
+      earModules = Collections.unmodifiableSet(earModules);
+    }
+    return earModules;
+  }
+
+  public Set<EarModule> getAllEarModules() throws EarPluginException {
+     return Collections.unmodifiableSet(collectEarModules());
+  }
+
+  private Set<EarModule> collectEarModules() throws EarPluginException {
+    Set<Artifact> artifacts = mavenProject.getArtifacts();
+    if(artifacts == null || artifacts.isEmpty()) {
+      return Collections.<EarModule> emptySet();
+    }
+
+    Set<EarModule> earModules = new LinkedHashSet<>(artifacts.size());
+    String defaultBundleDir = getDefaultBundleDirectory();
+    IProjectFacetVersion javaEEVersion = getEarFacetVersion();
+    EarModuleFactory earModuleFactory = EarModuleFactory.createEarModuleFactory(getArtifactTypeMappingService(),
+        getFileNameMapping(), getMainArtifactId(), artifacts);
+
+    //Resolve Ear modules from plugin config
+    earModules.addAll(getEarModulesFromConfig(earModuleFactory, defaultBundleDir, javaEEVersion)); 
+
+    ScopeArtifactFilter filter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME);
+
+    //next, add remaining modules from maven project dependencies
+    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())) { //$NON-NLS-1$
+        continue;
+      }
+
+      boolean isIncludedInApplicationXml = isIncludeLibInApplicationXml();
+      // Artifact is not yet registered and it has neither test, nor a
+      // provided scope, nor is it optional
+      if(!isArtifactRegistered(artifact, earModules) && filter.include(artifact) && !artifact.isOptional()) {
+        EarModule module = earModuleFactory.newEarModule(artifact, defaultBundleDir, javaEEVersion, isIncludedInApplicationXml);
+        if(module != null) {
+          earModules.add(module);
+        }
+      }
+    }
+    return earModules;
+  }
+
+  private String getMainArtifactId() {
+    // TODO read xml config
+    return "none"; //$NON-NLS-1$
+  }
+
+  private ArtifactTypeMappingService getArtifactTypeMappingService() throws EarPluginException {
+    if(typeMappingService == null) {
+      Xpp3Dom config = getConfiguration();
+      Xpp3Dom artifactTypeMappingConfig = null;
+      if (config != null) {
+        artifactTypeMappingConfig = config.getChild("artifactTypeMappings"); //$NON-NLS-1$
+      }
+      typeMappingService = new ArtifactTypeMappingService(artifactTypeMappingConfig);
+    }
+    return typeMappingService;
+  }
+
+  private FileNameMapping getFileNameMapping() {
+
+    Xpp3Dom config = getConfiguration();
+    FileNameMapping mapping = null;
+    boolean useBaseVersion = !supportsUseBaseVersion;
+    if(config != null) {
+	    Xpp3Dom fileNameMappingDom = config.getChild("fileNameMapping"); //$NON-NLS-1$
+	    if(fileNameMappingDom != null) {
+	      String fileNameMappingName = fileNameMappingDom.getValue().trim();
+	      mapping = FileNameMappingFactory.getFileNameMapping(fileNameMappingName);
+	    }
+	    if (supportsUseBaseVersion) {// for ear-plugin >= 2.9
+	    	useBaseVersion = DomUtils.getBooleanChildValue(config, "useBaseVersion", false); //$NON-NLS-1$
+	    }
+    }
+    if (mapping == null) {
+    	mapping = FileNameMappingFactory.getDefaultFileNameMapping(); 
+    }
+    if (mapping instanceof AbstractFileNameMapping) {
+    	((AbstractFileNameMapping)mapping).setUseBaseVersion(useBaseVersion);
+    }
+    return mapping;
+  }
+
+  /**
+   * Return a set of ear modules defined in maven-ear-plugin configuration.
+   * 
+   * @param earModuleFactory
+   */
+  private Set<EarModule> getEarModulesFromConfig(EarModuleFactory earModuleFactory, String defaultBundleDir, IProjectFacetVersion javaEEVersion) throws EarPluginException {
+    Set<EarModule> earModules = new LinkedHashSet<>();
+    Xpp3Dom configuration = getConfiguration();
+    if(configuration == null) {
+      return earModules;
+    }
+    Xpp3Dom modulesNode = configuration.getChild("modules"); //$NON-NLS-1$
+
+    if(modulesNode == null) {
+      return earModules;
+    }
+
+    Xpp3Dom[] domModules = modulesNode.getChildren();
+    if(domModules == null || domModules.length == 0) {
+      return earModules;
+    }
+    
+    boolean isIncludedInApplicationXml = isIncludeLibInApplicationXml();
+    for(Xpp3Dom domModule : domModules) {
+      EarModule earModule = earModuleFactory.newEarModule(domModule, defaultBundleDir, javaEEVersion, isIncludedInApplicationXml);
+      if(earModule != null) {
+        earModules.add(earModule);
+      }
+    }
+    
+    return earModules;
+  }
+
+  private static boolean isArtifactRegistered(Artifact a, Set<EarModule> modules) {
+    for(EarModule module : modules) {
+      if(module.getArtifact().equals(a)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public boolean isGenerateApplicationXml()  {
+    Xpp3Dom configuration = getConfiguration();
+    if(configuration == null) {
+      return true;
+    }
+    Xpp3Dom generateApplicationXmlNode = configuration.getChild("generateApplicationXml"); //$NON-NLS-1$
+    return (generateApplicationXmlNode == null) || Boolean.parseBoolean(generateApplicationXmlNode.getValue());
+  }
+  
+  public Set<SecurityRoleKey>  getSecurityRoleKeys() {
+    Set<SecurityRoleKey> securityRoles = new HashSet<>();
+    Xpp3Dom configuration = getConfiguration();
+    if(configuration == null) {
+      return securityRoles;
+    }
+    Xpp3Dom securityNode = configuration.getChild("security"); //$NON-NLS-1$
+
+    if(securityNode == null) {
+      return securityRoles;
+    }
+
+    Xpp3Dom[] secRoles = securityNode.getChildren("security-role"); //$NON-NLS-1$
+    if(secRoles == null || secRoles.length == 0) {
+      return securityRoles;
+    }
+    
+    for(Xpp3Dom domSecRole : secRoles) {
+      String id = domSecRole.getAttribute("id"); //$NON-NLS-1$
+      String description = DomUtils.getChildValue(domSecRole, "description"); //$NON-NLS-1$
+      String roleName = DomUtils.getChildValue(domSecRole, "role-name"); //$NON-NLS-1$
+      if (roleName != null)
+      {
+        SecurityRoleKey srk = new SecurityRoleKey();
+        srk.setId(id);
+        srk.setRoleName(roleName);
+        srk.setDescription(description);
+        securityRoles.add(srk);
+      }
+    }
+    
+    return securityRoles;
+  }
+
+  @Override
+  protected String getFilteringAttribute() {
+    return "filtering"; //$NON-NLS-1$
+  }
+
+  public boolean isIncludeLibInApplicationXml() {
+    Xpp3Dom configuration = getConfiguration();
+    if(configuration == null) {
+      return false;
+    }
+    
+    boolean isIncluded = DomUtils.getBooleanChildValue(configuration, "includeLibInApplicationXml"); //$NON-NLS-1$
+    return isIncluded;
+  }
+
+  @Override
+  public String[] getPackagingExcludes() {
+    return DomUtils.getPatternsAsArray(getConfiguration(),"packagingExcludes"); //$NON-NLS-1$
+  }
+
+  @Override
+  public String[] getPackagingIncludes() {
+    return DomUtils.getPatternsAsArray(getConfiguration(),"packagingIncludes"); //$NON-NLS-1$
+  }
+  
+  @Override
+  public String[] getSourceExcludes() {
+    return DomUtils.getPatternsAsArray(getConfiguration(),"earSourceExcludes"); //$NON-NLS-1$
+  }
+
+  @Override
+  public String[] getSourceIncludes() {
+    return DomUtils.getPatternsAsArray(getConfiguration(),"earSourceIncludes"); //$NON-NLS-1$
+  }  
+  
+  @Override
+  public SourceLocation getSourceLocation() {
+    Plugin plugin = getPlugin();
+    if (plugin == null) {
+      return null;
+    }
+    return SourceLocationHelper.findLocation(plugin, "configuration"); //$NON-NLS-1$
+  }
+
+  @Override
+  public String getSourceIncludeParameterName() {
+    return "earSourceIncludes"; //$NON-NLS-1$
+  }
+  
+  public String getFinalName() {
+    String finalName = DomUtils.getChildValue(getConfiguration(), "finalName"); //$NON-NLS-1$
+    if (StringUtils.isEmpty(finalName)) {
+      finalName = mavenProject.getBuild().getFinalName(); 
+    }
+    return finalName;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EarProjectConfiguratorDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EarProjectConfiguratorDelegate.java
new file mode 100644
index 0000000..e6cac6b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EarProjectConfiguratorDelegate.java
@@ -0,0 +1,282 @@
+
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeConflictingFacets;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jst.j2ee.earcreation.IEarFacetInstallDataModelProperties;
+import org.eclipse.jst.j2ee.internal.earcreation.EarFacetInstallDataModelProvider;
+import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
+import org.eclipse.jst.j2ee.model.IEARModelProvider;
+import org.eclipse.jst.j2ee.model.ModelProviderManager;
+import org.eclipse.jst.javaee.application.Application;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.earmodules.EarModule;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.internal.utilities.PathUtil;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Configures EAR projects based on their maven-ear-plugin configuration.
+ * 
+ * @see org.eclipse.jst.j2ee.ui.AddModulestoEARPropertiesPage
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+class EarProjectConfiguratorDelegate extends AbstractProjectConfiguratorDelegate {
+
+  private static final Logger LOG = LoggerFactory.getLogger(EarProjectConfiguratorDelegate.class); 
+
+  @Override
+protected void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+    
+    monitor.setTaskName(NLS.bind(Messages.EarProjectConfiguratorDelegate_Configuring_EAR_Project,project.getName()));
+    
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
+    IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project.getFile(IMavenConstants.POM_FILE_NAME), true, monitor);
+    
+    EarPluginConfiguration config = new EarPluginConfiguration(mavenProject);
+    Set<Action> actions = new LinkedHashSet<>();
+
+    String contentDir = config.getEarContentDirectory(project);
+    contentDir = PathUtil.toPortablePath(contentDir);
+    IFolder contentFolder = project.getFolder(contentDir);
+
+    ResourceCleaner fileCleaner = new ResourceCleaner(project);
+    addFoldersToClean(fileCleaner, facade);
+    fileCleaner.addFiles(contentFolder.getFile("META-INF/application.xml").getProjectRelativePath()); //$NON-NLS-1$
+
+    IProjectFacetVersion earFv = config.getEarFacetVersion();
+    if(!facetedProject.hasProjectFacet(WTPProjectsUtil.EAR_FACET)) {
+      removeConflictingFacets(facetedProject, earFv, actions);
+      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, earFv, getEarModel(contentDir)));
+    } else {
+      //MECLIPSEWTP-37 : don't uninstall the EAR Facet, as it causes constraint failures when used with RAD
+      IProjectFacetVersion projectFacetVersion = facetedProject.getProjectFacetVersion(WTPProjectsUtil.EAR_FACET);     
+      if(earFv.getVersionString() != null && !earFv.getVersionString().equals(projectFacetVersion.getVersionString())){
+          actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, earFv, getEarModel(contentDir)));
+      } 
+    }
+    
+    try {
+      if(!actions.isEmpty()) {
+        facetedProject.modify(actions, monitor);
+      }
+    }
+    finally {
+      try {
+        //Remove any WTP created files (extra application.xml and manifest) 
+        fileCleaner.cleanUp();
+      } catch (CoreException cex) {
+        LOG.error(Messages.Error_Cleaning_WTP_Files, cex);
+      }
+    }
+    //MECLIPSEWTP-41 Fix the missing moduleCoreNature
+    fixMissingModuleCoreNature(project, monitor);
+    
+    IVirtualComponent earComponent = ComponentCore.createComponent(project);
+    IPath contentDirPath = new Path((contentDir.startsWith("/"))?contentDir:"/"+contentDir); //$NON-NLS-1$ //$NON-NLS-2$
+    //Ensure the EarContent link has been created
+    if (!WTPProjectsUtil.hasLink(project, ROOT_PATH, contentDirPath, monitor)) {
+      earComponent.getRootFolder().createLink(contentDirPath, IVirtualResource.NONE, monitor);
+    }
+    WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(earComponent.getRootFolder(), contentDirPath, monitor);
+
+    //MECLIPSEWTP-56 : application.xml should not be generated in the source directory
+    boolean useBuildDirectory = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().getPreferences(project).isApplicationXmGeneratedInBuildDirectory();
+    boolean useResourcefiltering = config.isFilteringDeploymentDescriptorsEnabled();
+    
+    List<IPath> sourcePaths = new ArrayList<>();
+    sourcePaths.add(contentDirPath);
+    
+    if (!useBuildDirectory && useResourcefiltering) {
+        mavenMarkerManager.addMarker(project, MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID, 
+                                    Messages.markers_mavenarchiver_output_settings_ignored_warning, -1, IMarker.SEVERITY_WARNING);
+    }
+    if (useBuildDirectory || useResourcefiltering) {
+      IPath m2eclipseWtpFolderPath = new Path("/").append(ProjectUtils.getM2eclipseWtpFolder(mavenProject, project)); //$NON-NLS-1$
+      ProjectUtils.hideM2eclipseWtpFolder(mavenProject, project);
+      IPath generatedResourcesPath = m2eclipseWtpFolderPath.append(Path.SEPARATOR+MavenWtpConstants.EAR_RESOURCES_FOLDER);
+      sourcePaths.add(generatedResourcesPath);
+      if (!WTPProjectsUtil.hasLink(project, ROOT_PATH, generatedResourcesPath, monitor)) {
+        WTPProjectsUtil.insertLinkBefore(project, generatedResourcesPath, contentDirPath, ROOT_PATH, monitor);      
+      }
+     }
+
+    //MECLIPSEWTP-161 remove stale source paths
+    WTPProjectsUtil.deleteLinks(project, ROOT_PATH, sourcePaths, monitor);
+    
+    removeTestFolderLinks(project, mavenProject, monitor, "/"); //$NON-NLS-1$
+    
+    ProjectUtils.removeNature(project, JavaCore.NATURE_ID, monitor);
+
+    String finalName = config.getFinalName();
+    if (!finalName.endsWith(".ear")) { //$NON-NLS-1$
+      finalName += ".ear"; //$NON-NLS-1$
+    }
+    configureDeployedName(project, finalName);
+    project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+
+    
+    //MECLIPSEWTP-221 : add (in|ex)clusion patterns as .component metadata
+    addComponentExclusionPatterns(earComponent, config);
+    
+    setModuleDependencies(project, mavenProject, monitor);
+  }
+
+  private IDataModel getEarModel(String contentDir) {
+    IDataModel earModelCfg = DataModelFactory.createDataModel(new EarFacetInstallDataModelProvider());
+    earModelCfg.setProperty(IEarFacetInstallDataModelProperties.CONTENT_DIR, contentDir);
+    earModelCfg.setProperty(IEarFacetInstallDataModelProperties.GENERATE_DD, false);
+    return earModelCfg;
+  }
+
+  @Override
+public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
+    if(!facetedProject.hasProjectFacet(WTPProjectsUtil.EAR_FACET)) {
+      return;
+    }
+    IVirtualComponent earComponent = ComponentCore.createComponent(project);
+    
+    Set<IVirtualReference> newRefs = new LinkedHashSet<>();
+    
+    EarPluginConfiguration config = new EarPluginConfiguration(mavenProject);
+    // Retrieving all ear module configuration from maven-ear-plugin : User defined modules + artifacts dependencies.
+    
+    Set<EarModule> earModules = config.getEarModules();
+
+    String libBundleDir = config.getDefaultBundleDirectory();
+
+    updateLibDir(project, libBundleDir, monitor);
+    
+    IPackagingConfiguration packagingConfig = new PackagingConfiguration(config.getPackagingIncludes(), config.getPackagingExcludes());
+    
+    for(EarModule earModule : earModules) {
+
+      Artifact artifact = earModule.getArtifact();
+      IVirtualComponent depComponent = null;
+      IMavenProjectFacade workspaceDependency = projectManager.getMavenProject(artifact.getGroupId(), artifact
+          .getArtifactId(), artifact.getVersion());
+
+      if(workspaceDependency != null && !workspaceDependency.getProject().equals(project)
+          && workspaceDependency.getFullPath(artifact.getFile()) != null) {
+        //artifact dependency is a workspace project
+        IProject depProject = preConfigureDependencyProject(workspaceDependency, monitor);
+        if (ModuleCoreNature.isFlexibleProject(depProject)) {
+          depComponent = createDependencyComponent(earComponent, depProject);
+        }
+      } else {
+        //artifact dependency should be added as a JEE module, referenced with M2_REPO variable 
+        depComponent = createDependencyComponent(earComponent, earModule.getArtifact());
+      }
+      
+      if (depComponent != null && packagingConfig.isPackaged(earModule.getUri())) {
+        IVirtualReference depRef = ComponentCore.createReference(earComponent, depComponent);
+        String bundleDir = (StringUtils.isBlank(earModule.getBundleDir()))?"/":earModule.getBundleDir(); //$NON-NLS-1$
+        depRef.setRuntimePath(new Path(bundleDir));
+        depRef.setArchiveName(earModule.getBundleFileName());
+        newRefs.add(depRef);
+      }
+    }
+    
+    IVirtualReference[] newRefsArray = new IVirtualReference[newRefs.size()];
+    newRefs.toArray(newRefsArray);
+    
+    //Only change the project references if they've changed
+    if (hasChanged(earComponent.getReferences(), newRefsArray)) {
+      earComponent.setReferences(newRefsArray);
+    }
+
+    boolean useBuildDirectory = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().getPreferences(project).isApplicationXmGeneratedInBuildDirectory();
+    DeploymentDescriptorManagement.INSTANCE.updateConfiguration(project, mavenProject, config, useBuildDirectory, monitor);
+  }
+
+
+
+  private void updateLibDir(IProject project, String newLibDir, IProgressMonitor monitor) {
+    //Update lib dir only applies to Java EE 5 ear projects
+    if(!J2EEProjectUtilities.isJEEProject(project)){ 
+      return;
+    }
+    
+    //if the ear project Java EE level was < 5.0, the following would throw a ClassCastException  
+    final IEARModelProvider earModel = (IEARModelProvider)ModelProviderManager.getModelProvider(project);
+    if (earModel == null) {
+      return;
+    }
+    final Application app = (Application)earModel.getModelObject();
+    if (app != null) {
+      if (newLibDir == null || "/".equals(newLibDir)) { //$NON-NLS-1$
+        newLibDir = "lib"; //$NON-NLS-1$
+      } 
+      //MECLIPSEWTP-167 : lib directory mustn't start with a slash
+      else if (newLibDir.startsWith("/")) { //$NON-NLS-1$
+        newLibDir = newLibDir.substring(1);
+      }
+      String oldLibDir = app.getLibraryDirectory();
+      if (newLibDir.equals(oldLibDir)) return;
+      final String libDir = newLibDir;
+      earModel.modify(new Runnable() {
+        @Override
+		public void run() {     
+        app.setLibraryDirectory(libDir);
+      }}, null);
+    }
+  }
+
+
+  private IVirtualComponent createDependencyComponent(IVirtualComponent earComponent, IProject project) {
+    IVirtualComponent depComponent = ComponentCore.createComponent(project);
+    return depComponent;
+  }
+
+  private IVirtualComponent createDependencyComponent(IVirtualComponent earComponent, Artifact artifact) {
+      //Create dependency component, referenced from the local Repo.
+      String artifactPath = ArtifactHelper.getM2REPOVarPath(artifact);
+      IVirtualComponent depComponent = ComponentCore.createArchiveComponent(earComponent.getProject(), artifactPath);
+      return depComponent;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EjbPluginConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EjbPluginConfiguration.java
new file mode 100644
index 0000000..7c7334f
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EjbPluginConfiguration.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.core.project.MavenProjectUtils;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * maven-ear-plugin configuration model.
+ * 
+ * @see <a href="http://maven.apache.org/plugins/maven-ejb-plugin/ejb-mojo.html">http://maven.apache.org/plugins/maven-ejb-plugin/ejb-mojo.html</a>
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class EjbPluginConfiguration {
+  
+  private static final Logger LOG = LoggerFactory.getLogger(EjbPluginConfiguration.class); 
+
+  /**
+   * Maven defaults ejb version to 2.1
+   */
+  private static final IProjectFacetVersion DEFAULT_EJB_FACET_VERSION = IJ2EEFacetConstants.EJB_21;
+  
+  final Plugin plugin;
+ 
+  final MavenProject ejbProject;
+  
+  public EjbPluginConfiguration(MavenProject mavenProject) {
+
+    if (JEEPackaging.EJB != JEEPackaging.getValue(mavenProject.getPackaging()))
+      throw new IllegalArgumentException(Messages.EjbPluginConfiguration_Project_Must_Have_ejb_Packaging);
+    
+    this.ejbProject = mavenProject;
+    this.plugin = mavenProject.getPlugin("org.apache.maven.plugins:maven-ejb-plugin"); //$NON-NLS-1$
+  }
+
+  /**
+   * Gets EJB_FACET version of the project from pom.xml.<br/> 
+   * @return  value of &lt;maven-ejb-plugin&gt;&lt;configuration&gt;&lt;ejbVersion&gt;. Default value is 2.1.
+   */
+  public IProjectFacetVersion getEjbFacetVersion() {
+    if (plugin == null){
+      return DEFAULT_EJB_FACET_VERSION; 
+    }
+
+    Xpp3Dom dom = (Xpp3Dom) plugin.getConfiguration();
+    if (dom == null) {
+      return DEFAULT_EJB_FACET_VERSION; 
+    }
+    
+    String ejbVersion = DomUtils.getChildValue(dom, "ejbVersion"); //$NON-NLS-1$
+    if (ejbVersion != null) {
+      try {
+        return WTPProjectsUtil.EJB_FACET.getVersion(ejbVersion);
+      } catch (Exception e) {
+        LOG.warn(e.getMessage());
+        //If ejbVersion > 3.0 and WTP < 3.2, then downgrade to ejb facet 3.0
+        if (ejbVersion.startsWith("3.")){ //$NON-NLS-1$
+          return IJ2EEFacetConstants.EJB_30;
+        }
+      }
+    }
+    return DEFAULT_EJB_FACET_VERSION; 
+  }
+  
+  /**
+   * @return the first resource location directory declared in pom.xml
+   */
+  public String getEjbContentDirectory(IProject project) {
+    IPath[] resources = MavenProjectUtils.getResourceLocations(project, ejbProject.getResources());
+    if (resources != null && resources.length > 0 && resources[0] != null) {
+    	return resources[0].toPortableString();
+    }
+    return "src/main/resources"; //$NON-NLS-1$
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EjbProjectConfiguratorDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EjbProjectConfiguratorDelegate.java
new file mode 100644
index 0000000..ae7531a
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/EjbProjectConfiguratorDelegate.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeConflictingFacets;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jst.j2ee.ejb.project.operations.IEjbFacetInstallDataModelProperties;
+import org.eclipse.jst.j2ee.internal.ejb.project.operations.EjbFacetInstallDataModelProvider;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+
+/**
+ * Configures EJB projects based on their maven-ejb-plugin configuration.
+ * 
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+class EjbProjectConfiguratorDelegate extends AbstractProjectConfiguratorDelegate {
+
+  @Override
+protected void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
+
+    IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project.getFile(IMavenConstants.POM_FILE_NAME), true, monitor);
+
+    Set<Action> actions = new LinkedHashSet<>();
+    installJavaFacet(actions, project, facetedProject);
+
+    EjbPluginConfiguration config = new EjbPluginConfiguration(mavenProject);
+    String contentDir = config.getEjbContentDirectory(project);
+    IProjectFacetVersion ejbFv = config.getEjbFacetVersion();
+    
+    if(!facetedProject.hasProjectFacet(WTPProjectsUtil.EJB_FACET)) {
+      removeConflictingFacets(facetedProject, ejbFv, actions);
+      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, ejbFv, getEjbDataModel(contentDir)));
+    } else {
+      IProjectFacetVersion projectFacetVersion = facetedProject.getProjectFacetVersion(WTPProjectsUtil.EJB_FACET);     
+      if(ejbFv.getVersionString() != null && !ejbFv.getVersionString().equals(projectFacetVersion.getVersionString())){
+          actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, ejbFv, getEjbDataModel(contentDir)));
+      } 
+    }
+    
+    if(!actions.isEmpty()) {
+      ResourceCleaner fileCleaner = new ResourceCleaner(project);
+      try {
+        addFoldersToClean(fileCleaner, facade);
+        facetedProject.modify(actions, monitor);
+      } finally {
+        //Remove any unwanted MANIFEST.MF the Facet installation has created
+        fileCleaner.cleanUp();
+      }
+    }
+
+    //MECLIPSEWTP-41 Fix the missing moduleCoreNature
+    fixMissingModuleCoreNature(project, monitor);
+    
+    removeTestFolderLinks(project, mavenProject, monitor, "/"); //$NON-NLS-1$
+
+    IVirtualComponent ejbComponent = ComponentCore.createComponent(project);
+    if (ejbComponent != null) {
+      IPath contentDirPath = new Path("/").append(contentDir); //$NON-NLS-1$
+      WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(ejbComponent.getRootFolder(), contentDirPath, monitor);
+    }
+    
+    //Remove "library unavailable at runtime" warning.
+    setNonDependencyAttributeToContainer(project, monitor);
+    
+    WTPProjectsUtil.removeWTPClasspathContainer(project);
+  }
+
+  private Object getEjbDataModel(String contentDir) {
+    IDataModel ejbModelCfg = DataModelFactory.createDataModel(new EjbFacetInstallDataModelProvider());
+    ejbModelCfg.setProperty(IEjbFacetInstallDataModelProperties.CONFIG_FOLDER, contentDir);
+    ejbModelCfg.setBooleanProperty(IEjbFacetInstallDataModelProperties.ADD_TO_EAR, false);
+    return ejbModelCfg;
+  }
+
+  @Override
+  public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+    // TODO check if there's anything to do!
+  }
+  
+  @Override
+  protected void addFoldersToClean(ResourceCleaner fileCleaner, IMavenProjectFacade facade) {
+	  super.addFoldersToClean(fileCleaner, facade);
+	  cleanEjbJar(fileCleaner, facade.getCompileSourceLocations());
+	  cleanEjbJar(fileCleaner, facade.getResourceLocations());
+      IPath defaultResource = new Path("src/main/resources"); //$NON-NLS-1$
+	  fileCleaner.addFiles(defaultResource.append("META-INF/ejb-jar.xml")); //$NON-NLS-1$
+  }
+
+  private void cleanEjbJar(ResourceCleaner fileCleaner, IPath[] directories) {
+	  for (IPath p : directories) {
+		  if (p != null) {
+			  fileCleaner.addFiles(p.append("META-INF/ejb-jar.xml")); //$NON-NLS-1$
+		  }
+	  }
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/IMavenPackageFilter.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/IMavenPackageFilter.java
new file mode 100644
index 0000000..35ecea9
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/IMavenPackageFilter.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import org.eclipse.m2e.core.internal.markers.SourceLocation;
+
+/**
+ * Represents Maven packaging filter settings.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public interface IMavenPackageFilter {
+
+  /**
+   * @return exclusion patterns applied during packaging
+   */
+  public String[] getPackagingExcludes();
+
+  /**
+   * @return inclusion patterns applied during packaging
+   */
+  public String[] getPackagingIncludes();
+
+  /**
+   * @return exclusion patterns applied on sources
+   */
+  public String[] getSourceExcludes();
+
+  /**
+   * @return exclusion patterns applied on sources
+   */
+  public String[] getSourceIncludes();
+  
+  
+  /**
+   * @return the source location of the maven plugin
+   */
+  public SourceLocation getSourceLocation();
+
+  /**
+   * @return the name of the *SourceInclude parameter
+   */
+  public String getSourceIncludeParameterName();
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/IPackagingConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/IPackagingConfiguration.java
new file mode 100644
index 0000000..9d936ac
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/IPackagingConfiguration.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+
+/**
+ * Determines if a file must be deployed, according to its file name.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public interface IPackagingConfiguration {
+
+  boolean isPackaged(String deployedFileName);
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/IProjectConfiguratorDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/IProjectConfiguratorDelegate.java
new file mode 100644
index 0000000..05e04e9
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/IProjectConfiguratorDelegate.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.m2e.jdt.IClasspathDescriptor;
+
+
+/**
+ * Configure projects based on maven plugin configuration.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+interface IProjectConfiguratorDelegate {
+
+  /**
+   * Set project facet and configure settings according to maven plugin configuration.
+   * 
+   * @param mavenProject
+   * @param project
+   * @param monitor
+   * @throws MarkedException   
+   */
+  void configureProject(IProject project, MavenProject mavenProject, IProgressMonitor monitor) throws MarkedException;
+
+  /**
+   * Configure project module dependencies based on maven plugin configuration.
+   * 
+   * @param mavenProject
+   * @param project
+   * @param monitor
+   * @throws CoreException
+   */
+  void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException;
+
+  /**
+   * Configures Maven project classpath, i.e. content of MavenDependencies classpath container
+   * 
+   * @param project
+   * @param mavenProject
+   * @param classpath
+   * @param monitor
+   */
+  void configureClasspath(IProject project, MavenProject mavenProject, IClasspathDescriptor classpath,
+      IProgressMonitor monitor) throws CoreException;
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/JEEPackaging.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/JEEPackaging.java
new file mode 100644
index 0000000..70e1b6d
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/JEEPackaging.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+/**
+ * Enumeration of Maven JEE related packaging types.
+ * 
+ * @author Fred Bricon
+ */
+public enum JEEPackaging {
+  /**
+   * Web project.
+   */
+  WAR("war"), //$NON-NLS-1$
+  /**
+   * Enterprise Java Bean.
+   */
+  EJB("ejb"), //$NON-NLS-1$
+  /**
+   * Enterprise Application Resource.
+   */
+  EAR("ear"), //$NON-NLS-1$
+  /**
+   * Resource Adapter Archive.
+   */
+  RAR("rar"), //$NON-NLS-1$
+  /**
+   * Application client
+   */
+  APP_CLIENT("app-client"), //$NON-NLS-1$
+  /**
+   * Unknown packaging.
+   */
+  UNKNOWN(null);
+
+  private String name;
+
+  private JEEPackaging(String name) {
+    this.name = name;
+  }
+
+  /**
+   * @return the packaging name.
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Gets a JEEPackaging from maven packaging name. Supported values are <i>war</i>, <i>ejb</i>, <i>ear</i>,
+   * <i>rar</i>, <i>app-client</i>.
+   * 
+   * @param packaging of a maven artifact.
+   * @return the corresponding JEEPackaging or UNKNOWN if the package type is not supported.
+   */
+  public static JEEPackaging getValue(String packaging) {
+    if(packaging == null) {
+      throw new IllegalArgumentException("packaging must not be null"); //$NON-NLS-1$
+    }
+    for(JEEPackaging pkg : values()) {
+      if(packaging.equals(pkg.getName())) {
+        return pkg;
+      }
+    }
+    return UNKNOWN;
+  }
+  
+  static boolean isJEEPackaging(String packaging) {
+    JEEPackaging pkg = getValue(packaging);
+   return !UNKNOWN.equals(pkg);  
+  }
+
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MarkedException.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MarkedException.java
new file mode 100644
index 0000000..49dfc9d
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MarkedException.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+/**
+ * Represents an {@link Exception} that should be turned into an Error Marker.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class MarkedException extends Exception {
+
+  private static final long serialVersionUID = 7182756387257983149L;
+
+  public MarkedException() {
+  }
+
+  public MarkedException(String message) {
+    super(message);
+  }
+
+  public MarkedException(Throwable cause) {
+    super(cause);
+  }
+
+  public MarkedException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenDeploymentDescriptorManagement.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenDeploymentDescriptorManagement.java
new file mode 100644
index 0000000..ee72ec2
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenDeploymentDescriptorManagement.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.embedder.IMaven;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.internal.MavenPluginActivator;
+import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.IMavenProjectRegistry;
+import org.eclipse.m2e.wtp.earmodules.EarModule;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.CommonNavigator;
+
+
+/**
+ * Deployment Descriptor Management based on maven-ear-plugin invocation
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ * @author Snjezana Peco
+ */
+@SuppressWarnings("restriction")
+public class MavenDeploymentDescriptorManagement implements DeploymentDescriptorManagement {
+
+  private static final VersionRange VALID_EAR_PLUGIN_RANGE;
+  static {
+    try {
+      VALID_EAR_PLUGIN_RANGE = VersionRange.createFromVersionSpec("[2.4.3,)"); //$NON-NLS-1$
+    } catch(InvalidVersionSpecificationException ex) {
+      //Can't happen
+      throw new RuntimeException("Unable to create ear plugin version range from [2.4.3,)", ex); //$NON-NLS-1$
+    }
+  }
+
+  /**
+   * Executes ear:generate-application-xml goal to generate application.xml (and jboss-app.xml if needed). Existing
+   * files will be overwritten.
+   * 
+   * @throws CoreException
+   */
+
+  @Override
+public void updateConfiguration(IProject project, MavenProject mavenProject, EarPluginConfiguration plugin,
+     boolean useBuildDirectory, IProgressMonitor monitor) throws CoreException {
+
+    IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry();
+    IMavenProjectFacade mavenFacade = projectManager.getProject(project);
+    IMavenMarkerManager markerManager  = MavenPluginActivator.getDefault().getMavenMarkerManager();
+    
+    IFile pomResource = project.getFile(IMavenConstants.POM_FILE_NAME);
+    markerManager.deleteMarkers(pomResource, MavenWtpConstants.WTP_MARKER_GENERATE_APPLICATIONXML_ERROR);
+
+    //Create a maven request + session
+    IMaven maven = MavenPlugin.getMaven();
+    MavenExecutionRequest request = projectManager.createExecutionRequest(pomResource, mavenFacade.getResolverConfiguration(), monitor);
+    MavenSession session = maven.createSession(request, mavenProject);
+
+    MavenExecutionPlan executionPlan = maven.calculateExecutionPlan(session, mavenProject, Collections.singletonList("ear:generate-application-xml"), true, monitor); //$NON-NLS-1$
+    MojoExecution genConfigMojo = getExecution(executionPlan, "maven-ear-plugin", "generate-application-xml"); //$NON-NLS-1$ //$NON-NLS-2$
+    if(genConfigMojo == null) {
+      //TODO Better error management
+      return;
+    }
+    
+    //Let's force the generated config files location
+    Xpp3Dom configuration = genConfigMojo.getConfiguration();
+    if(configuration == null) {
+      configuration = new Xpp3Dom("configuration"); //$NON-NLS-1$
+      genConfigMojo.setConfiguration(configuration);
+    }
+    
+    File tempDirectory;
+    try {
+      tempDirectory = getTempDirectory();
+    } catch(IOException ex) {
+      IStatus status = new Status(IStatus.ERROR, MavenWtpPlugin.ID, ex.getLocalizedMessage(), ex);
+      throw new CoreException(status);
+    }
+
+    // Some old maven-ear-plugin have a dependency on an old plexus-util version that prevents
+    // using workdirectory == generatedDescriptorLocation, so we keep them separated 
+    File generatedDescriptorLocation = new File(tempDirectory, "generatedDescriptorLocation"); //$NON-NLS-1$
+    File workDirectory = new File(tempDirectory, "workDirectory"); //$NON-NLS-1$
+    
+    Xpp3Dom workDirectoryDom = configuration.getChild("workDirectory"); //$NON-NLS-1$
+    if(workDirectoryDom == null) {
+      workDirectoryDom = new Xpp3Dom("workDirectory"); //$NON-NLS-1$
+      configuration.addChild(workDirectoryDom);
+    }
+    workDirectoryDom.setValue(workDirectory.getAbsolutePath());
+
+    Xpp3Dom genDescriptorLocationDom = configuration.getChild("generatedDescriptorLocation"); //$NON-NLS-1$
+    if(genDescriptorLocationDom == null) {
+      genDescriptorLocationDom = new Xpp3Dom("generatedDescriptorLocation"); //$NON-NLS-1$
+      configuration.addChild(genDescriptorLocationDom);
+    }
+    genDescriptorLocationDom.setValue(generatedDescriptorLocation.getAbsolutePath());
+    
+
+    // Fix for http://jira.codehaus.org/browse/MEAR-116?focusedCommentId=232316&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_232316
+    // affecting maven-ear-plugin version < 2.4.3
+    if(!VALID_EAR_PLUGIN_RANGE.containsVersion(new DefaultArtifactVersion(genConfigMojo.getVersion()))) {
+      overrideModules(configuration, plugin.getAllEarModules());
+    }
+
+    //Execute our modified mojo
+    maven.execute(session, genConfigMojo, monitor);
+    
+    if (session.getResult().hasExceptions()){
+      markerManager.addMarkers(mavenFacade.getPom(), MavenWtpConstants.WTP_MARKER_GENERATE_APPLICATIONXML_ERROR, session.getResult());
+    }
+    
+    //Copy generated files to their final location
+    File[] files = generatedDescriptorLocation.listFiles();
+
+    //MECLIPSEWTP-56 : application.xml should not be generated in the source directory
+    
+    IFolder targetFolder;
+    IFolder earResourcesFolder = getEarResourcesDir(project, mavenProject, monitor); 
+    if (useBuildDirectory) {
+      targetFolder = earResourcesFolder;
+    } else {
+      targetFolder = project.getFolder(plugin.getEarContentDirectory(project));
+
+      if (earResourcesFolder.exists() && earResourcesFolder.isAccessible()) {
+        earResourcesFolder.delete(true, monitor);
+      }
+    }
+    
+    IFolder metaInfFolder = targetFolder.getFolder("/META-INF/"); //$NON-NLS-1$
+
+    if (files != null && files.length > 0) {
+    	for (File file:files) {
+    		if (!metaInfFolder.exists()) {
+    			ProjectUtils.createFolder(metaInfFolder, monitor);
+    		}
+    		InputStream is = null;
+    		try {
+    			is = new FileInputStream(file);
+    			IFile targetResource = metaInfFolder.getFile(file.getName());
+    			if (targetResource.exists()) {
+    				targetResource.setContents(is, IResource.FORCE, monitor);
+    			} else {
+    				targetResource.create(is, true, monitor);
+    			}
+    		} catch (FileNotFoundException ex) {
+    			IStatus status = new Status(IStatus.ERROR, MavenWtpPlugin.ID, IStatus.ERROR, ex.getMessage(), ex);
+    	        throw new CoreException(status);
+			} finally {
+    			if (is != null) {
+    				try {
+						is.close();
+					} catch (IOException ex) {
+						// ignore
+					}
+    			}
+    		}
+    	}
+    }
+    
+    deleteDirectory(generatedDescriptorLocation);
+    
+    Display.getDefault().asyncExec(new Runnable() {
+		@Override
+		public void run() {
+			if (PlatformUI.isWorkbenchRunning()) {
+				IViewPart view = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(IPageLayout.ID_PROJECT_EXPLORER);
+				if (view instanceof CommonNavigator) {
+					CommonNavigator navigator = (CommonNavigator) view;
+					navigator.getCommonViewer().refresh();
+				}
+			}
+		}
+	});
+  }
+
+  private IFolder getEarResourcesDir(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+    String appResourcesDir = ProjectUtils.getM2eclipseWtpFolder(mavenProject, project).toPortableString()+Path.SEPARATOR+MavenWtpConstants.EAR_RESOURCES_FOLDER;
+    IFolder appResourcesFolder = project.getFolder(appResourcesDir);
+ 
+    if (!appResourcesFolder.exists()) {
+      ProjectUtils.createFolder(appResourcesFolder, monitor);
+    }
+    if (!appResourcesFolder.isDerived()) {
+      appResourcesFolder.setDerived(true, monitor);
+    }
+    return appResourcesFolder;
+  }
+
+
+  private void overrideModules(Xpp3Dom configuration, Set<EarModule> earModules) {
+    Xpp3Dom modules = configuration.getChild("modules"); //$NON-NLS-1$
+    if(modules == null) {
+      modules = new Xpp3Dom("modules"); //$NON-NLS-1$
+      configuration.addChild(modules);
+    }
+    //TODO find a more elegant way to clear the modules  
+    while(modules.getChildCount() > 0) {
+      modules.removeChild(0);
+    }
+    //Recreate the module's children, forcing the uri.
+    for(EarModule earModule : earModules) {
+      modules.addChild(earModule.getAsDom());
+    }
+  }
+
+  private File getTempDirectory() throws IOException {
+    File tempDir = new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$
+    File dir = new File(tempDir, ".mavenDeploymentDescriptorManagement"); //$NON-NLS-1$
+    if(dir.exists()) {
+      if(dir.isFile()) {
+        if(!dir.delete()) {
+          throw new IOException(NLS.bind(Messages.MavenDeploymentDescriptorManagement_Error_Deleting_Temp_Folder, dir.getAbsolutePath()));
+        }
+      } else if(!deleteDirectory(dir)) {
+          throw new IOException(NLS.bind(Messages.MavenDeploymentDescriptorManagement_Error_Deleting_Temp_Folder, dir.getAbsolutePath())); 
+      }
+    }
+    dir.mkdir();
+    return dir;
+  }
+
+  private static boolean deleteDirectory(File path) {
+    if(path.exists()) {
+      File[] files = path.listFiles();
+      for(int i = 0; i < files.length; i++ ) {
+        if(files[i].isDirectory()) {
+          deleteDirectory(files[i]);
+        } else {
+          files[i].delete();
+        }
+      }
+    }
+    return (path.delete());
+  }
+
+  private MojoExecution getExecution(MavenExecutionPlan executionPlan, String artifactId, String goal) throws CoreException {
+    for(MojoExecution execution : executionPlan.getMojoExecutions()) {
+      if(artifactId.equals(execution.getArtifactId()) && goal.equals(execution.getGoal())) {
+        return execution;
+      }
+    }
+    return null;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenSessionHelper.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenSessionHelper.java
new file mode 100644
index 0000000..95da53b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenSessionHelper.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.lifecycle.internal.DependencyContext;
+import org.apache.maven.lifecycle.internal.MojoExecutor;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.internal.embedder.MavenImpl;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.IMavenProjectRegistry;
+import org.eclipse.m2e.wtp.internal.Messages;
+
+/**
+ * Helper for {@link MavenSession} manipulations.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class MavenSessionHelper {
+  
+  private final MavenProject project;
+
+  private Set<Artifact> artifacts;
+
+  private Set<Artifact> dependencyArtifacts; 
+
+  public MavenSessionHelper(MavenProject mavenProject) {
+    if (mavenProject == null) {
+      throw new IllegalArgumentException(Messages.Error_Maven_Project_Cant_Be_Null);
+    } 
+    this.project = mavenProject;
+  }
+  
+  public void ensureDependenciesAreResolved(String pluginId, String goal) throws CoreException {
+    artifacts = project.getArtifacts();
+    dependencyArtifacts = project.getDependencyArtifacts();
+    IProgressMonitor monitor = new NullProgressMonitor();
+    MavenSession session = getSession(monitor);
+          
+    MavenExecutionPlan executionPlan = MavenPlugin.getMaven().calculateExecutionPlan(session, 
+                                                                                     project, 
+                                                                                     Collections.singletonList(goal), 
+                                                                                     true, 
+                                                                                     monitor);
+    
+    MojoExecution execution = getExecution(executionPlan, pluginId);
+    
+    ensureDependenciesAreResolved(session, execution, monitor);
+  }
+  
+  public void ensureDependenciesAreResolved(MavenSession session, MojoExecution execution, IProgressMonitor monitor) throws CoreException {
+    artifacts = project.getArtifacts();
+    dependencyArtifacts = project.getDependencyArtifacts();
+    try {
+               
+      MojoExecutor mojoExecutor = lookup(MojoExecutor.class);
+      DependencyContext dependencyContext = mojoExecutor.newDependencyContext(session,
+          Collections.singletonList(execution));
+
+      mojoExecutor.ensureDependenciesAreResolved(execution.getMojoDescriptor(), session, dependencyContext);
+
+    } catch(Exception ex) {
+      dispose();
+    }
+  }
+
+  private MavenSession getSession(IProgressMonitor monitor) throws CoreException {
+    IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry();
+    IMavenProjectFacade mavenFacade = projectManager.getMavenProject(project.getGroupId(), 
+                                                                     project.getArtifactId(), 
+                                                                     project.getVersion());
+
+    MavenExecutionRequest request = projectManager.createExecutionRequest(mavenFacade.getPom(), 
+                                                                          mavenFacade.getResolverConfiguration(), 
+                                                                          monitor);
+    
+    MavenSession session = MavenPlugin.getMaven().createSession(request, project);
+    return session;
+  }
+  
+  public void dispose() {
+    project.setArtifactFilter(null);
+    project.setResolvedArtifacts(null);
+    project.setArtifacts(artifacts);
+    project.setDependencyArtifacts(dependencyArtifacts);
+  }
+  
+  private <T> T lookup(Class<T> clazz) throws CoreException {
+    try {
+      return ((MavenImpl)MavenPlugin.getMaven()).getPlexusContainer().lookup(clazz);
+    } catch(ComponentLookupException ex) {
+      throw new CoreException(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, -1,
+          Messages.MavenSessionHelper_Error_Component_Lookup, ex));
+    }
+  }
+
+  public static MojoExecution getExecution(MavenExecutionPlan executionPlan, String artifactId) throws CoreException {
+    if (executionPlan == null) return null;
+    for(MojoExecution execution : executionPlan.getMojoExecutions()) {
+      if(artifactId.equals(execution.getArtifactId()) ) {
+        return execution;
+      }
+    }
+    return null;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenWtpConstants.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenWtpConstants.java
new file mode 100644
index 0000000..fec89d4
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenWtpConstants.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2015 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import org.eclipse.m2e.core.internal.IMavenConstants;
+
+/**
+ * m2e-wtp Constants
+ *
+ * @author Fred Bricon
+ */
+public final class MavenWtpConstants {
+  
+  private MavenWtpConstants() {} 
+
+  public static final String WTP_MARKER_ID = IMavenConstants.MARKER_ID + ".wtp"; //$NON-NLS-1$
+
+  public static final String WTP_MARKER_CONFIGURATION_ERROR_ID = WTP_MARKER_ID + ".configuration";//$NON-NLS-1$ 
+  
+  public static final String WTP_MARKER_FILTERING_ERROR = WTP_MARKER_ID + ".filteringError"; //$NON-NLS-1$
+
+  public static final String WTP_MARKER_OVERLAY_ERROR = WTP_MARKER_ID + ".overlayError"; //$NON-NLS-1$
+
+  public static final String WTP_MARKER_GENERATE_APPLICATIONXML_ERROR = WTP_MARKER_ID + ".applicationXmlError"; //$NON-NLS-1$
+
+  public static final String WTP_MARKER_UNSUPPORTED_DEPENDENCY_PROBLEM = WTP_MARKER_ID + ".unsupportedDependencyProblem"; //$NON-NLS-1$
+
+  public static final String WTP_MARKER_FAIL_ON_MISSING_WEBXML_ERROR = WTP_MARKER_ID + ".failOnMissingWebXml"; //$NON-NLS-1$
+
+  
+  public static final String M2E_WTP_FOLDER = "m2e-wtp"; //$NON-NLS-1$
+  
+  public static final String WEB_RESOURCES_FOLDER = "web-resources"; //$NON-NLS-1$
+
+  public static final String EAR_RESOURCES_FOLDER = "ear-resources"; //$NON-NLS-1$
+  
+  public static final String ROOT_FOLDER = "/"; //$NON-NLS-1$
+  
+
+  /**
+   * Provisional name of component property used by WTP server adapters to exclude resources from deployment.
+   * Only known consumer is JBoss AS adapter.
+   */
+  public static final String COMPONENT_EXCLUSION_PATTERNS = "component.exclusion.patterns"; //$NON-NLS-1$
+  
+  /**
+   * Provisional name of component property used by WTP server adapters to include resources in deployment.
+   * Only known consumer is JBoss AS adapter.
+   */
+  public static final String COMPONENT_INCLUSION_PATTERNS = "component.inclusion.patterns"; //$NON-NLS-1$
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenWtpPlugin.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenWtpPlugin.java
new file mode 100644
index 0000000..4c064a7
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/MavenWtpPlugin.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import org.eclipse.m2e.wtp.internal.preferences.MavenWtpPreferencesManagerImpl;
+import org.eclipse.m2e.wtp.preferences.IMavenWtpPreferencesManager;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * m2e-wtp plugin
+ *
+ * @author Eugene Kuleshov
+ */
+public class MavenWtpPlugin extends AbstractUIPlugin {
+
+  public static final String ID = "org.eclipse.m2e.wtp"; //$NON-NLS-1$
+  
+  private static MavenWtpPlugin instance;
+
+  private IMavenWtpPreferencesManager preferenceManager; 
+  
+  public IMavenWtpPreferencesManager getMavenWtpPreferencesManager() {
+    return preferenceManager;
+  }
+
+  public MavenWtpPlugin() {
+    instance = this;
+  }
+  
+  @Override
+  public void start(BundleContext context) throws Exception {
+    super.start(context);
+    
+    this.preferenceManager = new MavenWtpPreferencesManagerImpl();
+  }
+
+  @Override
+  public void stop(BundleContext context) throws Exception {
+    super.stop(context);
+  }
+  
+  public static MavenWtpPlugin getDefault() {
+    return instance;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/OverlayConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/OverlayConfigurator.java
new file mode 100644
index 0000000..bb5927a
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/OverlayConfigurator.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.war.Overlay;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.lifecyclemapping.model.IPluginExecutionMetadata;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.MavenProjectChangedEvent;
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
+import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
+import org.eclipse.m2e.jdt.IClasspathDescriptor;
+import org.eclipse.m2e.wtp.internal.StringUtils;
+import org.eclipse.m2e.wtp.overlay.modulecore.IOverlayVirtualComponent;
+import org.eclipse.m2e.wtp.overlay.modulecore.OverlayComponentCore;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * Configurator for war overlays.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class OverlayConfigurator extends WTPProjectConfigurator {
+
+  @Override
+  public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor)
+      throws CoreException {
+	  mavenProjectChanged(request.getMavenProjectFacade(), monitor);
+  }
+
+  @Override
+  public void mavenProjectChanged(MavenProjectChangedEvent event, IProgressMonitor monitor) throws CoreException {
+	  mavenProjectChanged(event.getMavenProject(), monitor);
+  }
+  
+  private void mavenProjectChanged(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
+    if(facade == null) { return; }
+    IProject project = facade.getProject();
+    if (WTPProjectsUtil.isM2eWtpDisabled(facade, monitor) || project.getResourceAttributes().isReadOnly()){
+      return;
+    }
+
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
+    if(!facetedProject.hasProjectFacet(WebFacetUtils.WEB_FACET)) {
+      return;
+    }
+
+    MavenProject mavenProject = facade.getMavenProject(monitor);
+    try {
+      markerManager.deleteMarkers(facade.getPom(), MavenWtpConstants.WTP_MARKER_OVERLAY_ERROR);
+      setModuleDependencies(project, mavenProject, monitor);
+    } catch(Exception ex) {
+      markerManager.addErrorMarkers(facade.getPom(), MavenWtpConstants.WTP_MARKER_OVERLAY_ERROR,ex);
+    }
+  }
+
+  /**
+   * @param project
+   * @param mavenProject
+   * @param monitor
+   * @throws CoreException 
+   */
+  private void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor) throws CoreException {
+
+    IVirtualComponent warComponent = ComponentCore.createComponent(project);
+    if (warComponent == null) {
+      return;
+    }
+    
+    Set<IVirtualReference> newOverlayRefs = new LinkedHashSet<>();
+    MavenSessionHelper helper = new MavenSessionHelper(mavenProject);
+    try {
+      helper.ensureDependenciesAreResolved("maven-war-plugin", "war:war"); //$NON-NLS-1$ //$NON-NLS-2$
+      
+      MavenPlugin.getMaven();
+      
+    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
+    
+    List<Overlay> overlays = config.getOverlays();
+    //1 overlay = current project => no overlay component needed
+    if (overlays.size() > 1) {
+
+      //Component order must be inverted to follow maven's overlay order behaviour 
+      //as in WTP, last components supersede the previous ones
+      Collections.reverse(overlays);
+      for(Overlay overlay : overlays) {
+
+        if (overlay.shouldSkip()) {
+          continue;
+        }
+        
+        Artifact artifact = overlay.getArtifact();
+        IOverlayVirtualComponent overlayComponent = null;
+        IMavenProjectFacade workspaceDependency = projectManager.getMavenProject(
+            artifact.getGroupId(), 
+            artifact.getArtifactId(),
+            artifact.getVersion());
+
+        if(workspaceDependency != null) {
+          //artifact dependency is a workspace project && dependency resolution is on
+          IProject overlayProject = workspaceDependency.getProject();
+
+          if (overlayProject.equals(project)) {
+            overlayComponent = OverlayComponentCore.createSelfOverlayComponent(project);
+          } else if (workspaceDependency.getFullPath(artifact.getFile()) != null){
+            overlayComponent = OverlayComponentCore.createOverlayComponent(overlayProject);
+          } else {
+            //Dependency resolution is off
+            overlayComponent = createOverlayArchiveComponent(project, mavenProject, overlay);
+          }
+        } else {
+          overlayComponent = createOverlayArchiveComponent(project, mavenProject, overlay);
+        }
+
+        if (overlayComponent != null) {
+          
+          overlayComponent.setInclusions(new LinkedHashSet<>(Arrays.asList(overlay.getIncludes())));
+          overlayComponent.setExclusions(new LinkedHashSet<>(Arrays.asList(overlay.getExcludes())));
+          
+          IVirtualReference depRef = ComponentCore.createReference(warComponent, overlayComponent);
+          String targetPath = StringUtils.nullOrEmpty(overlay.getTargetPath())?"/":overlay.getTargetPath(); //$NON-NLS-1$
+          depRef.setRuntimePath(new Path(targetPath));
+          newOverlayRefs.add(depRef);
+        }
+      }
+      
+    }
+    
+    IVirtualReference[] oldOverlayRefs = WTPProjectsUtil.extractHardReferences(warComponent, true);
+    
+    IVirtualReference[] updatedOverlayRefs = newOverlayRefs.toArray(new IVirtualReference[newOverlayRefs.size()]);
+    
+    if (WTPProjectsUtil.hasChanged2(oldOverlayRefs, updatedOverlayRefs)){
+      //Only write in the .component file if necessary 
+      IVirtualReference[] nonOverlayRefs = WTPProjectsUtil.extractHardReferences(warComponent, false);
+      IVirtualReference[] allRefs = new IVirtualReference[nonOverlayRefs.length + updatedOverlayRefs.length];
+      System.arraycopy(nonOverlayRefs, 0, allRefs, 0, nonOverlayRefs.length);
+      System.arraycopy(updatedOverlayRefs, 0, allRefs, nonOverlayRefs.length, updatedOverlayRefs.length);
+      warComponent.setReferences(allRefs);
+    }
+
+    } finally {
+      helper.dispose();
+    }
+
+  }
+
+  private IOverlayVirtualComponent createOverlayArchiveComponent(IProject project, MavenProject mavenProject, Overlay overlay) throws CoreException {
+    IPath m2eWtpFolder = ProjectUtils.getM2eclipseWtpFolder(mavenProject, project);
+    IPath unpackDirPath = new Path(m2eWtpFolder.toOSString()+"/overlays"); //$NON-NLS-1$
+    String archiveLocation = ArtifactHelper.getM2REPOVarPath(overlay.getArtifact());
+    String targetPath = StringUtils.nullOrEmpty(overlay.getTargetPath())?"/":overlay.getTargetPath(); //$NON-NLS-1$
+    IOverlayVirtualComponent component = OverlayComponentCore.createOverlayArchiveComponent(
+                                                                project, 
+                                                                archiveLocation, 
+                                                                unpackDirPath, 
+                                                                new Path(targetPath));
+    return component;
+  }
+  
+  
+  @Override
+  public void configureClasspath(IMavenProjectFacade facade, IClasspathDescriptor classpath, IProgressMonitor monitor)
+      throws CoreException {
+  }
+  
+  @Override
+  public AbstractBuildParticipant getBuildParticipant(IMavenProjectFacade projectFacade, MojoExecution execution,
+      IPluginExecutionMetadata executionMetadata) {
+    return null;
+  }
+  
+  @Override
+  public boolean hasConfigurationChanged(IMavenProjectFacade newFacade,
+			ILifecycleMappingConfiguration oldProjectConfiguration,
+			MojoExecutionKey key, IProgressMonitor monitor) {
+	//Changes to maven-war-plugin in pom.xml don't make it "dirty" 
+	//wrt Overlay configuration (i.e. no need to invoke configure(request, monitor))
+	return false;
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/PackagingConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/PackagingConfiguration.java
new file mode 100644
index 0000000..e657cc8
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/PackagingConfiguration.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.m2e.wtp.internal.AntPathMatcher;
+
+
+/**
+ * Packaging configuration based on ANT and %regex[] patterns.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Lars Ködderitzsch
+ * @author Fred Bricon
+ */
+public class PackagingConfiguration implements IPackagingConfiguration {
+
+  String[] packagingIncludes;
+
+  String[] packagingExcludes;
+
+  private AntPathMatcher matcher;
+
+  private final static String REGEX_BEGIN = "%regex["; //$NON-NLS-1$
+  private final static String REGEX_END = "]"; //$NON-NLS-1$
+
+  public PackagingConfiguration(String[] packagingIncludes, String[] packagingExcludes) {
+    this.packagingIncludes = toPortablePathArray(packagingIncludes);
+    this.packagingExcludes = toPortablePathArray(packagingExcludes);
+    matcher = new AntPathMatcher();
+  }
+
+  @Override
+public boolean isPackaged(String virtualPath) {
+    if (virtualPath == null) {
+      return false;
+    }
+    virtualPath = toPortablePath(virtualPath);
+    if (packagingIncludes != null) {
+      for(String excl : packagingExcludes) {
+        if(matches(excl, virtualPath)) {
+          //stop here already, since exclusions have precedence over inclusions
+          return false;
+        }
+      }
+    }
+
+    //so the path is not excluded, check if it is included into packaging
+    if (packagingIncludes == null || packagingIncludes.length == 0) {
+      return true;
+    }
+    for(String incl : packagingIncludes) {
+      if(matches(incl, virtualPath)) {
+        return true;
+      }
+    }
+
+    //Definitely not included
+    return false;
+  }
+
+  private String[] toPortablePathArray(String[] patterns) {
+    if (patterns == null) {
+      return null;
+    }
+    String[] newPatterns = new String[patterns.length];
+    for (int i = 0; i < patterns.length; i++) {
+      newPatterns[i] = toPortablePath(patterns[i]);
+    }
+    return newPatterns;
+  }
+  
+  private String toPortablePath(String path) {
+    return (path==null)?null:path.replace("\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$
+  }
+  
+  private boolean isRegex(String regEx){
+	  return regEx.startsWith(REGEX_BEGIN) && regEx.endsWith(REGEX_END);
+  }
+
+  private boolean matches(String pattern, String input){
+	  if (isRegex(pattern)){
+		  //%regex[] pattern
+		  return Pattern.matches(convertToJavaRegEx(pattern), input);
+      }
+	  return matcher.match(pattern, input);
+  }
+
+  private String convertToJavaRegEx(String regEx){
+	  return regEx.substring(REGEX_BEGIN.length(), regEx.length()-REGEX_END.length());
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ProjectConfiguratorDelegateFactory.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ProjectConfiguratorDelegateFactory.java
new file mode 100644
index 0000000..fffe557
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ProjectConfiguratorDelegateFactory.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+
+/**
+ * This factory creates IProjectConfiguratorDelegate based on Maven projects packaging.  
+ *
+ * @author Fred Bricon
+ */
+//XXX See if we could refactor this to do JEEPackaging.createProjectConfiguratorDelegate() instead. 
+class ProjectConfiguratorDelegateFactory {
+
+  private ProjectConfiguratorDelegateFactory() {
+    //We don't need to instantiate this class
+  }
+   
+  
+  /**
+   * IProjectConfiguratorDelegate factory method.  
+   * @param packaging supported values are war, ejb, ear.
+   * @return a new instance of IProjectConfiguratorDelegate or null if packaging is not supported.
+   */
+  static IProjectConfiguratorDelegate getProjectConfiguratorDelegate(String packaging){
+    JEEPackaging mvnPackaging = JEEPackaging.getValue(packaging);
+    
+    switch(mvnPackaging) {
+      case WAR:
+        return new WebProjectConfiguratorDelegate();
+      case EJB:
+        return new EjbProjectConfiguratorDelegate();
+      case EAR:
+        return new EarProjectConfiguratorDelegate();
+      case RAR:
+        return new ConnectorProjectConfiguratorDelegate();
+      case APP_CLIENT:
+    	  return new AppClientProjectConfiguratorDelegate();
+      default :
+        return null;
+    }
+  
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ProjectUtils.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ProjectUtils.java
new file mode 100644
index 0000000..c44eb18
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ProjectUtils.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+
+/**
+ * Utility class around {@link IProject}
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class ProjectUtils {
+
+  /**
+   * Transform an absolute path into a relative path to a project, if possible
+   * @param project
+   * @param absolutePath : relative path to the project
+   * @return
+   */
+  public static String getRelativePath(IProject project, String absolutePath){
+	//Code copied from org.eclipse.m2e.jdt.internal.AbstractJavaProjectConfigurator 
+	//since Path.makeRelativeTo() doesn't seem to work on Linux
+    File basedir = project.getLocation().toFile();
+    String relative;
+    if(absolutePath.equals(basedir.getAbsolutePath())) {
+      relative = "."; //$NON-NLS-1$
+    } else if(absolutePath.startsWith(basedir.getAbsolutePath())) {
+      relative = absolutePath.substring(basedir.getAbsolutePath().length() + 1);
+    } else {
+      relative = absolutePath;
+    }
+    return relative.replace('\\', '/');
+  }
+  
+
+  /**
+   * @return the &lt;project&gt;/&lt;buildOutputDir&gt;/m2e-wtp/ folder
+   */
+  public static IPath getM2eclipseWtpFolder(MavenProject mavenProject, IProject project) {
+    return getBuildFolder(mavenProject, project).append(MavenWtpConstants.M2E_WTP_FOLDER);
+  }
+
+  /**
+   * Returns the project build output folder
+   * @since 0.18.0
+   */
+  public static IPath getBuildFolder(MavenProject mavenProject, IProject project) {
+    String buildOutputDir = mavenProject.getBuild().getDirectory();
+    String relativeBuildOutputDir = getRelativePath(project, buildOutputDir);
+    return new Path(relativeBuildOutputDir);
+  }
+
+  
+  /**
+   * @return the &lt;project&gt;/&lt;buildOutputDir&gt;/m2e-wtp/web-resources folder
+   */
+  public static IFolder getGeneratedWebResourcesFolder(MavenProject mavenProject, IProject project) {
+    IPath m2eWtpFolder = getM2eclipseWtpFolder(mavenProject, project);
+    return project.getFolder(m2eWtpFolder).getFolder(MavenWtpConstants.WEB_RESOURCES_FOLDER);
+  }
+
+  
+  /**
+   * Hides and derives &lt;project&gt;/&lt;buildOutputDir&gt;/m2e-wtp/ folder
+   */
+  public static void hideM2eclipseWtpFolder(MavenProject mavenProject, IProject project) throws CoreException {
+    IPath m2eclipseWtpPath = getM2eclipseWtpFolder(mavenProject, project);
+    IFolder folder = project.getFolder(m2eclipseWtpPath);
+    if (folder.exists()) {
+      IProgressMonitor monitor = new NullProgressMonitor();
+      if (!folder.isDerived()) {
+        folder.setDerived(true);//TODO Eclipse < 3.6 doesn't support setDerived(bool, monitor)
+      }
+      if (!folder.isHidden()) {
+        folder.setHidden(true);
+      }
+      folder.getParent().refreshLocal(IResource.DEPTH_ZERO,monitor);
+    }
+  }
+  
+  /**
+   * Creates an IFolder and its parent hierarchy recursively. 
+   */
+  public static void createFolder(IFolder folder, IProgressMonitor monitor) throws CoreException {
+    if (folder == null || folder.exists()) {
+      return;
+    }
+    IContainer parent = folder.getParent();
+    if (parent instanceof IFolder) {
+      createFolder((IFolder)parent, monitor);
+    }
+    folder.create(true, true, monitor);
+  }
+  
+  /**
+   * Removes the nature of a project.
+   */
+  public static void removeNature(IProject project, String natureId, IProgressMonitor monitor) throws CoreException {
+    if (project.hasNature(natureId)) {
+      IProjectDescription description = project.getDescription();
+      String[] prevNatures = description.getNatureIds();
+      String[] newNatures = new String[prevNatures.length - 1];
+      for (int i=0, j = 0 ; i < prevNatures.length; i++) {
+        if (!prevNatures[i].equals(natureId)) {
+          newNatures[j++] = prevNatures[i];
+        }
+      }
+      description.setNatureIds(newNatures);
+      project.setDescription(description, monitor);
+    }
+  }
+  
+  
+  /**
+   * Refreshes the projects hierarchy. For example, if the project on
+   * which a facet should be installed is 'Parent1/Parent2/Child',
+   * then both Parent1, Parent2 and Child are refreshed.
+   * 
+   * @param basedir : the base directory (absolute file system path) of the (child) project to refresh.
+   * @param refreshDepth: the refresh depth
+   * @param monitor : the progress monitor
+   * @return the number of projects that were refreshed
+   * @throws CoreException
+   *             in case of problem during refresh
+   * @see IResource for depth values.
+   * 
+   * @author Xavier Coulon
+   * @author Fred Bricon
+   */
+  public static int refreshHierarchy(File basedir, int refreshDepth, IProgressMonitor monitor) throws CoreException {
+    try {
+      int count = 0;
+      final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+      final List<IProject> projects = new ArrayList<>(Arrays.asList(root.getProjects()));
+      
+      final IPath rootLocation = root.getLocation();
+      IPath basedirPath = new Path(basedir.getAbsolutePath());
+      while(!rootLocation.equals(basedirPath) && rootLocation.isPrefixOf(basedirPath)) {
+        Iterator<IProject> ite = projects.iterator();
+         
+        // In case of maven module projects, root.findContainersForLocationURI(...) would return an IFolder
+        // instead of an IProject. So we manually loop through all projects and test their path against the 
+        // current basedirPath. Refreshed projects will be removed from the list for subsequent checks
+        while(ite.hasNext()) {
+          IProject project = ite.next();
+          final IPath projectLocation = project.getLocation();
+          if(projectLocation != null && projectLocation.equals(basedirPath) && project.isAccessible()) {
+            project.refreshLocal(refreshDepth, monitor);
+            count++;
+            ite.remove();
+            break;
+          }
+        }
+        basedirPath = basedirPath.removeLastSegments(1);
+      }
+      
+      return count;
+    } finally {
+      monitor.done();
+    }
+  }
+
+  /**
+   * Returns the underlying file for a given path 
+   * @param project
+   * @param path, ex. WEB-INF/web.xml
+   * @return the underlying file corresponding to path, or null if no file exists.
+   */
+  public static IFile getWebResourceFile(IProject project, String path) {
+      IVirtualComponent component = ComponentCore.createComponent(project);
+      if (component == null) {
+       return null;
+      }
+      IPath filePath = new Path(path);
+      IContainer[] underlyingFolders = component.getRootFolder().getUnderlyingFolders();
+      for (IContainer underlyingFolder : underlyingFolders) {
+        IPath p = underlyingFolder.getProjectRelativePath().append(filePath);
+        IFile f = project.getFile(p);
+        if (f.exists()) {
+         return f;
+        }
+      }
+      return null;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/RarPluginConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/RarPluginConfiguration.java
new file mode 100644
index 0000000..7ac715e
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/RarPluginConfiguration.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * maven-rar-plugin configuration model.
+ * 
+ * @see <a href="maven.apache.org/plugins/maven-rar-plugin/rar-mojo.html">maven.apache.org/plugins/maven-rar-plugin/rar-mojo.html</a>
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class RarPluginConfiguration {
+
+  private static final Logger LOG = LoggerFactory.getLogger(RarPluginConfiguration.class) ;
+
+  private static final String RAR_DEFAULT_CONTENT_DIR = "src/main/rar";  //$NON-NLS-1$
+
+  private static final String RA_XML = "META-INF/ra.xml"; //$NON-NLS-1$
+
+  private static final int JCA_1_6_ID = 16;//Exists in WTP >= 3.2 only
+
+  private static final int JCA_1_7_ID = 17;//Exists in WTP >= 3.5 only
+
+
+  final Plugin plugin;
+  
+  final IMavenProjectFacade rarFacade;
+  
+  
+  public RarPluginConfiguration(IMavenProjectFacade facade) throws CoreException {
+    Assert.isNotNull(facade);
+    if (JEEPackaging.RAR != JEEPackaging.getValue(facade.getPackaging()))
+      throw new IllegalArgumentException(Messages.RarPluginConfiguration_Project_Must_Have_rar_Packaging);
+    
+    this.rarFacade = facade;
+    this.plugin = facade.getMavenProject(new NullProgressMonitor()).getPlugin("org.apache.maven.plugins:maven-rar-plugin"); //$NON-NLS-1$
+  }
+
+  /**
+   * @return rar plugin configuration or null.
+   */
+  private Xpp3Dom getConfiguration() {
+    if(plugin == null) {
+      return null;
+    }
+    return (Xpp3Dom) plugin.getConfiguration();
+  }
+
+  /**
+   * Should project classes be included in the resulting RAR?
+   * @return the value of "includeJar". Default is true;
+   */
+  public boolean isJarIncluded() {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom includeJarDom = config.getChild("includeJar"); //$NON-NLS-1$
+      if (includeJarDom != null) {
+        return Boolean.parseBoolean(includeJarDom.getValue().trim());
+      }
+    }
+    return true; 
+  }
+  
+  
+  /**
+   * Gets the rar content directory of the project from pom.xml configuration.
+   * 
+   * @return the first resource directory found in pom.xml.
+   */
+  public String getRarContentDirectory() {
+    IProject project = rarFacade.getProject();
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom contentDirDom = config.getChild("rarSourceDirectory"); //$NON-NLS-1$
+      if(contentDirDom != null && contentDirDom.getValue() != null) {
+        String contentDir = contentDirDom.getValue().trim();
+        contentDir = ProjectUtils.getRelativePath(project, contentDir);
+        contentDir = (contentDir.length() == 0) ? RAR_DEFAULT_CONTENT_DIR : contentDir;
+        return contentDir;
+      }
+    }
+
+    return RAR_DEFAULT_CONTENT_DIR;
+  }
+
+  /**
+   * @return
+   */
+  public IProjectFacetVersion getConnectorFacetVersion() {
+      IFile raXml = getRaXml();
+      
+      if(raXml != null && raXml.isAccessible()) {
+        try {
+          InputStream is = raXml.getContents();
+          try {
+            JavaEEQuickPeek jqp = new JavaEEQuickPeek(is);
+            switch(jqp.getVersion()) {
+              case J2EEVersionConstants.JCA_1_0_ID:
+                return IJ2EEFacetConstants.JCA_10;
+              case J2EEVersionConstants.JCA_1_5_ID:
+                return IJ2EEFacetConstants.JCA_15;
+              case JCA_1_6_ID:
+                //Don't create a static 1.6 facet version, it'd blow up WTP < 3.2
+                return IJ2EEFacetConstants.JCA_FACET.getVersion("1.6");//only exists in WTP version >= 3.2 //$NON-NLS-1$
+              case JCA_1_7_ID:
+                //Don't create a static 1.7 facet version, it'd blow up WTP < 3.5
+                return IJ2EEFacetConstants.JCA_FACET.getVersion("1.7");//only exists in WTP version >= 3.5 //$NON-NLS-1$
+            }
+          } finally {
+            is.close();
+          }
+        } catch(IOException ex) {
+          // expected
+        } catch(CoreException ex) {
+          // expected
+        }
+      }
+
+      IProject project = rarFacade.getProject();
+      //If no rar.xml found, don't change existing facet version
+      try {
+          IFacetedProject fProject = ProjectFacetsManager.create(project);
+          if (fProject != null && fProject.hasProjectFacet(IJ2EEFacetConstants.JCA_FACET)) {
+            return fProject.getProjectFacetVersion(IJ2EEFacetConstants.JCA_FACET);
+          }
+        } catch (Exception e) {
+          LOG.warn(NLS.bind(Messages.Error_Reading_Project_Facet, project.getName()), e); 
+        }      
+      
+      //If no ra.xml found and the project depends and WTP >= 3.2, then set connector facet to 1.6
+      //TODO see if other conditions might apply to differentiate JCA 1.6 from 1.5
+      return IJ2EEFacetConstants.JCA_FACET.getVersion("1.6"); //$NON-NLS-1$
+    }
+
+  /**
+   * Get the custom location of ra.xml, as set in &lt;raXmlFile&gt;.
+   * @return the custom location of ra.xml or null if &lt;raXmlFile&gt; is not set
+   */
+  public String getCustomRaXml() {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom raXmlFileDom = config.getChild("raXmlFile"); //$NON-NLS-1$
+      if(raXmlFileDom != null && raXmlFileDom.getValue() != null) {
+        String raXmlFile = raXmlFileDom.getValue().trim();
+        raXmlFile = ProjectUtils.getRelativePath(rarFacade.getProject(), raXmlFile);
+        return raXmlFile;
+      }
+    }
+    return null;
+  }
+
+  public IFile getRaXml() {
+    IProject project = rarFacade.getProject();
+    String customRaXmlPath = getCustomRaXml();
+    IFile raXml = null;
+    if (customRaXmlPath != null ) {
+      raXml = project.getFile(customRaXmlPath);
+    }
+    if (raXml == null || !raXml.isAccessible()) {
+      raXml = project.getFolder(getRarContentDirectory()).getFile(RA_XML);
+    }
+    if (!raXml.isAccessible()) {
+      for (IPath resourcePath : rarFacade.getResourceLocations()) {
+        raXml = project.getFolder(resourcePath).getFile(RA_XML);
+        if (raXml.isAccessible()) {
+          break;
+        }
+      }
+    }
+    return raXml;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ResourceCleaner.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ResourceCleaner.java
new file mode 100644
index 0000000..3634294
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/ResourceCleaner.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Utility class used to delete generated resources.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class ResourceCleaner {
+  
+  private static final Path EMPTY_PATH = new Path(""); //$NON-NLS-1$
+
+  private final IProject project;
+
+  private List<IFolder> folders = new ArrayList<>(); 
+
+  private List<IFile> files = new ArrayList<>(); 
+  
+  private Set<IFolder> keepers = new HashSet<>();
+
+  /**
+   * @param project
+   */
+  public ResourceCleaner(IProject project) {
+    this.project = project;
+  }
+
+  public ResourceCleaner(IProject project, IFolder ... foldersToKeep) {
+    this.project = project;
+    if (foldersToKeep != null) {
+      for (IFolder folder : foldersToKeep) {
+        if (folder != null) {
+          keepers.add(folder);
+          IContainer parent = folder.getParent();
+          while (parent instanceof IFolder) {
+            keepers.add((IFolder)parent);
+            parent = parent.getParent();
+          }
+        }
+      }
+    }
+  }
+
+  
+  public void addFolder(IPath folderPath) {
+    if (folderPath == null || EMPTY_PATH.equals(folderPath)) {
+      return;
+    }
+    addFolder(project.getFolder(folderPath));
+  }
+
+  public void addFolder(IFolder folder) {
+    if (folder != null && !folder.exists()) {
+      if (!folder.getProject().getFullPath().equals(folder.getFullPath())){
+        folders.add(folder);
+        addInexistentParentFolders(folder);
+      }
+    }
+  }
+
+  public void addFiles(IPath ... filePaths) {
+    if (filePaths == null) {
+      return;
+    }
+    for (IPath fileName : filePaths) {
+      IFile fileToDelete = project.getFile(fileName);
+      if (!fileToDelete.exists()) {
+        files.add(fileToDelete);
+        addInexistentParentFolders(fileToDelete);
+      }
+    }
+  }
+
+  public void addFiles(IFile ... filesToDelete) {
+    if (filesToDelete == null) {
+      return;
+    }
+    for (IFile fileToDelete : filesToDelete) {
+      if (!fileToDelete.exists()) {
+        files.add(fileToDelete);
+        addInexistentParentFolders(fileToDelete);
+      }
+    }
+  }
+
+  public void cleanUp() throws CoreException {
+    IProgressMonitor monitor = new NullProgressMonitor();
+    for (IFile file : files) {
+      if (file.exists()) {
+        file.delete(true, monitor);
+      }
+    }
+    for (IFolder folder : folders) {
+      if (folder.exists() && folder.members().length == 0) {
+        folder.delete(true, monitor);
+      }
+    }
+  }
+  
+  protected void addInexistentParentFolders(IResource resource) {
+    IContainer parentContainer = resource.getParent();
+    while (parentContainer instanceof IFolder) {
+      if (keepers.contains(parentContainer) 
+          || parentContainer.exists()) {
+        break;
+      }
+      IFolder parent = (IFolder)parentContainer;
+      folders.add(parent);
+      parentContainer = parentContainer.getParent();
+    }
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/UnsupportedDependencyTypeProjectConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/UnsupportedDependencyTypeProjectConfigurator.java
new file mode 100644
index 0000000..1957afb
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/UnsupportedDependencyTypeProjectConfigurator.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2012-2014 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import static org.eclipse.m2e.wtp.MavenWtpConstants.WTP_MARKER_UNSUPPORTED_DEPENDENCY_PROBLEM;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Dependency;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.m2e.core.internal.markers.SourceLocation;
+import org.eclipse.m2e.core.internal.markers.SourceLocationHelper;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.MavenProjectChangedEvent;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+
+
+/**
+ * Configurator used to display warnings on projects depending on unsupported Maven packages.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ *
+ * @author Fred Bricon
+ * 
+ */
+public class UnsupportedDependencyTypeProjectConfigurator extends AbstractProjectConfigurator {
+
+  private static final Set<String> UNSUPPORTED_DEPENDENCY_TYPES;
+
+  static {
+    UNSUPPORTED_DEPENDENCY_TYPES = new HashSet<>(Arrays.asList(new String[] {"ejb-client", "test-jar"})); //$NON-NLS-1$ //$NON-NLS-2$
+  }
+
+  @Override
+  public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
+	  checkUnsupportedWorkspaceDependency(monitor, request.getMavenProjectFacade());
+  }
+
+  @Override
+  public void mavenProjectChanged(MavenProjectChangedEvent event, IProgressMonitor monitor) throws CoreException {
+    checkUnsupportedWorkspaceDependency(monitor, event.getMavenProject());
+  }
+
+/**
+ * @param monitor
+ * @param facade
+ * @throws CoreException
+ */
+private void checkUnsupportedWorkspaceDependency(IProgressMonitor monitor,
+		IMavenProjectFacade facade) throws CoreException {
+	if(facade == null) {
+      return;
+    }
+    
+    clearWarnings(facade.getPom());
+
+    if (WTPProjectsUtil.isM2eWtpDisabled(facade, monitor) || !ModuleCoreNature.isFlexibleProject(facade.getProject())) {
+      //Not a WTP project
+      return;
+    }
+
+    //Constraints only applies when workspace project resolution is active
+    if(!facade.getResolverConfiguration().shouldResolveWorkspaceProjects()) {
+      return;
+    }
+
+    for(Artifact a : facade.getMavenProject().getArtifacts()) {
+      String type = a.getType();
+      if(isUnsupported(type)) {
+        IMavenProjectFacade workspaceDependency = getWorkspaceProject(a);
+        if(workspaceDependency != null) {
+          Dependency dependency = getDependency(a, facade.getMavenProject().getDependencies());
+          int lineNumber = -1;
+          if(dependency != null) {
+            SourceLocation location = SourceLocationHelper.findLocation(facade.getMavenProject(), dependency);
+            lineNumber = location.getLineNumber();
+          }
+          addWarning(facade.getPom(), workspaceDependency, type, lineNumber);
+        }
+      }
+    }
+}
+
+  private void clearWarnings(IResource resource) throws CoreException {
+    markerManager.deleteMarkers(resource, WTP_MARKER_UNSUPPORTED_DEPENDENCY_PROBLEM);
+  }
+
+  private boolean isUnsupported(String type) {
+    return UNSUPPORTED_DEPENDENCY_TYPES.contains(type);
+  }
+
+  private IMavenProjectFacade getWorkspaceProject(Artifact artifact) {
+    return projectManager.getMavenProject(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
+  }
+
+  private Dependency getDependency(Artifact a, List<Dependency> dependencies) {
+    for(Dependency d : dependencies) {
+      if(StringUtils.equals(a.getArtifactId(), d.getArtifactId()) && StringUtils.equals(a.getGroupId(), d.getGroupId())
+          && StringUtils.equals(a.getVersion(), d.getVersion())
+          && StringUtils.equals(a.getClassifier(), a.getClassifier())
+        ) {
+        String dType = (StringUtils.isBlank(d.getType()))?"jar":d.getType(); //$NON-NLS-1$
+        String aType = (StringUtils.isBlank(a.getType()))?"jar":a.getType(); //$NON-NLS-1$
+        if (aType.equals(dType)) {
+          return d;
+        }
+      }
+    }
+    return null;
+  }
+
+  private void addWarning(IResource resource, IMavenProjectFacade workspaceDependency, String type, int lineNumber) {
+    String warning = NLS.bind(Messages.markers_unsupported_dependencies_warning, workspaceDependency.getProject().getName(), type);
+    markerManager.addMarker(resource, WTP_MARKER_UNSUPPORTED_DEPENDENCY_PROBLEM, warning, lineNumber,
+        IMarker.SEVERITY_WARNING);
+  }
+
+  @Override
+  public boolean hasConfigurationChanged(IMavenProjectFacade newFacade,
+			ILifecycleMappingConfiguration oldProjectConfiguration,
+			MojoExecutionKey key, IProgressMonitor monitor) {
+	return false;
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/UtilityProjectConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/UtilityProjectConfigurator.java
new file mode 100644
index 0000000..26e2371
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/UtilityProjectConfigurator.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.installJavaFacet;
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeTestFolderLinks;
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeWTPClasspathContainer;
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.setNonDependencyAttributeToContainer;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.eclipse.wst.validation.ValidationFramework;
+
+/**
+ * Utility Project Configurator. Allows to update the WTP configuration of Utility projects
+ *  on Maven Update project configuration.<br/>  
+ *  This configurator is secondary to the JavaConfigurator.
+ *  
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class UtilityProjectConfigurator extends AbstractProjectConfigurator {
+
+  @Override
+  public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
+
+    IProject project = request.getProject();
+    if (WTPProjectsUtil.isM2eWtpDisabled(request.getMavenProjectFacade(), monitor) || !project.isAccessible() || project.getResourceAttributes().isReadOnly()) {
+      return;
+    }
+    
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project);
+
+    // Only reconfigure utility projects 
+    if(facetedProject != null && facetedProject.hasProjectFacet(WTPProjectsUtil.UTILITY_FACET)) {
+
+      MavenProject mavenProject = request.getMavenProject();
+
+      Set<Action> actions = new LinkedHashSet<>();
+      installJavaFacet(actions, project, facetedProject);
+      if(!actions.isEmpty()) {
+        facetedProject.modify(actions, monitor);
+      }
+
+      removeWTPClasspathContainer(project);
+
+      removeTestFolderLinks(project, mavenProject, monitor, "/");  //$NON-NLS-1$
+
+      //MECLIPSEWTP-125 Remove "MAVEN2_CLASSPATH_CONTAINER will not be exported or published" warning.
+      setNonDependencyAttributeToContainer(project, monitor);
+
+      IFolder buildFolder = project.getFolder(ProjectUtils.getBuildFolder(mavenProject, project));
+      ValidationFramework.getDefault().disableValidation(buildFolder);
+    }
+    
+  }
+
+
+  @Override
+  public boolean hasConfigurationChanged(IMavenProjectFacade newFacade, ILifecycleMappingConfiguration oldProjectConfiguration, MojoExecutionKey key, IProgressMonitor monitor) {
+
+    if (WTPProjectsUtil.isM2eWtpDisabled(newFacade, monitor)) {
+      return false;
+    }
+
+    return super.hasConfigurationChanged(newFacade, oldProjectConfiguration, key, monitor);
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WTPProjectConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WTPProjectConfigurator.java
new file mode 100644
index 0000000..35cd79f
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WTPProjectConfigurator.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2015 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.m2e.core.lifecyclemapping.model.IPluginExecutionMetadata;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.MavenProjectChangedEvent;
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
+import org.eclipse.m2e.jdt.IClasspathDescriptor;
+import org.eclipse.m2e.jdt.IJavaProjectConfigurator;
+import org.eclipse.m2e.wtp.internal.build.WarProjectBuildParticipant;
+import org.eclipse.m2e.wtp.internal.filtering.EarResourceBuildParticipant;
+import org.eclipse.m2e.wtp.internal.filtering.ResourceFilteringBuildParticipant;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.validation.ValidationFramework;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Project configurator for WTP projects. Specific project configuration is delegated to the
+ * IProjectConfiguratorDelegate bound to a maven packaging type.
+ *
+ * @provisional This class has been added as part of a work in progress.
+ * It is not guaranteed to work or remain the same in future releases.
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ *
+ * @author Igor Fedorenko
+ * @author Fred Bricon
+ */
+public class WTPProjectConfigurator extends AbstractProjectConfigurator implements IJavaProjectConfigurator {
+
+  private static final Logger LOG = LoggerFactory.getLogger(WTPProjectConfigurator.class);
+
+  @Override
+  public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor)
+      throws CoreException {
+
+    IProject project = request.getProject();
+    if (WTPProjectsUtil.isM2eWtpDisabled(request.getMavenProjectFacade(), monitor)) {
+      return;
+    }
+
+    MavenProject mavenProject = request.getMavenProject();
+    //Lookup the project configurator
+    IProjectConfiguratorDelegate configuratorDelegate = ProjectConfiguratorDelegateFactory
+        .getProjectConfiguratorDelegate(mavenProject.getPackaging());
+    if(configuratorDelegate != null) {
+      if (project.getResourceAttributes().isReadOnly()){
+        return;
+      }
+
+      try {
+        configuratorDelegate.configureProject(project, mavenProject, monitor);
+      } catch(MarkedException ex) {
+        LOG.error(ex.getMessage(), ex);
+      }
+
+      IFolder buildFolder = project.getFolder(ProjectUtils.getBuildFolder(mavenProject, project));
+      ValidationFramework.getDefault().disableValidation(buildFolder);
+    }
+  }
+
+  @Override
+  public void mavenProjectChanged(MavenProjectChangedEvent event, IProgressMonitor monitor) throws CoreException {
+    IMavenProjectFacade facade = event.getMavenProject();
+    if(facade != null) {
+      IProject project = facade.getProject();
+
+      if (!isWTPProject(project) || WTPProjectsUtil.isM2eWtpDisabled(facade, monitor)
+          || project.getResourceAttributes().isReadOnly()){
+        return;
+      }
+
+      MavenProject mavenProject = facade.getMavenProject(monitor);
+      IProjectConfiguratorDelegate configuratorDelegate = ProjectConfiguratorDelegateFactory
+          .getProjectConfiguratorDelegate(mavenProject.getPackaging());
+      if(configuratorDelegate != null) {
+        configuratorDelegate.setModuleDependencies(project, mavenProject, monitor);
+      }
+    }
+  }
+
+  protected static boolean isWTPProject(IProject project) {
+    return ModuleCoreNature.isFlexibleProject(project);
+  }
+
+  @Override
+  public void configureClasspath(IMavenProjectFacade facade, IClasspathDescriptor classpath, IProgressMonitor monitor)
+      throws CoreException {
+    IProject project = facade.getProject();
+    if (WTPProjectsUtil.isM2eWtpDisabled(facade, monitor)) {
+      return;
+    }
+
+    MavenProject mavenProject = facade.getMavenProject(monitor);
+    //Lookup the project configurator
+    IProjectConfiguratorDelegate configuratorDelegate = ProjectConfiguratorDelegateFactory
+        .getProjectConfiguratorDelegate(mavenProject.getPackaging());
+    if(configuratorDelegate != null) {
+      try {
+        configuratorDelegate.configureClasspath(project, mavenProject, classpath, monitor);
+      } catch(CoreException ex) {
+        LOG.error(ex.getMessage(), ex);
+      }
+    }
+  }
+
+  @Override
+  public void configureRawClasspath(ProjectConfigurationRequest request, IClasspathDescriptor classpath,
+      IProgressMonitor monitor) throws CoreException {
+    // we do not change raw project classpath, do we?
+  }
+
+  @Override
+  public AbstractBuildParticipant getBuildParticipant(IMavenProjectFacade projectFacade, MojoExecution execution,
+      IPluginExecutionMetadata executionMetadata) {
+
+    if (WTPProjectsUtil.isM2eWtpDisabled(projectFacade, new NullProgressMonitor())) {
+      return null;
+    }
+
+    //FIXME should refactor that by removing the project configurator delegates
+    if ("maven-war-plugin".equals(execution.getArtifactId()) && "war".equals(execution.getGoal())) {//$NON-NLS-1$ //$NON-NLS-2$
+    	return new WarProjectBuildParticipant();
+    } else if ("maven-acr-plugin".equals(execution.getArtifactId()) && "acr".equals(execution.getGoal())) { //$NON-NLS-1$ //$NON-NLS-2$
+      return new ResourceFilteringBuildParticipant();
+    } else if ("maven-ear-plugin".equals(execution.getArtifactId()) && "generate-application-xml".equals(execution.getGoal())) { //$NON-NLS-1$ //$NON-NLS-2$
+      return new EarResourceBuildParticipant();
+    }
+    return null;
+  }
+
+
+  @Override
+  public boolean hasConfigurationChanged(IMavenProjectFacade newFacade,
+      ILifecycleMappingConfiguration oldProjectConfiguration,
+      MojoExecutionKey key, IProgressMonitor monitor) {
+
+    if (WTPProjectsUtil.isM2eWtpDisabled(newFacade, monitor)) {
+      return false;
+    }
+
+    return super.hasConfigurationChanged(newFacade, oldProjectConfiguration, key, monitor);
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WTPProjectsUtil.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WTPProjectsUtil.java
new file mode 100644
index 0000000..342076c
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WTPProjectsUtil.java
@@ -0,0 +1,668 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jst.common.project.facet.core.JavaFacet;
+import org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil;
+import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
+import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
+import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
+import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.internal.lifecyclemapping.LifecycleMappingFactory;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.MavenProjectUtils;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.jdt.internal.MavenClasspathHelpers;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.internal.webfragment.WebFragmentUtil;
+import org.eclipse.m2e.wtp.overlay.modulecore.IOverlayVirtualComponent;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.common.componentcore.internal.ComponentResource;
+import org.eclipse.wst.common.componentcore.internal.StructureEdit;
+import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
+import org.eclipse.wst.common.componentcore.internal.impl.ResourceTreeNode;
+import org.eclipse.wst.common.componentcore.internal.impl.ResourceTreeRoot;
+import org.eclipse.wst.common.componentcore.internal.util.FacetedProjectUtilities;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class for WTP projects.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+public class WTPProjectsUtil {
+
+  private static final Logger LOG = LoggerFactory.getLogger(WTPProjectsUtil.class);
+
+  public static final IProjectFacet UTILITY_FACET = ProjectFacetsManager.getProjectFacet(IJ2EEFacetConstants.UTILITY);
+
+  public static final IProjectFacetVersion UTILITY_10 = UTILITY_FACET.getVersion("1.0"); //$NON-NLS-1$
+
+  public static final IProjectFacet EJB_FACET = ProjectFacetsManager.getProjectFacet(IJ2EEFacetConstants.EJB);
+
+  public static final IProjectFacet JCA_FACET = ProjectFacetsManager.getProjectFacet(IJ2EEFacetConstants.JCA);
+  
+  public static final IProjectFacet WEB_FRAGMENT_FACET = ProjectFacetsManager.getProjectFacet(IJ2EEFacetConstants.WEBFRAGMENT);
+
+  public static final IProjectFacetVersion WEB_FRAGMENT_3_0 = WEB_FRAGMENT_FACET.getVersion("3.0"); //$NON-NLS-1$
+
+  public static final IProjectFacet DYNAMIC_WEB_FACET = ProjectFacetsManager
+      .getProjectFacet(IJ2EEFacetConstants.DYNAMIC_WEB);
+
+  public static final IProjectFacet APP_CLIENT_FACET = ProjectFacetsManager.getProjectFacet(IJ2EEFacetConstants.APPLICATION_CLIENT);
+
+  public static final IClasspathAttribute NONDEPENDENCY_ATTRIBUTE = JavaCore.newClasspathAttribute(
+      IClasspathDependencyConstants.CLASSPATH_COMPONENT_NON_DEPENDENCY, "");//$NON-NLS-1$
+
+  /**
+   * Defaults Web facet version to 2.5
+   */
+  public static final IProjectFacetVersion DEFAULT_WEB_FACET = DYNAMIC_WEB_FACET.getVersion("2.5"); //$NON-NLS-1$
+
+  public static final IProjectFacet EAR_FACET = ProjectFacetsManager
+      .getProjectFacet(IJ2EEFacetConstants.ENTERPRISE_APPLICATION);
+
+  public static final String DYN_REQUESTED_REFERENCE_TYPE;
+
+  public static final String M2E_WTP_ACTIVATION_PROPERTY = "m2e.wtp.activation"; //$NON-NLS-1$
+  
+  //TODO Clean that up for Eclipse Mars
+  static {
+    //Bug #385605 : IVirtualComponent.DISPLAYABLE_REFERENCES_ALL is not available in helios
+    String reqRefType = null;
+    try {
+      Field displayableRefsAllField = IVirtualComponent.class.getField("DISPLAYABLE_REFERENCES_ALL"); //$NON-NLS-1$
+      reqRefType = (String)displayableRefsAllField.get(null);
+    } catch(Throwable e) {
+      //Falling back on IVirtualComponent.HARD_REFERENCES works in helios wrt bug #385229 : 
+      reqRefType = IVirtualComponent.HARD_REFERENCES;
+    }
+    DYN_REQUESTED_REFERENCE_TYPE = reqRefType;
+  }
+  
+  /**
+   * Checks if a project has a given class in its classpath 
+   * @param project : the workspace project
+   * @param className : the fully qualified name of the class to search for
+   * @return true if className is found in the project's classpath (provided the project is a JavaProject and its classpath has been set.)   
+   */
+  public static boolean hasInClassPath(IProject project, String className) {
+    boolean result = false;
+    if (project != null){
+      IJavaProject javaProject = JavaCore.create(project);
+      try {
+        if (javaProject!= null && javaProject.findType(className)!=null){
+         result = true; 
+        }
+      } catch(JavaModelException ex) {
+        //Ignore this
+      }
+    }
+    return result;
+  }
+
+  
+  /**
+   * Checks if the project is one of Dynamic Web, EJB, Application client, EAR or JCA project.
+   * @param project - the project to be checked.
+   * @return true if the project is a JEE - or legacy J2EE - project (but not a utility project). 
+   */
+  public static boolean isJavaEEProject(IProject project) {
+    return (J2EEProjectUtilities.isLegacyJ2EEProject(project) || J2EEProjectUtilities.isJEEProject(project)) && !JavaEEProjectUtilities.isUtilityProject(project); 
+  }
+  
+  /**
+   * Delete a project's component resources having a given runtimePath
+   * @param project - the project to modify
+   * @param runtimePath - the component resource runtime path (i.e. deploy path)
+   * @param monitor - an eclipse monitor
+   * @throws CoreException
+   */
+  public static void deleteLinks(IProject project, IPath runtimePath, IProgressMonitor monitor) throws CoreException {
+    deleteLinks(project, runtimePath, null, monitor);
+  }
+
+  /**
+   * Delete a project's component resources having a given runtimePath
+   * @param project - the project to modify
+   * @param runtimePath - the component resource runtime path (i.e. deploy path)
+   * @param sourcePathToKeep - the list of source paths to keep
+   * @param monitor - an eclipse monitor
+   * @throws CoreException
+   */
+  public static void deleteLinks(IProject project, IPath runtimePath, List<IPath> sourcePathToKeep, IProgressMonitor monitor) throws CoreException {
+    //Looks like WTP'APIS doesn't have such feature, hence this implementation.
+    StructureEdit moduleCore = null;
+    try {
+      moduleCore = StructureEdit.getStructureEditForWrite(project);
+      if (moduleCore == null) {
+        return;
+      }
+      WorkbenchComponent component = moduleCore.getComponent();
+      if (component == null)  {
+        return;
+      }
+      ResourceTreeRoot root = ResourceTreeRoot.getDeployResourceTreeRoot(component);
+      ComponentResource[] resources = root.findModuleResources(runtimePath, 0);
+      for (ComponentResource link : resources) {
+        if (runtimePath.equals(link.getRuntimePath()) && 
+           (sourcePathToKeep == null || !sourcePathToKeep.contains(link.getSourcePath()))) {
+          component.getResources().remove(link);
+        }
+      }
+   }
+   finally {
+     if (moduleCore != null) {
+       moduleCore.saveIfNecessary(monitor);
+       moduleCore.dispose();
+     }
+    }
+  }
+  
+  public static void insertLinkBefore(IProject project, IPath newSource, IPath referenceSource, IPath runtimePath, IProgressMonitor monitor) throws CoreException {
+    //Looks like WTP'APIS doesn't have such feature, hence this implementation.
+    StructureEdit moduleCore = null;
+    try {
+      moduleCore = StructureEdit.getStructureEditForWrite(project);
+      if (moduleCore == null) {
+        return;
+      }
+      WorkbenchComponent component = moduleCore.getComponent();
+      if (component == null)  {
+        return;
+      }
+      
+      int i = 0;
+      int refPosition = -1;
+      int newSourcePosition = -1;
+      List<ComponentResource> resources = component.getResources();
+      
+      for (ComponentResource resource : resources) {
+        IPath sourcePath = resource.getSourcePath();
+        if (referenceSource.equals(sourcePath)) {
+          refPosition = i;
+        } else if (newSource.equals(sourcePath)) {
+          newSourcePosition = i;
+        }
+        if (refPosition > -1 &&  newSourcePosition > -1) {
+          break;
+        }
+        i++;
+      }
+      if (refPosition < 0) {
+        refPosition = i;
+      }
+      IResource folder = project.getFolder(newSource);
+      if (newSourcePosition > refPosition) {
+        component.getResources().move(newSourcePosition, refPosition);
+      } else if (newSourcePosition < 0) {
+        ComponentResource componentResource = moduleCore.createWorkbenchModuleResource(folder);
+        componentResource.setRuntimePath(runtimePath);
+        component.getResources().add(refPosition,componentResource);
+      }
+   }
+   finally {
+     if (moduleCore != null) {
+       moduleCore.saveIfNecessary(monitor);
+       moduleCore.dispose();
+     }
+    }
+  }
+
+  public static void insertLinkFirst(IProject project, IPath newSource, IPath runtimePath, IProgressMonitor monitor) throws CoreException {
+    //Looks like WTP'APIS doesn't have such feature, hence this implementation.
+    StructureEdit moduleCore = null;
+    try {
+      moduleCore = StructureEdit.getStructureEditForWrite(project);
+      if (moduleCore == null) {
+        return;
+      }
+      WorkbenchComponent component = moduleCore.getComponent();
+      if (component == null)  {
+        return;
+      }
+      
+      IResource folder = project.getFolder(newSource);
+      ComponentResource componentResource = moduleCore.createWorkbenchModuleResource(folder);
+      componentResource.setRuntimePath(runtimePath);
+      component.getResources().add(0,componentResource);
+   }
+   finally {
+     if (moduleCore != null) {
+       moduleCore.saveIfNecessary(monitor);
+       moduleCore.dispose();
+     }
+    }
+  }
+  
+  public static boolean hasLink(IProject project, IPath runtimePath, IPath aProjectRelativeLocation, IProgressMonitor monitor) throws CoreException {
+    StructureEdit moduleCore = null;
+    try {
+      moduleCore = StructureEdit.getStructureEditForRead(project);
+      if( moduleCore != null ) {
+        WorkbenchComponent component = moduleCore.getComponent();
+        if (component != null) {
+          ResourceTreeRoot root = ResourceTreeRoot.getDeployResourceTreeRoot(component);
+          ComponentResource[] resources = root.findModuleResources(runtimePath, ResourceTreeNode.CREATE_NONE);
+          if (resources.length > 0) {
+            for (int resourceIndx = 0; resourceIndx < resources.length; resourceIndx++) {
+              if (aProjectRelativeLocation.makeAbsolute().equals(resources[resourceIndx].getSourcePath())) {
+                return true;
+              }
+            }
+          }
+        }
+      }
+    }
+    finally {
+      if (moduleCore != null) {
+        moduleCore.dispose();
+      }
+    }
+    return false;
+  }
+
+  /**
+   * @param project
+   * @param dir
+   * @return
+   */
+  public static IPath tryProjectRelativePath(IProject project, String resourceLocation) {
+    if(resourceLocation == null) {
+      return null;
+    }
+    IPath projectLocation = project.getLocation();
+    IPath directory = Path.fromOSString(resourceLocation); // this is an absolute path!
+    if(projectLocation == null || !projectLocation.isPrefixOf(directory)) {
+      return directory;
+    }
+    return directory.removeFirstSegments(projectLocation.segmentCount()).makeRelative().setDevice(null);
+  }
+  
+  
+  public static boolean hasChanged(IVirtualReference[] existingRefs, IVirtualReference[] refArray) {
+    
+    if (existingRefs==refArray) {
+      return false;
+    }
+    if (existingRefs == null || existingRefs.length != refArray.length) {
+      return true;
+    }
+    for (int i=0; i<existingRefs.length;i++){
+      IVirtualReference existingRef = existingRefs[i];
+      IVirtualReference newRef = refArray[i];
+      if ((existingRef.getArchiveName() != null && !existingRef.getArchiveName().equals(newRef.getArchiveName())) ||
+          (existingRef.getArchiveName() == null && newRef.getArchiveName() != null) ||
+          !existingRef.getReferencedComponent().equals(newRef.getReferencedComponent()) ||
+          !existingRef.getRuntimePath().equals(newRef.getRuntimePath())) 
+      {
+        return true;  
+      }
+    }
+    return false;    
+  }
+  
+  public static boolean hasChanged2(IVirtualReference[] existingRefs, IVirtualReference[] refArray) {
+    
+    if (existingRefs==refArray) {
+      return false;
+    }
+    if (existingRefs == null || existingRefs.length != refArray.length) {
+      return true;
+    }
+    for (int i=0; i<existingRefs.length;i++){
+      IVirtualReference existingRef = existingRefs[i];
+      IVirtualReference newRef = refArray[i];
+      if (
+          !existingRef.getReferencedComponent().equals(newRef.getReferencedComponent()) ||
+          !existingRef.getRuntimePath().equals(newRef.getRuntimePath())) 
+      {
+        return true;  
+      }
+    }
+    return false;    
+  }
+  
+  public static IVirtualReference[] extractHardReferences(IVirtualComponent warComponent, boolean overlays) {
+    Map<String, Object> options = new HashMap<String, Object>(1);
+    options.put(IVirtualComponent.REQUESTED_REFERENCE_TYPE, DYN_REQUESTED_REFERENCE_TYPE);
+    IVirtualReference[] allReferences = warComponent.getReferences(options);
+    if (allReferences == null || allReferences.length == 0) {
+      return new IVirtualReference[]{};
+    }
+    
+    List<IVirtualReference> selectedRefs = new ArrayList<>();
+    for (IVirtualReference ref  : allReferences) {
+      IVirtualComponent component = ref.getReferencedComponent();
+      if (component != null) {
+        if (component instanceof IOverlayVirtualComponent) {
+          if (overlays) {
+            selectedRefs.add(ref);
+          }
+        } else {
+          if (!overlays) {
+            selectedRefs.add(ref);
+          }
+        }
+      }
+    }
+    
+    IVirtualReference[] selectedReferences = new IVirtualReference[selectedRefs.size()]; 
+    selectedRefs.toArray(selectedReferences);
+    return selectedReferences;
+  }
+
+  /**
+   * Remove the WTP classpath containers that might conflicts with the Maven Library 
+   * classpath container 
+   * @param project
+   * @throws JavaModelException
+   */
+  public static void removeWTPClasspathContainer(IProject project) throws JavaModelException {
+    IJavaProject javaProject = JavaCore.create(project);
+    if(javaProject != null) {
+      // remove classpatch container from JavaProject
+      ArrayList<IClasspathEntry> newEntries = new ArrayList<>();
+      for(IClasspathEntry entry : javaProject.getRawClasspath()) {
+      String path = entry.getPath().toString();
+        if(!"org.eclipse.jst.j2ee.internal.module.container".equals(path) //$NON-NLS-1$
+          && !"org.eclipse.jst.j2ee.internal.web.container".equals(path)) { //$NON-NLS-1$
+            newEntries.add(entry);
+        }
+      }
+      javaProject.setRawClasspath(newEntries.toArray(new IClasspathEntry[newEntries.size()]), null);
+    }
+  }
+
+ /**
+  * Adds uninstall actions of facets from the faceted project that conflict with the given facetVersion. 
+  */
+  public static void removeConflictingFacets(IFacetedProject project, IProjectFacetVersion facetVersion, Set<Action> actions) {
+    if (project == null) {
+      throw new IllegalArgumentException(Messages.WTPProjectsUtil_Project_Cant_Be_Null);
+    }
+    if (facetVersion == null) {
+      throw new IllegalArgumentException(Messages.WTPProjectsUtil_Facet_Version_Cant_Be_Null);
+    }
+    if (actions == null) {
+      throw new IllegalArgumentException(Messages.WTPProjectsUtil_Actions_Cant_Be_Null);
+    }
+    for (IProjectFacetVersion existingFacetVersion : project.getProjectFacets()) {
+      if (facetVersion.conflictsWith(existingFacetVersion)) {
+        actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.UNINSTALL, existingFacetVersion, null));
+      }
+    }
+  }
+
+  /**
+   * @param actions
+   * @param project
+   * @param facetedProject
+   */
+  public static void installJavaFacet(Set<Action> actions, IProject project, IFacetedProject facetedProject) {
+    IProjectFacetVersion javaFv = JavaFacet.FACET.getVersion(JavaFacetUtil.getCompilerLevel(project));
+    if(!facetedProject.hasProjectFacet(JavaFacet.FACET)) {
+      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, javaFv, null));
+    } else if(!facetedProject.hasProjectFacet(javaFv)) {
+      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, javaFv, null));
+    } 
+  }
+
+  /**
+   * @param project
+   * @return
+   */
+  @SuppressWarnings("restriction")
+  public static boolean hasWebFragmentFacet(IProject project) {
+    return FacetedProjectUtilities.isProjectOfType(project, WTPProjectsUtil.WEB_FRAGMENT_FACET.getId());
+  }
+
+  /**
+   * @param mavenProject
+   * @return
+   */
+  public static boolean isQualifiedAsWebFragment(IMavenProjectFacade facade) {
+    return WebFragmentUtil.isQualifiedAsWebFragment(facade);
+  }
+  
+  /**
+   * Return the project's classes folder, a.k.a. output build directory
+   * @param facade
+   * @return the project's classes folder
+   */
+  public static IFolder getClassesFolder(IMavenProjectFacade facade) {
+    final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+    IFolder output = root.getFolder(facade.getOutputLocation());
+    return output;
+  }
+
+
+  public static void removeTestFolderLinks(IProject project, MavenProject mavenProject, IProgressMonitor monitor,
+      String folder) throws CoreException {
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    if (component == null){
+      return;
+    }
+    IVirtualFolder jsrc = component.getRootFolder().getFolder(folder);
+    for(IPath location : MavenProjectUtils.getSourceLocations(project, mavenProject.getTestCompileSourceRoots())) {
+      if (location == null) {
+		continue;
+	}
+      jsrc.removeLink(location, 0, monitor);
+    }
+    for(IPath location : MavenProjectUtils.getResourceLocations(project, mavenProject.getTestResources())) {
+      if (location == null) {
+		continue;
+	}
+      jsrc.removeLink(location, 0, monitor);
+    }
+
+    //MECLIPSEWTP-217 : exclude other test source folders, added by build-helper for instance
+    if (project.hasNature(JavaCore.NATURE_ID)) {
+      IJavaProject javaProject = JavaCore.create(project);
+      if (javaProject == null) {
+        return;
+      }
+      IPath testOutputDirPath = MavenProjectUtils.getProjectRelativePath(project, mavenProject.getBuild().getTestOutputDirectory());
+      if (testOutputDirPath == null) {
+        return;
+      }
+      IPath testPath = project.getFullPath().append(testOutputDirPath);
+      IClasspathEntry[] cpes = javaProject.getRawClasspath();
+      IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+      for (IClasspathEntry cpe : cpes) {
+        if (cpe != null && cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+          IPath outputLocation = cpe.getOutputLocation();
+          if (testPath.equals(outputLocation)) {
+            IPath sourcePath = root.getFolder(cpe.getPath()).getProjectRelativePath();
+            if (sourcePath != null) {
+              jsrc.removeLink(sourcePath, 0, monitor);
+            }
+          }
+        }
+      }
+    }
+  }
+
+
+  public static void setNonDependencyAttributeToContainer(IProject project, IProgressMonitor monitor) throws JavaModelException {
+    updateContainerAttributes(project, NONDEPENDENCY_ATTRIBUTE, IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY, monitor);
+  }
+
+  public static void updateContainerAttributes(IProject project, IClasspathAttribute attributeToAdd, String attributeToDelete, IProgressMonitor monitor)
+  throws JavaModelException {
+    IJavaProject javaProject = JavaCore.create(project);
+    if (javaProject == null) {
+		return;
+	}
+    IClasspathEntry[] cp = javaProject.getRawClasspath();
+    for(int i = 0; i < cp.length; i++ ) {
+      if(IClasspathEntry.CPE_CONTAINER == cp[i].getEntryKind()
+          && MavenClasspathHelpers.isMaven2ClasspathContainer(cp[i].getPath())) {
+        LinkedHashMap<String, IClasspathAttribute> attrs = new LinkedHashMap<>();
+        for(IClasspathAttribute attr : cp[i].getExtraAttributes()) {
+          if (!attr.getName().equals(attributeToDelete)) {
+            attrs.put(attr.getName(), attr);            
+          }
+        }
+        attrs.put(attributeToAdd.getName(), attributeToAdd);
+        IClasspathAttribute[] newAttrs = attrs.values().toArray(new IClasspathAttribute[attrs.size()]);
+        cp[i] = JavaCore.newContainerEntry(cp[i].getPath(), cp[i].getAccessRules(), newAttrs, cp[i].isExported());
+        break;
+      }
+    }
+    javaProject.setRawClasspath(cp, monitor);
+  }
+
+
+  /**
+   * Add the ModuleCoreNature to a project, if necessary.
+   * 
+   * @param project An accessible project.
+   * @param monitor A progress monitor to track the time to completion
+   * @throws CoreException if the ModuleCoreNature cannot be added
+   */
+  public static void fixMissingModuleCoreNature(IProject project, IProgressMonitor monitor) throws CoreException {
+    //MECLIPSEWTP-41 Fix the missing moduleCoreNature
+    if (null == ModuleCoreNature.addModuleCoreNatureIfNecessary(project, monitor)) {
+      //If we can't add the missing nature, then the project is useless, so let's tell the user
+      throw new CoreException(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, NLS.bind(Messages.WTPProjectsUtil_Unable_To_Add_ModuleCoreNature,project.getName()),null));
+    }
+  }
+
+
+  /**
+   * @return true if the Maven project associated ArtifactHandler's language is java.
+   */
+  public static boolean isJavaProject(IMavenProjectFacade facade) {
+    //Java rocks ... not
+    if (facade == null 
+     || facade.getMavenProject() == null
+     || facade.getMavenProject().getArtifact() == null
+     || facade.getMavenProject().getArtifact().getArtifactHandler() == null) {
+      return false;
+    }
+    String language = facade.getMavenProject().getArtifact().getArtifactHandler().getLanguage();
+    return "java".equals(language); //$NON-NLS-1$
+  }
+  
+  /**
+   * Sets the default deployment descriptor folder for Eclipse > Indigo
+   */
+  public static void setDefaultDeploymentDescriptorFolder(IVirtualFolder folder, IPath aProjectRelativeLocation, IProgressMonitor monitor) {
+      IPath currentDefaultLocation = J2EEModuleVirtualComponent.getDefaultDeploymentDescriptorFolder(folder);
+      if (aProjectRelativeLocation.equals(currentDefaultLocation)) {
+        return;
+      }
+      J2EEModuleVirtualComponent.setDefaultDeploymentDescriptorFolder(folder, aProjectRelativeLocation, monitor);
+  }
+
+  
+  /**
+   * Gets the default deployment descriptor folder's relative path. 
+   * @return  An IFolder representing the default folder for deployment descriptor, or null if 
+   *          the default folder is the root of the project.
+   */
+  public static IFolder getDefaultDeploymentDescriptorFolder(IVirtualFolder vFolder) {
+    IPath defaultPath = J2EEModuleVirtualComponent.getDefaultDeploymentDescriptorFolder(vFolder);
+    IFolder folder = null;
+    IVirtualComponent component = vFolder.getComponent();
+    if (defaultPath == null) {
+      IContainer container = vFolder.getUnderlyingFolder();
+      if (container instanceof IFolder) {
+		folder = (IFolder)container;
+	  }
+    } else if (!defaultPath.isRoot()){
+        folder = component.getProject().getFolder(defaultPath);
+    }    
+    return folder;
+  }  
+  
+  public static boolean isWTPProject(IProject project) {
+    return ModuleCoreNature.getModuleCoreNature(project) != null;
+  }
+  
+  public static boolean isM2eWtpDisabled(IMavenProjectFacade facade, IProgressMonitor monitor) {
+	if (facade == null) {
+	  return true;
+	}
+	MavenProject mavenProject;
+	Object pomActivationValue = null; 
+	try {
+		mavenProject = facade.getMavenProject(monitor);
+		pomActivationValue = mavenProject == null? null : mavenProject.getProperties().get(M2E_WTP_ACTIVATION_PROPERTY);
+	} catch (CoreException ex) {
+		// TODO Auto-generated catch block
+		LOG.error("Unable to load Maven project",ex); //$NON-NLS-1$
+	}
+	boolean enabled;
+	if (pomActivationValue == null) {
+	  enabled = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().getPreferences(facade.getProject()).isEnabled();
+	} else {
+	  enabled = Boolean.parseBoolean(pomActivationValue.toString());
+	}	
+	return !enabled;
+  }
+
+
+  public static boolean isLastConfigurator(IMavenProjectFacade facade, Class<? extends AbstractProjectConfigurator> clazz, String id) {
+	String  lastConfigurator = null;
+	Map<String, AbstractProjectConfigurator> configurators = LifecycleMappingFactory.getProjectConfigurators(facade);
+	for (Map.Entry<String, AbstractProjectConfigurator> e : configurators.entrySet()) {
+		if (e.getValue().getClass().equals(clazz)){
+			lastConfigurator = e.getKey();
+		}
+	}
+	return id.equals(lastConfigurator);
+  }  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WarPluginConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WarPluginConfiguration.java
new file mode 100644
index 0000000..9e5504b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WarPluginConfiguration.java
@@ -0,0 +1,425 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2015 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.war.Overlay;
+import org.apache.maven.plugin.war.overlay.InvalidOverlayConfigurationException;
+import org.apache.maven.plugin.war.overlay.OverlayManager;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
+import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils;
+import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.internal.markers.SourceLocation;
+import org.eclipse.m2e.core.internal.markers.SourceLocationHelper;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.internal.StringUtils;
+import org.eclipse.m2e.wtp.namemapping.FileNameMapping;
+import org.eclipse.m2e.wtp.namemapping.PatternBasedFileNameMapping;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ *  maven-war-plugin configuration model.
+ *  
+ * @see <a href="http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html">http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html</a>
+ *  
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Igor Fedorenko
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+public class WarPluginConfiguration extends AbstractFilteringSupportMavenPlugin implements IMavenPackageFilter {
+
+  private static final Logger LOG = LoggerFactory.getLogger(WarPluginConfiguration.class);
+  
+  private static final String WAR_SOURCE_FOLDER = "/src/main/webapp"; //$NON-NLS-1$
+
+  private static final String WAR_PACKAGING = "war"; //$NON-NLS-1$
+
+  private static final String WEB_XML = "WEB-INF/web.xml"; //$NON-NLS-1$
+
+  private static final int WEB_3_1_ID = 31;
+
+  private static final String WEB_3_1_TEXT = "3.1"; //$NON-NLS-1$
+  
+  private static final String FAIL_ON_MISSING_WEB_XML = "failOnMissingWebXml";
+  
+  //Keep backward compat with WTP < Kepler
+  private static final IProjectFacetVersion WEB_31 = WebFacetUtils.WEB_FACET.hasVersion(WEB_3_1_TEXT)?
+                                                              WebFacetUtils.WEB_FACET.getVersion(WEB_3_1_TEXT)
+                                                             :WebFacetUtils.WEB_30;
+  
+  private IProject project;
+  
+  private MavenProject mavenProject;
+
+  public WarPluginConfiguration(MavenProject mavenProject, IProject project) {
+    this.project = project;
+    this.mavenProject = mavenProject;
+    Plugin plugin = getPlugin();
+    if (plugin != null) {
+    	setConfiguration((Xpp3Dom)plugin.getConfiguration());
+    }
+  }
+
+  public Plugin getPlugin() {
+    return mavenProject.getPlugin("org.apache.maven.plugins:maven-war-plugin"); //$NON-NLS-1$
+  }
+
+  static boolean isWarProject(MavenProject mavenProject) {
+    return WAR_PACKAGING.equals(mavenProject.getPackaging());
+  }
+
+  public Xpp3Dom[] getWebResources() {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom webResources = config.getChild("webResources"); //$NON-NLS-1$
+      if (webResources != null && webResources.getChildCount() > 0)
+      {
+        int count = webResources.getChildCount();  
+        Xpp3Dom[] resources = new Xpp3Dom[count];
+        for (int i= 0; i< count ; i++) {
+          //MECLIPSEWTP-97 support old maven-war-plugin configurations which used <webResource> 
+          // instead of <resource>
+          Xpp3Dom webResource = new Xpp3Dom(webResources.getChild(i),"resource");  //$NON-NLS-1$
+          
+          //MECLIPSEWTP-152 : Web resource processing fails when targetPath has a leading /
+          Xpp3Dom targetPath = webResource.getChild("targetPath"); //$NON-NLS-1$
+          if(targetPath != null && targetPath.getValue() != null && targetPath.getValue().startsWith("/")) { //$NON-NLS-1$
+            targetPath.setValue(targetPath.getValue().substring(1));
+          }
+
+          resources[i] = webResource;
+        }
+        return resources;
+      }
+    }
+    return new Xpp3Dom[0];
+  }
+
+  public String getWarSourceDirectory() {
+    Xpp3Dom dom = getConfiguration();
+    if(dom == null) {
+      return WAR_SOURCE_FOLDER;
+    }
+
+    Xpp3Dom[] warSourceDirectory = dom.getChildren("warSourceDirectory"); //$NON-NLS-1$
+    if(warSourceDirectory != null && warSourceDirectory.length > 0) {
+      // first one wins
+      String dir = warSourceDirectory[0].getValue();
+      //MNGECLIPSE-1600 fixed absolute warSourceDirectory thanks to Snjezana Peco's patch
+      if(project != null) {
+        return WTPProjectsUtil.tryProjectRelativePath(project, dir).toOSString();
+      }
+      return dir;
+    }
+
+    return WAR_SOURCE_FOLDER;
+  }
+
+  @Override
+public String[] getPackagingExcludes() {
+    return DomUtils.getPatternsAsArray(getConfiguration(),"packagingExcludes"); //$NON-NLS-1$
+  }
+
+  @Override
+public String[] getPackagingIncludes() {
+    return DomUtils.getPatternsAsArray(getConfiguration(),"packagingIncludes"); //$NON-NLS-1$
+  }
+
+  @Override
+public String[] getSourceExcludes() {
+    return DomUtils.getPatternsAsArray(getConfiguration(),"warSourceExcludes"); //$NON-NLS-1$
+  }
+
+  @Override
+public String[] getSourceIncludes() {
+    return DomUtils.getPatternsAsArray(getConfiguration(),"warSourceIncludes"); //$NON-NLS-1$
+  }
+
+  public boolean isAddManifestClasspath() {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom arch = config.getChild("archive"); //$NON-NLS-1$
+      if(arch != null) {
+        Xpp3Dom manifest = arch.getChild("manifest"); //$NON-NLS-1$
+        if(manifest != null) {
+          Xpp3Dom addToClp = manifest.getChild("addClasspath"); //$NON-NLS-1$
+          if(addToClp != null) {
+            return Boolean.valueOf(addToClp.getValue());
+          }
+        }
+      }
+  }
+    return false;
+  }
+
+  public String getManifestClasspathPrefix() {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom arch = config.getChild("archive"); //$NON-NLS-1$
+      if(arch != null) {
+        Xpp3Dom manifest = arch.getChild("manifest"); //$NON-NLS-1$
+        if(manifest != null) {
+          Xpp3Dom prefix = manifest.getChild("classpathPrefix"); //$NON-NLS-1$
+          if(prefix != null && !StringUtils.nullOrEmpty(prefix.getValue())) {
+            String rawPrefix = prefix.getValue().trim();
+            if (!rawPrefix.endsWith("/")){ //$NON-NLS-1$
+              rawPrefix += "/"; //$NON-NLS-1$
+            }
+            return rawPrefix;
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  public IProjectFacetVersion getWebFacetVersion(IProject project) {
+    IFile webXml;
+    String customWebXml = getCustomWebXml(project);
+    if (customWebXml == null) {
+      webXml = project.getFolder(getWarSourceDirectory()).getFile(WEB_XML);
+    } else {
+      webXml = project.getFile(customWebXml);
+    }
+
+    if(webXml.isAccessible()) {
+      try {
+        InputStream is = webXml.getContents();
+        try {
+          JavaEEQuickPeek jqp = new JavaEEQuickPeek(is);
+          switch(jqp.getVersion()) {
+            case J2EEVersionConstants.WEB_2_2_ID:
+              return WebFacetUtils.WEB_22;
+            case J2EEVersionConstants.WEB_2_3_ID:
+              return WebFacetUtils.WEB_23;
+            case J2EEVersionConstants.WEB_2_4_ID:
+              return WebFacetUtils.WEB_24;
+            case J2EEVersionConstants.WEB_2_5_ID:
+              return WebFacetUtils.WEB_25;
+            case J2EEVersionConstants.WEB_3_0_ID:
+              return WebFacetUtils.WEB_30;
+            case WEB_3_1_ID:
+              return WEB_31;
+          }
+        } finally {
+          is.close();
+        }
+      } catch(IOException ex) {
+        // expected
+      } catch(CoreException ex) {
+        // expected
+      }
+    }
+   
+    //If no web.xml found and the project depends on some java EE 7 jar, then set web facet to 3.1
+    if (WTPProjectsUtil.hasInClassPath(project, "javax.servlet.http.WebConnection")) { //$NON-NLS-1$
+      return WEB_31;
+    }
+    //MNGECLIPSE-1978 If no web.xml found and the project depends on some java EE 6 jar, then set web facet to 3.0
+    if (WTPProjectsUtil.hasInClassPath(project, "javax.servlet.annotation.WebServlet")) { //$NON-NLS-1$
+      return WebFacetUtils.WEB_30;
+    }
+    
+    //If no web.xml found, don't change existing facet version
+    try {
+      IFacetedProject fProject = ProjectFacetsManager.create(project);
+      if (fProject != null && fProject.hasProjectFacet(WebFacetUtils.WEB_FACET)) {
+        return fProject.getProjectFacetVersion(WebFacetUtils.WEB_FACET);
+      }
+    } catch (Exception e) {
+      LOG.warn(NLS.bind(Messages.Error_Reading_Project_Facet, project.getName()), e); 
+    }
+    
+    //MNGECLIPSE-984 web.xml is optional for 2.5 Web Projects
+    return WTPProjectsUtil.DEFAULT_WEB_FACET;
+    //We don't want to prevent the project creation when the java compiler level is < 5, we coud try that instead :
+    //IProjectFacetVersion javaFv = JavaFacetUtils.compilerLevelToFacet(JavaFacetUtils.getCompilerLevel(project));
+    //return (JavaFacetUtils.JAVA_50.compareTo(javaFv) > 0)?WebFacetUtils.WEB_24:WebFacetUtils.WEB_25; 
+  }
+  /**
+   * Get the custom location of web.xml, as set in &lt;webXml&gt;.
+   * @return the custom location of web.xml or null if &lt;webXml&gt; is not set
+   */
+  public String getCustomWebXml(IProject project) {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom webXmlDom = config.getChild("webXml"); //$NON-NLS-1$
+      if(webXmlDom != null && webXmlDom.getValue() != null) {
+        String webXmlFile = webXmlDom.getValue().trim();
+        webXmlFile = ProjectUtils.getRelativePath(project, webXmlFile);
+        return webXmlFile;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * @return
+   * @throws CoreException 
+   */
+  public List<Overlay> getOverlays() throws CoreException {
+    Overlay currentProjectOverlay = Overlay.createInstance();
+    currentProjectOverlay.setArtifact(mavenProject.getArtifact());
+    OverlayManager overlayManager = null;
+    List<Overlay> overlays = null;
+    try {
+      overlayManager = new OverlayManager(getConfiguredOverlays(), 
+                                                         mavenProject, 
+                                                         getDependentWarIncludes(),
+                                                         getDependentWarExcludes(), 
+                                                         currentProjectOverlay);
+      overlays = overlayManager.getOverlays();
+    } catch(InvalidOverlayConfigurationException ex) {
+      throw new CoreException(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, ex.getMessage(),ex));
+    }
+    
+    return overlays;
+  }
+  
+  public String getDependentWarIncludes() {
+    return DomUtils.getChildValue(getConfiguration(), "dependentWarIncludes", "**/**"); //$NON-NLS-1$ //$NON-NLS-2$
+  }
+
+  public String getDependentWarExcludes() {
+    return DomUtils.getChildValue(getConfiguration(), "dependentWarExcludes", "META-INF/MANIFEST.MF"); //$NON-NLS-1$ //$NON-NLS-2$
+  }
+
+  public List<Overlay> getConfiguredOverlays() {
+    Xpp3Dom config = getConfiguration();
+    if(config != null) {
+      Xpp3Dom overlaysNode = config.getChild("overlays"); //$NON-NLS-1$
+      if (overlaysNode != null && overlaysNode.getChildCount() > 0) {
+        List<Overlay> overlays = new ArrayList<>(overlaysNode.getChildCount());
+        for (Xpp3Dom overlayNode : overlaysNode.getChildren("overlay")) { //$NON-NLS-1$
+          overlays.add(parseOverlay(overlayNode));
+        }
+        return overlays;
+      }
+    }
+    return Collections.emptyList();
+  }
+  
+  /**
+   * @param overlayNode
+   * @return
+   */
+  private Overlay parseOverlay(Xpp3Dom overlayNode) {
+    String artifactId = DomUtils.getChildValue(overlayNode, "artifactId"); //$NON-NLS-1$
+    String groupId = DomUtils.getChildValue(overlayNode, "groupId"); //$NON-NLS-1$
+    String[] exclusions = DomUtils.getChildrenAsStringArray(overlayNode.getChild("excludes"), "exclude"); //$NON-NLS-1$ //$NON-NLS-2$
+    String[] inclusions = DomUtils.getChildrenAsStringArray(overlayNode.getChild("includes"), "include"); //$NON-NLS-1$ //$NON-NLS-2$
+    String classifier = DomUtils.getChildValue(overlayNode, "classifier"); //$NON-NLS-1$
+    boolean filtered = DomUtils.getBooleanChildValue(overlayNode, "filtered"); //$NON-NLS-1$
+    boolean skip = DomUtils.getBooleanChildValue(overlayNode, "skip"); //$NON-NLS-1$
+    String type = DomUtils.getChildValue(overlayNode, "type", "war"); //$NON-NLS-1$ //$NON-NLS-2$
+    String targetPath = DomUtils.getChildValue(overlayNode, "targetPath", "/"); //$NON-NLS-1$ //$NON-NLS-2$
+
+    Overlay overlay = new Overlay();
+    overlay.setArtifactId(artifactId);
+    overlay.setGroupId(groupId);
+    overlay.setClassifier(classifier);
+    if (exclusions== null || exclusions.length ==0) {
+      overlay.setExcludes(getDependentWarExcludes());
+    } else {
+      overlay.setExcludes(exclusions);
+    }
+    if (inclusions== null || inclusions.length ==0) {
+      overlay.setIncludes(getDependentWarIncludes());
+    } else {
+      overlay.setIncludes(inclusions);
+    }
+    overlay.setFiltered(filtered);
+    overlay.setSkip(skip);
+    overlay.setTargetPath(targetPath);
+    overlay.setType(type);
+    
+    return overlay;
+  }
+
+  public FileNameMapping getFileNameMapping() {
+    Xpp3Dom config = getConfiguration();
+    String expression = null;
+    if(config != null) {
+      expression = DomUtils.getChildValue(config, "outputFileNameMapping"); //$NON-NLS-1$
+    }
+    return new PatternBasedFileNameMapping(expression);
+  }
+  
+  @Override
+protected String getFilteringAttribute() {
+    return "filteringDeploymentDescriptors"; //$NON-NLS-1$
+  }
+  
+  public String getWarName() {
+    Xpp3Dom config = getConfiguration();
+    String warName = null;
+    if (config != null) {
+      warName = DomUtils.getChildValue(config, "warName"); //$NON-NLS-1$
+    }
+    if (StringUtils.nullOrEmpty(warName)) {
+      warName = mavenProject.getBuild().getFinalName();
+    }
+    return warName;
+  }
+
+  @Override
+  public SourceLocation getSourceLocation() {
+    Plugin plugin = getPlugin();
+    if (plugin == null) {
+      return null;
+    }
+    return SourceLocationHelper.findLocation(plugin, "configuration"); //$NON-NLS-1$
+  }
+
+  @Override
+  public String getSourceIncludeParameterName() {
+    return "warSourceIncludes"; //$NON-NLS-1$
+  }
+
+  
+  public boolean isFailOnMissingWebXml() {
+    Xpp3Dom config = getConfiguration();
+    boolean failOnMissingWebXml = true;
+    String fail = null;
+    if (config != null) {
+      fail = DomUtils.getChildValue(config, FAIL_ON_MISSING_WEB_XML); //$NON-NLS-1$
+    }
+    if (fail == null) {
+      fail = mavenProject.getProperties().getProperty(FAIL_ON_MISSING_WEB_XML); //$NON-NLS-1$
+    }
+    if (fail != null) {
+      failOnMissingWebXml = Boolean.parseBoolean(fail);
+    }
+    return failOnMissingWebXml;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WebFragmentProjectConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WebFragmentProjectConfigurator.java
new file mode 100644
index 0000000..3b6e77d
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WebFragmentProjectConfigurator.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.installJavaFacet;
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeConflictingFacets;
+import static org.eclipse.m2e.wtp.internal.webfragment.WebFragmentUtil.getWebFragment;
+import static org.eclipse.m2e.wtp.internal.webfragment.WebFragmentUtil.isQualifiedAsWebFragment;
+
+import java.io.InputStream;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.codehaus.plexus.util.IOUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jst.j2ee.web.project.facet.IWebFragmentFacetInstallDataModelProperties;
+import org.eclipse.jst.j2ee.web.project.facet.WebFragmentFacetInstallDataModelProvider;
+import org.eclipse.m2e.core.internal.MavenPluginActivator;
+import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.internal.webfragment.WebFragmentQuickPeek;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action.Type;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Project configurator for web-fragment projects. A web-fragment project is a java project having a
+ * META-INF/web-fragment.xml file
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ */
+public class WebFragmentProjectConfigurator extends AbstractProjectConfigurator {
+
+  private static final Logger LOG = LoggerFactory.getLogger(WebFragmentProjectConfigurator.class); 
+
+  /**
+   * Adds the Java and Web fragment facets to jar projects qualified as web-fragments, i.e, 
+   * having a MET-INF/web-fragment.xml file in their output build directory (or any of their resource folders)
+   * If a previous utility facet was installed, it's removed before setting the Web Fragment facet.
+   */
+  @Override
+  public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
+    IMavenProjectFacade facade = request.getMavenProjectFacade();
+    IProject project = facade.getProject();
+
+    if(WTPProjectsUtil.isM2eWtpDisabled(facade, monitor) || !project.isAccessible() || 
+    		project.getResourceAttributes().isReadOnly() || !isQualifiedAsWebFragment(facade)){
+      return;
+    }
+    
+    IMavenMarkerManager mavenMarkerManager = MavenPluginActivator.getDefault().getMavenMarkerManager();
+    try {
+      mavenMarkerManager.deleteMarkers(project,MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID);
+      configureWebfragment(facade, monitor);
+    } catch (CoreException cex) {
+      mavenMarkerManager.addErrorMarkers(project, MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID, cex);
+    }
+  }
+
+  private void configureWebfragment(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
+	  
+	IFile webFragment = getWebFragment(facade);
+	if (webFragment == null) {
+		return;
+	}
+	
+	IProjectFacetVersion facetVersion = getVersion(webFragment);
+	if (facetVersion == null) {
+		return;
+	}
+	
+    IProject project = facade.getProject();
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
+    
+    Set<Action> actions = new LinkedHashSet<>();
+    
+    ResourceCleaner fileCleaner = new ResourceCleaner(project);
+    addFoldersToClean(fileCleaner, facade);
+     
+    try {
+      IProjectFacetVersion currentFacetVersion = facetedProject.getProjectFacetVersion(WTPProjectsUtil.WEB_FRAGMENT_FACET);
+      Type actionType = null;
+      if(currentFacetVersion == null) {
+    	  removeConflictingFacets(facetedProject, facetVersion, actions);
+          installJavaFacet(actions, project, facetedProject);
+
+    	  //Only install the web facet fragment if necessary
+    	  actionType = IFacetedProject.Action.Type.INSTALL;
+      } else if (facetVersion.compareTo(currentFacetVersion) > 0) {
+    	  actionType = IFacetedProject.Action.Type.VERSION_CHANGE;  
+      }
+
+ 	  if (actionType != null) {
+          IDataModel cfg = DataModelFactory.createDataModel(new WebFragmentFacetInstallDataModelProvider());
+          //Don't create an associated war project
+          cfg.setProperty(IWebFragmentFacetInstallDataModelProperties.ADD_TO_WAR, false);
+    	  actions.add(new IFacetedProject.Action(actionType,facetVersion, cfg)); 
+      }
+      
+      if (!actions.isEmpty()) {
+    	  facetedProject.modify(actions, monitor);
+      }
+      
+    } finally {
+      try {
+        //Remove any WTP created files (extras fragment descriptor and manifest) 
+        fileCleaner.cleanUp();
+      } catch (CoreException cex) {
+        LOG.error(Messages.Error_Cleaning_WTP_Files, cex);
+      }
+    }
+    //remove test folder links
+    WTPProjectsUtil.removeTestFolderLinks(project, facade.getMavenProject(), monitor, "/"); //$NON-NLS-1$
+    
+    WTPProjectsUtil.setNonDependencyAttributeToContainer(project, monitor);
+  }
+
+  private IProjectFacetVersion getVersion(IFile webFragment) {
+	InputStream in = null;
+	try {
+		webFragment.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
+		in = webFragment.getContents();
+		WebFragmentQuickPeek peek = new WebFragmentQuickPeek(in);
+		String version = peek.getVersion();
+		if (version != null) {
+			return WTPProjectsUtil.WEB_FRAGMENT_FACET.getVersion(version);
+		}
+	} catch (Exception e) {
+		// ignore
+		LOG.error("Error_Reading_WebFragment", e); //$NON-NLS-1$
+		return WTPProjectsUtil.WEB_FRAGMENT_FACET.getDefaultVersion();
+	} finally {
+		IOUtil.close(in);
+	}
+	return null;
+  }
+
+  protected void addFoldersToClean(ResourceCleaner fileCleaner, IMavenProjectFacade facade) {
+    for (IPath p : facade.getCompileSourceLocations()) {
+      if (p != null) {
+        fileCleaner.addFiles(p.append("META-INF/MANIFEST.MF")); //$NON-NLS-1$
+        fileCleaner.addFiles(p.append("META-INF/web-fragment.xml")); //$NON-NLS-1$
+        fileCleaner.addFolder(p);
+      }
+    }
+    for (IPath p : facade.getResourceLocations()) {
+      if (p != null) {
+        fileCleaner.addFiles(p.append("META-INF/MANIFEST.MF")); //$NON-NLS-1$
+        fileCleaner.addFiles(p.append("META-INF/web-fragment.xml")); //$NON-NLS-1$
+        fileCleaner.addFolder(p);
+      }
+    }
+    for (IPath p : facade.getTestCompileSourceLocations()) {
+      if (p != null) fileCleaner.addFolder(p);
+    }
+    for (IPath p : facade.getTestResourceLocations()) {
+      if (p != null) fileCleaner.addFolder(p);
+    }
+  }
+  
+  @Override
+  public boolean hasConfigurationChanged(IMavenProjectFacade newFacade,
+			ILifecycleMappingConfiguration oldProjectConfiguration,
+			MojoExecutionKey key, IProgressMonitor monitor) {
+    return false;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WebProjectConfiguratorDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WebProjectConfiguratorDelegate.java
new file mode 100644
index 0000000..89beed6
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/WebProjectConfiguratorDelegate.java
@@ -0,0 +1,406 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp;
+
+import static org.eclipse.m2e.wtp.WTPProjectsUtil.removeConflictingFacets;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
+import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
+import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEModuleFacetInstallDataModelProperties;
+import org.eclipse.jst.j2ee.web.project.facet.IWebFacetInstallDataModelProperties;
+import org.eclipse.jst.j2ee.web.project.facet.WebFacetInstallDataModelProvider;
+import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.embedder.ArtifactKey;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.jdt.IClasspathDescriptor;
+import org.eclipse.m2e.jdt.IClasspathEntryDescriptor;
+import org.eclipse.m2e.wtp.internal.ExtensionReader;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.internal.filtering.WebResourceFilteringConfiguration;
+import org.eclipse.m2e.wtp.internal.utilities.ComponentModuleUtil;
+import org.eclipse.m2e.wtp.namemapping.FileNameMapping;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * Configures web projects based on their maven-war-plugin configuration.
+ *
+ * @author Igor Fedorenko
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+class WebProjectConfiguratorDelegate extends AbstractProjectConfiguratorDelegate {
+
+  private static final Logger LOG = LoggerFactory.getLogger(WebProjectConfiguratorDelegate.class);
+  /**
+   * See http://wiki.eclipse.org/ClasspathEntriesPublishExportSupport
+   */
+  static final IClasspathAttribute DEPENDENCY_ATTRIBUTE = JavaCore.newClasspathAttribute(
+      IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY, "/WEB-INF/lib"); //$NON-NLS-1$
+
+  /**
+  * Name of maven property that overrides WTP context root.
+  */
+  private static final String M2ECLIPSE_WTP_CONTEXT_ROOT = "m2eclipse.wtp.contextRoot"; //$NON-NLS-1$
+
+  @Override
+protected void configure(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+    IFacetedProject facetedProject = ProjectFacetsManager.create(project, true, monitor);
+    IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().create(project.getFile(IMavenConstants.POM_FILE_NAME), true, monitor);
+
+    // make sure to update the main deployment folder
+    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
+    String warSourceDirectory = config.getWarSourceDirectory();
+
+    IFolder contentFolder = project.getFolder(warSourceDirectory);
+
+    Set<Action> actions = new LinkedHashSet<>();
+
+    installJavaFacet(actions, project, facetedProject);
+
+    IVirtualComponent component = ComponentCore.createComponent(project, true);
+
+    //MNGECLIPSE-2279 get the context root from the final name of the project, or artifactId by default.
+    String contextRoot = getContextRoot(mavenProject, config.getWarName());
+
+    IProjectFacetVersion webFv = config.getWebFacetVersion(project);
+    IDataModel webModelCfg = getWebModelConfig(warSourceDirectory, contextRoot);
+    if(!facetedProject.hasProjectFacet(WebFacetUtils.WEB_FACET)) {
+      removeConflictingFacets(facetedProject, webFv, actions);
+      actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.INSTALL, webFv, webModelCfg));
+    } else {
+      IProjectFacetVersion projectFacetVersion = facetedProject.getProjectFacetVersion(WebFacetUtils.WEB_FACET);
+      if(webFv.getVersionString() != null && !webFv.getVersionString().equals(projectFacetVersion.getVersionString())){
+          actions.add(new IFacetedProject.Action(IFacetedProject.Action.Type.VERSION_CHANGE, webFv, webModelCfg));
+      }
+    }
+
+    String customWebXml = config.getCustomWebXml(project);
+
+    if(!actions.isEmpty()) {
+      ResourceCleaner fileCleaner = new ResourceCleaner(project, contentFolder);
+      try {
+        addFoldersToClean(fileCleaner, facade);
+        fileCleaner.addFiles(contentFolder.getFile("META-INF/MANIFEST.MF").getProjectRelativePath()); //$NON-NLS-1$
+        fileCleaner.addFolder(contentFolder.getFolder("WEB-INF/lib")); //$NON-NLS-1$
+        if (customWebXml != null) {
+          fileCleaner.addFiles(contentFolder.getFile("WEB-INF/web.xml").getProjectRelativePath()); //$NON-NLS-1$
+        }
+
+        facetedProject.modify(actions, monitor);
+      } finally {
+        //Remove any unwanted MANIFEST.MF the Facet installation has created
+        fileCleaner.cleanUp();
+      }
+    }
+
+    //MECLIPSEWTP-41 Fix the missing moduleCoreNature
+    fixMissingModuleCoreNature(project, monitor);
+
+    configureDeployedName(project, config.getWarName());
+
+    // MNGECLIPSE-632 remove test sources/resources from WEB-INF/classes
+    removeTestFolderLinks(project, mavenProject, monitor, "/WEB-INF/classes"); //$NON-NLS-1$
+
+    addContainerAttribute(project, DEPENDENCY_ATTRIBUTE, monitor);
+
+    //MNGECLIPSE-2279 change the context root if needed
+    if (!contextRoot.equals(J2EEProjectUtilities.getServerContextRoot(project))) {
+      J2EEProjectUtilities.setServerContextRoot(project, contextRoot);
+    }
+
+    if (customWebXml != null) {
+      linkFileFirst(project, customWebXml, "/WEB-INF/web.xml", monitor); //$NON-NLS-1$
+    }
+
+
+    component = ComponentCore.createComponent(project, true);
+    if(component != null) {
+      IVirtualFolder rootFolder = component.getRootFolder();
+      IPath warPath = new Path("/").append(contentFolder.getProjectRelativePath()); //$NON-NLS-1$
+      boolean warPathExists = WTPProjectsUtil.hasLink(project, ROOT_PATH, warPath, monitor);
+      if (!warPathExists) {
+        component.getRootFolder().createLink(warPath, IVirtualResource.NONE, monitor);
+      }
+      IPath currentDefaultLocation = J2EEModuleVirtualComponent.getDefaultDeploymentDescriptorFolder(rootFolder);
+      if (currentDefaultLocation == null) {
+    	  WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(rootFolder , warPath, monitor);
+      }
+      //MECLIPSEWTP-22 support web filtered resources. Filtered resources directory must be declared BEFORE
+      //the regular web source directory. First resources discovered take precedence on deployment
+      IPath filteredFolder = new Path("/").append(WebResourceFilteringConfiguration.getTargetFolder(mavenProject, project)); //$NON-NLS-1$
+
+      boolean useBuildDir = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().getPreferences(project).isWebMavenArchiverUsesBuildDirectory();
+      boolean useWebresourcefiltering = config.getWebResources() != null
+                                        && config.getWebResources().length > 0
+                                        || config.isFilteringDeploymentDescriptorsEnabled();
+
+      if (useBuildDir || useWebresourcefiltering) {
+
+        if (!useBuildDir && useWebresourcefiltering) {
+          mavenMarkerManager.addMarker(project, MavenWtpConstants.WTP_MARKER_CONFIGURATION_ERROR_ID,
+                                      Messages.markers_mavenarchiver_output_settings_ignored_warning, -1, IMarker.SEVERITY_WARNING);
+        }
+        if (!WTPProjectsUtil.hasLink(project, ROOT_PATH, filteredFolder, monitor)) {
+        	WTPProjectsUtil.insertLinkBefore(project, filteredFolder, warPath, ROOT_PATH, monitor);
+        }
+      } else {
+        component.getRootFolder().removeLink(filteredFolder,IVirtualResource.NONE, monitor);
+      }
+
+      addComponentExclusionPatterns(component, config);
+    }
+    WTPProjectsUtil.removeWTPClasspathContainer(project);
+
+    setModuleDependencies(project, mavenProject, monitor);
+  }
+
+  private IDataModel getWebModelConfig(String warSourceDirectory, String contextRoot) {
+    IDataModel webModelCfg = DataModelFactory.createDataModel(new WebFacetInstallDataModelProvider());
+    webModelCfg.setProperty(IJ2EEModuleFacetInstallDataModelProperties.CONFIG_FOLDER, warSourceDirectory);
+    webModelCfg.setProperty(IWebFacetInstallDataModelProperties.CONTEXT_ROOT, contextRoot);
+    webModelCfg.setProperty(IJ2EEModuleFacetInstallDataModelProperties.GENERATE_DD, false);
+    webModelCfg.setBooleanProperty(IWebFacetInstallDataModelProperties.ADD_TO_EAR, false);
+    return webModelCfg;
+  }
+
+  @Override
+  public void setModuleDependencies(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+      throws CoreException {
+    if (!ModuleCoreNature.isFlexibleProject(project)) {
+      return;
+    }
+    //MECLIPSEWTP-41 Fix the missing moduleCoreNature
+    fixMissingModuleCoreNature(project, monitor);
+
+    IVirtualComponent component = ComponentModuleUtil.getOrCreateComponent(project, monitor);
+    //if the attempt to create dependencies happens before the project is actually created, abort.
+    //this will be created again when the project exists.
+    if(component == null){
+      LOG.error(project.getName() + "/.settings/org.eclipse.wst.common.component is missing or invalid. "
+      		+ "Skipping module dependency configuration. Deployment issues may arise.");
+      return;
+    }
+
+    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
+    Map<Artifact, String> deployedArtifacts = getDeployedArtifacts(mavenProject.getArtifacts(), config);
+
+    List<AbstractDependencyConfigurator> depConfigurators = ExtensionReader.readDependencyConfiguratorExtensions(projectManager,
+        MavenPlugin.getMavenRuntimeManager(), mavenMarkerManager);
+
+    Set<IVirtualReference> references = new LinkedHashSet<>();
+
+    List<IMavenProjectFacade> exportedDependencies = getWorkspaceDependencies(project, mavenProject);
+
+    for(IMavenProjectFacade dependency : exportedDependencies) {
+      String depPackaging = dependency.getPackaging();
+      if ("pom".equals(depPackaging) //MNGECLIPSE-744 pom dependencies shouldn't be deployed //$NON-NLS-1$
+          || "war".equals(depPackaging) //Overlays are dealt with the overlay configurator //$NON-NLS-1$
+          || "zip".equals(depPackaging)) { //$NON-NLS-1$
+        continue;
+      }
+
+      preConfigureDependencyProject(dependency, monitor);
+
+      if (!ModuleCoreNature.isFlexibleProject(dependency.getProject())) {
+        //Projects unsupported by WTP (ex. adobe flex projects) should not be added as references
+        continue;
+      }
+      MavenProject depMavenProject =  dependency.getMavenProject(monitor);
+
+      IVirtualComponent depComponent = ComponentCore.createComponent(dependency.getProject());
+
+      ArtifactKey artifactKey = ArtifactHelper.toArtifactKey(depMavenProject.getArtifact());
+      //Get artifact using the proper classifier
+      Artifact artifact = ArtifactHelper.getArtifact(mavenProject.getArtifacts(), artifactKey);
+      if (artifact == null) {
+        //could not map key to artifact
+        artifact = depMavenProject.getArtifact();
+      }
+      String deployedName = deployedArtifacts.get(artifact);
+
+  		//an artifact in mavenProject.getArtifacts() doesn't have the "optional" value as depMavenProject.getArtifact();
+  		if (deployedName != null) {
+  		  IVirtualReference reference = ComponentCore.createReference(component, depComponent);
+  		  IPath path = new Path("/WEB-INF/lib"); //$NON-NLS-1$
+  		  reference.setArchiveName(deployedName);
+  		  reference.setRuntimePath(path);
+  		  references.add(reference);
+  		}
+    }
+
+    IVirtualReference[] oldRefs = WTPProjectsUtil.extractHardReferences(component, false);
+
+    IVirtualReference[] newRefs = references.toArray(new IVirtualReference[references.size()]);
+
+    if (WTPProjectsUtil.hasChanged(oldRefs, newRefs)){
+      //Only write in the .component file if necessary
+      IVirtualReference[] overlayRefs = WTPProjectsUtil.extractHardReferences(component, true);
+      IVirtualReference[] allRefs = new IVirtualReference[overlayRefs.length + newRefs.length];
+      System.arraycopy(newRefs, 0, allRefs, 0, newRefs.length);
+      System.arraycopy(overlayRefs, 0, allRefs, newRefs.length, overlayRefs.length);
+      component.setReferences(allRefs);
+    }
+
+    //TODO why a 2nd loop???
+    for(IMavenProjectFacade dependency : exportedDependencies) {
+      MavenProject depMavenProject =  dependency.getMavenProject(monitor);
+      Iterator<AbstractDependencyConfigurator> configurators = depConfigurators.iterator();
+      while (configurators.hasNext()) {
+        try {
+          configurators.next().configureDependency(mavenProject, project, depMavenProject, dependency.getProject(), monitor);
+        } catch(MarkedException ex) {
+          //XXX handle this
+        }
+      }
+    }
+  }
+
+  /**
+   * Get the context root from a maven web project
+   * @param mavenProject
+   * @param warName
+   * @return the final name of the project if it exists, or the project's artifactId.
+   */
+  protected String getContextRoot(MavenProject mavenProject, String warName) {
+    String contextRoot;
+	//MECLIPSEWTP-43 : Override with maven property
+   String property = mavenProject.getProperties().getProperty(M2ECLIPSE_WTP_CONTEXT_ROOT);
+   if (StringUtils.isBlank(property)) {
+  		String finalName = warName;
+  		if (StringUtils.isBlank(finalName)
+  		   || finalName.equals(mavenProject.getArtifactId() + "-" + mavenProject.getVersion())) { //$NON-NLS-1$
+  		  contextRoot = mavenProject.getArtifactId();
+  		}  else {
+  		  contextRoot = finalName;
+  		}
+  	} else {
+  		contextRoot = property;
+  	}
+
+    return contextRoot.trim().replace(" ", "_"); //$NON-NLS-1$ //$NON-NLS-2$
+  }
+
+  @Override
+  public void configureClasspath(IProject project, MavenProject mavenProject, IClasspathDescriptor classpath,
+      IProgressMonitor monitor) throws CoreException {
+
+    WarPluginConfiguration config = new WarPluginConfiguration(mavenProject, project);
+    Set<Artifact> artifacts = mavenProject.getArtifacts();
+    Map<Artifact, String> deployedArtifacts = getDeployedArtifacts(artifacts, config);
+
+    Iterator<IClasspathEntryDescriptor> iter = classpath.getEntryDescriptors().iterator();
+    while (iter.hasNext()) {
+      IClasspathEntryDescriptor descriptor = iter.next();
+      Artifact artifact = ArtifactHelper.getArtifact(artifacts, descriptor.getArtifactKey());
+      if (artifact == null) {
+        return;
+      }
+
+      String deployedName = deployedArtifacts.get(artifact);
+
+      if(deployedName == null || isWorkspaceProject(artifact)) {
+        descriptor.setClasspathAttribute(NONDEPENDENCY_ATTRIBUTE.getName(), NONDEPENDENCY_ATTRIBUTE.getValue());
+        continue;
+      }
+      descriptor.getClasspathAttributes().put(IClasspathDependencyConstants.CLASSPATH_ARCHIVENAME_ATTRIBUTE, deployedName);
+    }
+  }
+
+  private boolean isWorkspaceProject(Artifact artifact) {
+	  IMavenProjectFacade facade = projectManager.getMavenProject(artifact.getGroupId(),
+																	artifact.getArtifactId(),
+																	artifact.getVersion());
+
+	  return facade != null && facade.getFullPath(artifact.getFile()) != null;
+  }
+
+  private Map<Artifact, String> getDeployedArtifacts(Collection<Artifact> artifacts, WarPluginConfiguration config ) {
+    if (artifacts == null || artifacts.isEmpty()) {
+      return Collections.emptyMap();
+    }
+    int size = artifacts.size();
+    Map<Artifact, String> artifactsMap = new LinkedHashMap<>(size);
+
+    IPackagingConfiguration opts = new PackagingConfiguration(config.getPackagingIncludes(), config.getPackagingExcludes());
+    FileNameMapping fileNameMapping = config.getFileNameMapping();
+
+    Set<String> names = new HashSet<>(size);
+
+    Set<String> duplicates = new HashSet<>(size);
+
+    for (Artifact artifact : artifacts) {
+      ArtifactHelper.fixArtifactHandler(artifact.getArtifactHandler());
+      String deployedName = fileNameMapping.mapFileName(artifact);
+      String scope = artifact.getScope();
+    	boolean isDeployed =  (Artifact.SCOPE_COMPILE.equals(scope) || Artifact.SCOPE_RUNTIME.equals(scope))
+    	                      && !artifact.isOptional()
+    	                      && opts.isPackaged("WEB-INF/lib/"+deployedName); //$NON-NLS-1$
+    	if (isDeployed) {
+    	  if (!names.add(deployedName)) {
+    		  duplicates.add(deployedName);
+     	  }
+    	  artifactsMap.put(artifact, deployedName);
+    	}
+	  }
+
+    //disambiguate duplicates
+    for (String name : duplicates) {
+    	for (Map.Entry<Artifact, String> entry : artifactsMap.entrySet()) {
+    		if (name.equals(entry.getValue())) {
+    		    String newDeployedName = entry.getKey().getGroupId() + "-" + name; //$NON-NLS-1$
+    			entry.setValue(newDeployedName);
+    		}
+    	}
+    }
+
+    return artifactsMap;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/AbstractEarModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/AbstractEarModule.java
new file mode 100644
index 0000000..c257309
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/AbstractEarModule.java
@@ -0,0 +1,305 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+
+/** 
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.AbstractEarModule 
+ * 
+ * A base implementation of an {@link EarModule}.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public abstract class AbstractEarModule implements EarModule {
+
+  private String uri;
+
+  private Artifact artifact;
+
+  // Those are set by the configuration
+
+  private String groupId;
+
+  private String artifactId;
+
+  private String classifier;
+
+  protected String bundleDir;
+
+  protected String bundleFileName;
+
+  protected boolean excluded;
+
+  //Unusable by WTP so far
+  protected Boolean unpack = null;
+
+  //Unusable by WTP so far
+  protected String altDeploymentDescriptor;
+
+  /**
+   * 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) {
+    setArtifact(a);
+  }
+  
+  public Artifact getArtifact() {
+    return artifact;
+  }
+
+  void setArtifact(Artifact a) {
+    this.artifact = a;
+    this.groupId = a.getGroupId();
+    this.artifactId = a.getArtifactId();
+    this.classifier = a.getClassifier();
+  }
+
+  public String getUri() {
+    if(uri == null) {
+      String bd = getBundleDir();
+      if(StringUtils.isEmpty(bd) || "/".equals(bd)) { //$NON-NLS-1$
+        uri = getBundleFileName();
+      } else {
+        if(!bd.endsWith("/")) { //$NON-NLS-1$
+          bd = bd + "/"; //$NON-NLS-1$
+        } 
+        if (bd.startsWith("/")) { //$NON-NLS-1$
+          bd = bd.substring(1);
+        }
+        uri =  bd + getBundleFileName();
+      }
+    }
+    return uri;
+  }
+
+  /**
+   * Returns the artifact's groupId.
+   * 
+   * @return the group Id
+   */
+  public String getGroupId() {
+    return groupId;
+  }
+
+  /**
+   * Returns the artifact's Id.
+   * 
+   * @return the artifact Id
+   */
+  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() {
+    if(bundleDir != null) {
+      bundleDir = cleanBundleDir(bundleDir);
+    }
+    return bundleDir;
+  }
+
+  /**
+   * Returns the bundle file name. If null, the artifact's file name is returned.
+   * 
+   * @return the bundle file name
+   */
+  public String getBundleFileName() {
+    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
+   * @since JavaEE 5
+   */
+  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;
+  }
+
+  public Boolean shouldUnpack() {
+    //Unusable by WTP so far
+    return unpack;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append(getType()).append(":").append(groupId).append(":").append(artifactId); //$NON-NLS-1$ //$NON-NLS-2$
+    if(classifier != null) {
+      sb.append(":").append(classifier); //$NON-NLS-1$
+    }
+    if(artifact != null) {
+      sb.append(":").append(artifact.getVersion()); //$NON-NLS-1$
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Cleans the bundle directory so that it might be used properly.
+   * 
+   * @param bundleDir the bundle directory to clean
+   * @return the cleaned bundle directory
+   */
+  static String cleanBundleDir(String bundleDir) {
+    if(bundleDir == null) {
+      return bundleDir;
+    }
+
+    // Using slashes
+    bundleDir = bundleDir.replace('\\', '/');
+
+    //WTP needs the bundle dir to start with a '/'
+    if(!bundleDir.startsWith("/")) { //$NON-NLS-1$
+      bundleDir = "/" + bundleDir ; //$NON-NLS-1$
+    }
+
+    return bundleDir;
+  }
+
+  void setBundleDir(String bundleDir) {
+    //Ignore bundleDir if uri has already been set
+    if (StringUtils.isBlank(uri)){
+      this.bundleDir = bundleDir;
+    } 
+  }
+
+  void setBundleFileName(String fileName) {
+    //Ignore bundleFileName if uri has already been set
+    if (StringUtils.isBlank(uri)){
+      this.bundleFileName = fileName;
+    } 
+  }
+
+  /**
+   * Setting an URI overrides any bundleDir or bundleFileName set on a module.
+   * @param uri 
+   */
+  void setUri(String uri) {
+    this.uri = uri;
+    resolveDeploymentInfo();
+  }
+
+
+  /**
+   * Parses the module's uri to compute the bundleDir and bundleFileName.
+   */
+  private void resolveDeploymentInfo() {
+    if (StringUtils.isNotBlank(uri)) {
+      int lastSlash = uri.lastIndexOf('/');
+      if (lastSlash == uri.length()-1){
+        throw new IllegalArgumentException("module uri ("+uri+") : can not end with a / "); //$NON-NLS-1$ //$NON-NLS-2$
+      }
+      if (lastSlash>0) {
+        bundleDir = uri.substring(0,lastSlash);
+        bundleFileName = uri.substring(lastSlash+1);
+      } else {
+        bundleFileName = uri.replace("/",""); //$NON-NLS-1$ //$NON-NLS-2$
+      }
+      bundleDir = cleanBundleDir(bundleDir);
+
+      if (StringUtils.isBlank(bundleFileName)){
+        throw new IllegalArgumentException("module uri must contain a file name "); //$NON-NLS-1$
+      }
+    }
+  }
+
+  void setExcluded(boolean excluded) {
+    this.excluded = excluded;
+  }
+
+  void setAltDeploymentDescriptor(String altDeploymentDescriptor) {
+    //Unusable by WTP so far
+    this.altDeploymentDescriptor = altDeploymentDescriptor;
+  }
+  
+  void setShouldUnpack(Boolean unpack) {
+    this.unpack = unpack;
+  }
+  
+  public Xpp3Dom getAsDom() {
+    Xpp3Dom moduleDom = new Xpp3Dom(getModuleType());
+    Xpp3Dom groupIdDom = new Xpp3Dom("groupId"); //$NON-NLS-1$
+    groupIdDom.setValue(getGroupId());  
+    moduleDom.addChild(groupIdDom);
+    Xpp3Dom artifactIdDom = new Xpp3Dom("artifactId"); //$NON-NLS-1$
+    artifactIdDom.setValue(getArtifactId());  
+    moduleDom.addChild(artifactIdDom);
+    Xpp3Dom uriDom = new Xpp3Dom("uri"); //$NON-NLS-1$
+    uriDom.setValue(getUri());  
+    moduleDom.addChild(uriDom);
+    Xpp3Dom altDdDom = new Xpp3Dom("altDeploymentDescriptor"); //$NON-NLS-1$
+    altDdDom.setValue(getAltDeploymentDescriptor());  
+    moduleDom.addChild(altDdDom);
+    Xpp3Dom excludedDom = new Xpp3Dom("excluded"); //$NON-NLS-1$
+    excludedDom.setValue(Boolean.toString(isExcluded()));  
+    moduleDom.addChild(excludedDom);
+    setCustomValues(moduleDom);
+    return moduleDom;
+  }
+
+  /**
+   * @return
+   */
+  protected String getModuleType() {
+    return "jarModule"; //$NON-NLS-1$
+  }
+  
+  protected void setCustomValues(Xpp3Dom module) {
+  }
+  
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/AppClientModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/AppClientModule.java
new file mode 100644
index 0000000..41f35af
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/AppClientModule.java
@@ -0,0 +1,49 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.apache.maven.artifact.Artifact;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.AppClientModule 
+ * 
+ * The {@link EarModule} implementation for an Application Client module.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class AppClientModule extends AbstractEarModule {
+
+  public AppClientModule() {
+    super();
+  }
+
+  public AppClientModule(Artifact a) {
+    super(a);
+  }
+
+  public String getType() {
+    return "app-client"; //$NON-NLS-1$
+  }
+
+  protected String getModuleType() {
+    return "appClientModule"; //$NON-NLS-1$
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/ArtifactRepository.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/ArtifactRepository.java
new file mode 100644
index 0000000..71453da
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/ArtifactRepository.java
@@ -0,0 +1,144 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.Artifact;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.util.ArtifactRepository
+ * 
+ * An artifact repository used to resolve {@link org.eclipse.m2e.wtp.earmodules.EarModule}. This is a Java 5 port
+ * of org.apache.maven.plugin.ear.ArtifactRepository from maven-ear-plugin
+ * 
+ * @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 wih the specified artifacts.
+   * 
+   * @param artifacts the artifacts
+   * @param mainArtifactId the id to use for the main artifact (no classifier)
+   */
+  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/> 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.isEmpty()) {
+      return null;
+    } else if(candidates.size() == 1 && classifier == null) {
+      return candidates.iterator().next();
+    } else if(classifier != null) {
+      for(Artifact a : artifacts) {
+        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/> 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<Artifact>();
+    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;
+  }
+
+  public Artifact resolveArtifact(String groupId, String artifactId, String type, String classifier)
+      throws EarPluginException {
+    // If the artifact is already set no need to resolve it
+    // Make sure that at least the groupId and the artifactId are specified
+    if(groupId == null || artifactId == null) {
+      throw new IllegalArgumentException("Could not resolve artifact[" + type + ":" + groupId + ":" + artifactId +"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    }
+    Artifact artifact = getUniqueArtifact(groupId, artifactId, type, classifier);
+    // Artifact has not been found
+    if(artifact == null) {
+      Set<Artifact> candidates = getArtifacts(groupId, artifactId, type);
+      if(candidates.size() > 1) {
+        throw new EarPluginException("Artifact[" + type + ":" + groupId + ":" + artifactId +"] has " + candidates.size() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+            + " candidates, please provide a classifier."); //$NON-NLS-1$
+      } else {
+        throw new EarPluginException("Artifact[" + type + ":" + groupId + ":" + artifactId +"] is not a dependency of the project."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+      }
+    }
+    return artifact;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/ArtifactTypeMappingService.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/ArtifactTypeMappingService.java
new file mode 100644
index 0000000..e95745a
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/ArtifactTypeMappingService.java
@@ -0,0 +1,169 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.util.ArtifactTypeMappingService
+ * 
+ * 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"; //$NON-NLS-1$
+
+  static final String TYPE_ATTRIBUTE = "type"; //$NON-NLS-1$
+
+  static final String MAPPING_ATTRIBUTE = "mapping"; //$NON-NLS-1$
+
+  public final static List<String> standardArtifactTypes = new ArrayList<>(10);
+
+  static {
+    standardArtifactTypes.add("jar"); //$NON-NLS-1$
+    standardArtifactTypes.add("ejb"); //$NON-NLS-1$
+    standardArtifactTypes.add("ejb3"); //$NON-NLS-1$
+    standardArtifactTypes.add("par"); //$NON-NLS-1$
+    standardArtifactTypes.add("ejb-client"); //$NON-NLS-1$
+    standardArtifactTypes.add("rar"); //$NON-NLS-1$
+    standardArtifactTypes.add("war"); //$NON-NLS-1$
+    standardArtifactTypes.add("sar"); //$NON-NLS-1$
+    standardArtifactTypes.add("wsr"); //$NON-NLS-1$
+    standardArtifactTypes.add("har"); //$NON-NLS-1$
+    standardArtifactTypes.add("app-client");     //$NON-NLS-1$
+  }
+
+  // A standard type to a list of customType
+  private Map<String, List<String>> typeMappings;
+
+  // The user-defined mapping for direct access
+  private Map<String, String> customMappings;
+
+  public ArtifactTypeMappingService(Xpp3Dom plexusConfiguration) throws EarPluginException {
+    // Initializes the typeMappings with default values
+    init();
+
+    // No user defined configuration
+    if(plexusConfiguration == null) {
+      return;
+    }
+
+    // Inject users configuration
+    final Xpp3Dom[] artifactTypeMappings = plexusConfiguration.getChildren(ARTIFACT_TYPE_MAPPING_ELEMENT);
+
+    for(Xpp3Dom 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."); //$NON-NLS-1$
+      } else if(mapping == null) {
+        throw new EarPluginException("Invalid artifact type mapping, mapping attribute should be set."); //$NON-NLS-1$
+      } else if(!isStandardArtifactType(mapping)) {
+        throw new EarPluginException("Invalid artifact type mapping, mapping[" + mapping //$NON-NLS-1$
+            + "] must be a standard Ear artifact type[" + getStandardArtifactTypes() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+      } else if(customMappings.containsKey(customType)) {
+        throw new EarPluginException("Invalid artifact type mapping, type[" + customType + "] is already registered."); //$NON-NLS-1$ //$NON-NLS-2$
+      } 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 <tt>customType</tt> could be mapped to the <tt>standardType</tt>.
+   * 
+   * @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(!isStandardArtifactType(standardType)) {
+      throw new IllegalStateException("Artifact type[" + standardType + "] is not a standard Ear artifact type[" //$NON-NLS-1$ //$NON-NLS-2$
+          + getStandardArtifactTypes() + "]"); //$NON-NLS-1$
+    }
+    final List<String> typeMappings = this.typeMappings.get(standardType);
+    return typeMappings.contains(customType);
+
+  }
+
+  /**
+   * Returns the standard type for the specified <tt>type</tt>. 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
+   */
+  public String getStandardType(final String type) throws UnknownArtifactTypeException {
+    if(type == null) {
+      throw new IllegalStateException("custom type could not be null."); //$NON-NLS-1$
+    } else if(getStandardArtifactTypes().contains(type)) {
+      return type;
+    } else if(!customMappings.containsKey(type)) {
+      throw new UnknownArtifactTypeException("Unknown artifact type[" + type + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+    } else {
+      return customMappings.get(type);
+    }
+  }
+
+  private void init() {
+    this.typeMappings = new HashMap<String, List<String>>();
+    this.customMappings = new HashMap<String, String>();
+
+    // Initialize the mapping with the standard artifact types
+    for(String type : getStandardArtifactTypes()) {
+      List<String> typeMapping = new ArrayList<>();
+      typeMapping.add(type);
+      this.typeMappings.put(type, typeMapping);
+    }
+  }
+
+  /**
+   * Returns a list of standard artifact types.
+   * 
+   * @return the standard artifact types
+   */
+  public static List<String> getStandardArtifactTypes() {
+    return standardArtifactTypes;
+  }
+
+  /**
+   * 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 standardArtifactTypes.contains(type);
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EarModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EarModule.java
new file mode 100644
index 0000000..c4c4ed1
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EarModule.java
@@ -0,0 +1,94 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.EarModule
+ *  
+ * The ear module interface.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public interface EarModule {
+
+  /**
+   * Returns the {@link Artifact} representing this module. <p/> Note that this might return <tt>null</tt> till the
+   * module has been resolved.
+   * 
+   * @return the artifact
+   * @see #resolveArtifact(java.util.Set)
+   */
+  public Artifact getArtifact();
+
+  /**
+   * Returns the <tt>URI</tt> for this module.
+   * 
+   * @return the <tt>URI</tt>
+   */
+  public String getUri();
+
+  /**
+   * Returns the type associated to the module.
+   * 
+   * @return the artifact's type of the module
+   */
+  public String getType();
+
+  /**
+   * Specify whether this module should be excluded or not.
+   * 
+   * @return true if this module should be skipped, false otherwise
+   */
+  public boolean isExcluded();
+
+  /**
+   * Specify whether this module should be unpacked in the EAR archive or not. <p/> Returns null if no configuration was
+   * specified so that defaulting may apply.
+   * 
+   * @return true if this module should be bundled unpacked, false otherwise
+   */
+  public 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
+   */
+  public String getAltDeploymentDescriptor();
+
+  public String getBundleDir();
+
+  /**
+   * @return the module fileName in the bundle directory 
+   */
+  public String getBundleFileName();
+
+  /**
+   * @return
+   */
+  public Xpp3Dom getAsDom();
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EarModuleFactory.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EarModuleFactory.java
new file mode 100644
index 0000000..2e2714d
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EarModuleFactory.java
@@ -0,0 +1,206 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+
+import static org.eclipse.m2e.wtp.DomUtils.getBooleanChildValue;
+import static org.eclipse.m2e.wtp.DomUtils.getChildValue;
+
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.wtp.namemapping.FileNameMapping;
+import org.eclipse.m2e.wtp.namemapping.FileNameMappingFactory;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.EarModuleFactory
+ * 
+ * Builds an {@link EarModule} based on an <tt>Artifact</tt>.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public final class EarModuleFactory {
+  
+  private ArtifactTypeMappingService artifactTypeMappingService;
+
+  private FileNameMapping fileNameMapping;
+
+  private ArtifactRepository artifactRepository;
+
+  private EarModuleFactory(ArtifactTypeMappingService artifactTypeMappingService, FileNameMapping fileNameMapping,
+      ArtifactRepository artifactRepository) {
+    this.artifactTypeMappingService = artifactTypeMappingService;
+    this.artifactRepository = artifactRepository;
+    this.fileNameMapping = fileNameMapping;
+  }
+
+  public static EarModuleFactory createEarModuleFactory(ArtifactTypeMappingService artifactTypeMappingService,
+      FileNameMapping fileNameMapping, String mainArtifactId, Set<Artifact> artifacts) throws EarPluginException {
+    if(artifactTypeMappingService == null) {
+      artifactTypeMappingService = new ArtifactTypeMappingService(null);
+    }
+    if(fileNameMapping == null) {
+      fileNameMapping = FileNameMappingFactory.getDefaultFileNameMapping();
+    }
+    ArtifactRepository artifactRepository = new ArtifactRepository(artifacts, mainArtifactId,
+        artifactTypeMappingService);
+
+    return new EarModuleFactory(artifactTypeMappingService, fileNameMapping, artifactRepository);
+  }
+
+  /**
+   * Creates a new {@link EarModule} based on the specified {@link Artifact} and the specified execution configuration.
+   * 
+   * @param artifact the artifact
+   * @param defaultLibBundleDir the default bundle dir for {@link JarModule}
+   * @param javaEEVersion 
+   * @return an ear module for this artifact
+   */
+  public EarModule newEarModule(Artifact artifact, String defaultLibBundleDir, IProjectFacetVersion javaEEVersion, 
+      boolean defaultIncludeInApplicationXml) throws UnknownArtifactTypeException {
+    // Get the standard artifact type based on default config and user-defined mapping(s)
+    final String artifactType = artifactTypeMappingService.getStandardType(artifact.getType());
+    AbstractEarModule earModule = null;
+    if("jar".equals(artifactType)) { //$NON-NLS-1$
+      earModule = new JarModule(artifact);
+      ((JarModule)earModule).setIncludeInApplicationXml(defaultIncludeInApplicationXml);
+      ((JarModule)earModule).setLibBundleDir(defaultLibBundleDir);
+    } else if("ejb".equals(artifactType) || "ejb3".equals(artifactType)) { //$NON-NLS-1$ //$NON-NLS-2$
+      earModule  = new EjbModule(artifact);
+    } else if("par".equals(artifactType)) { //$NON-NLS-1$
+      earModule  = new ParModule(artifact);
+    } else if("ejb-client".equals(artifactType)) { //$NON-NLS-1$
+      earModule  = new EjbClientModule(artifact);
+      if (javaEEVersion.compareTo(IJ2EEFacetConstants.ENTERPRISE_APPLICATION_14) >  0)
+      {
+        ((EjbClientModule)earModule).setLibBundleDir(defaultLibBundleDir);
+      }
+    } else if("rar".equals(artifactType)) { //$NON-NLS-1$
+      earModule  = new RarModule(artifact);
+    } else if("war".equals(artifactType)) { //$NON-NLS-1$
+      earModule  = new WebModule(artifact);
+    } else if("sar".equals(artifactType)) { //$NON-NLS-1$
+      earModule  = new SarModule(artifact);
+    } else if("wsr".equals(artifactType)) { //$NON-NLS-1$
+      earModule  = new WsrModule(artifact);
+    } else if("har".equals(artifactType)) { //$NON-NLS-1$
+      earModule  = new HarModule(artifact);
+    } else if("app-client".equals(artifactType)) { //$NON-NLS-1$
+        earModule  = new AppClientModule(artifact);
+    } else {
+      throw new IllegalStateException("Could not handle artifact type[" + artifactType + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    earModule.setBundleFileName(fileNameMapping.mapFileName(artifact));
+    
+    return earModule;
+
+  }
+
+  public EarModule newEarModule(Xpp3Dom domModule, String defaultLibBundleDir, IProjectFacetVersion javaEEVersion, boolean defaultIncludeInApplicationXml) throws EarPluginException {
+    String artifactType = domModule.getName();
+    String groupId      = getChildValue(domModule, "groupId"); //$NON-NLS-1$
+    String artifactId   = getChildValue(domModule, "artifactId"); //$NON-NLS-1$
+    String classifier   = getChildValue(domModule, "classifier"); //$NON-NLS-1$
+    
+    AbstractEarModule earModule = null;
+    // Get the standard artifact type based on default config and user-defined mapping(s)
+    if ( "jarModule".equals(artifactType) || "javaModule".equals(artifactType)) { //$NON-NLS-1$ //$NON-NLS-2$
+      JarModule jarModule = new JarModule();
+      jarModule.setBundleDir(defaultLibBundleDir);
+      
+      if (domModule.getChild("includeInApplicationXml") == null) { //$NON-NLS-1$
+        jarModule.setIncludeInApplicationXml(defaultIncludeInApplicationXml);
+      } else {
+        jarModule.setIncludeInApplicationXml(getBooleanChildValue(domModule, "includeInApplicationXml"));   //$NON-NLS-1$
+      }
+      earModule = jarModule;
+    } 
+    else if ( "ejbModule".equals(artifactType) || "ejb3Module".equals(artifactType)) { //$NON-NLS-1$ //$NON-NLS-2$
+      earModule  = new EjbModule();
+    } 
+    else if ( "webModule".equals(artifactType)){ //$NON-NLS-1$
+      WebModule webModule  = new WebModule();
+      webModule.setContextRoot(getChildValue(domModule, "contextRoot")); //$NON-NLS-1$
+      earModule = webModule;
+    }
+    else if ( "parModule".equals(artifactType)){ //$NON-NLS-1$
+      earModule = new ParModule();
+    }
+    else if ( "ejbClientModule".equals(artifactType)){ //$NON-NLS-1$
+      earModule = new EjbClientModule();
+      if (javaEEVersion.compareTo(IJ2EEFacetConstants.ENTERPRISE_APPLICATION_14) >  0)
+      {
+        ((EjbClientModule)earModule).setLibBundleDir(defaultLibBundleDir);
+      }
+    }
+    else if ( "rarModule".equals(artifactType)){ //$NON-NLS-1$
+      earModule = new RarModule();
+    }
+    else if ( "warModule".equals(artifactType)){ //$NON-NLS-1$
+      earModule = new WebModule();
+    }
+    else if ( "sarModule".equals(artifactType)){ //$NON-NLS-1$
+      earModule = new SarModule();
+    }
+    else if ( "wsrModule".equals(artifactType)){ //$NON-NLS-1$
+      earModule = new WsrModule();
+    }
+    else if ( "harModule".equals(artifactType)){ //$NON-NLS-1$
+      earModule = new HarModule();
+    }
+    else if ( "appClientModule".equals(artifactType)){ //$NON-NLS-1$
+        earModule = new AppClientModule();
+    }
+    else {
+        throw new IllegalStateException( "Could not handle artifact type[" + artifactType + "]" ); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    Artifact artifact   = artifactRepository.resolveArtifact(groupId, artifactId, earModule.getType(), classifier);
+    earModule.setArtifact(artifact);
+    
+    String bundleDir = getChildValue(domModule, "bundleDir"); //$NON-NLS-1$
+    if (StringUtils.isNotBlank(bundleDir)){
+      earModule.setBundleDir(bundleDir);      
+    }
+    //To this point, we're sure to have a valid earModule ...
+    String bundleFileName  = getChildValue(domModule, "bundleFileName"); //$NON-NLS-1$
+    if (null==bundleFileName){
+      bundleFileName = fileNameMapping.mapFileName(artifact);
+    }
+    earModule.setBundleFileName(bundleFileName);
+    earModule.setUri(getChildValue(domModule, "uri")); //$NON-NLS-1$
+    earModule.setExcluded(getBooleanChildValue(domModule, "excluded")); //$NON-NLS-1$
+
+    earModule.setAltDeploymentDescriptor(getChildValue(domModule, "altDeploymentDescriptor")); //$NON-NLS-1$
+    
+    //The following will be ignored by WTP - so far
+    String unpack = getChildValue(domModule, "unpack"); //$NON-NLS-1$
+    earModule.setShouldUnpack(unpack==null?null:Boolean.valueOf(unpack));
+    
+    return earModule;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EarPluginException.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EarPluginException.java
new file mode 100644
index 0000000..3a75e6e
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EarPluginException.java
@@ -0,0 +1,57 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.wtp.internal.Messages;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.EarPluginException
+ * 
+ * The base exception of the EAR plugin.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @author Fred Bricon
+ */
+public class EarPluginException extends CoreException {
+  private static final long serialVersionUID = -819727447130647982L;
+
+  private static final String DEFAULT_MESSAGE = Messages.EarPluginException_Default_Message;
+
+  public EarPluginException() {
+    super(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, DEFAULT_MESSAGE));
+  }
+
+  public EarPluginException(String message) {
+    super(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, message));
+  }
+
+  public EarPluginException(Throwable cause) {
+    super(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, DEFAULT_MESSAGE, cause));
+  }
+
+  public EarPluginException(String message, Throwable cause) {
+    super(new Status(IStatus.ERROR, IMavenConstants.PLUGIN_ID, message, cause));
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EjbClientModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EjbClientModule.java
new file mode 100644
index 0000000..065b3bd
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EjbClientModule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.apache.maven.artifact.Artifact;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.EjbClientModule
+ * 
+ * The {@link EarModule} implementation for an ejb client module.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EjbClientModule extends JarModule {
+
+  public EjbClientModule() {
+    super();
+  }
+
+  public EjbClientModule(Artifact artifact) {
+    super(artifact);
+  }
+
+  public String getType() {
+    return "ejb-client"; //$NON-NLS-1$
+  }
+  
+  protected String getModuleType() {
+    return "ejbClientModule"; //$NON-NLS-1$
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EjbModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EjbModule.java
new file mode 100644
index 0000000..a27b801
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/EjbModule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+
+import org.apache.maven.artifact.Artifact;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.EjbModule
+ * 
+ * The {@link EarModule} implementation for an EJB module.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class EjbModule extends AbstractEarModule {
+
+  public EjbModule() {
+    super();
+  }
+
+  public EjbModule(Artifact a) {
+    super(a);
+  }
+
+  public String getType() {
+    return "ejb"; //$NON-NLS-1$
+  }
+  
+  protected String getModuleType() {
+    return "ejbModule"; //$NON-NLS-1$
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/HarModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/HarModule.java
new file mode 100644
index 0000000..1bb1e96
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/HarModule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.apache.maven.artifact.Artifact;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.HarModule
+ * 
+ * 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 {
+
+  public HarModule() {
+    super();
+  }
+
+  public HarModule(Artifact a) {
+    super(a);
+  }
+
+  public String getType() {
+    return "har"; //$NON-NLS-1$
+  }
+
+  protected String getModuleType() {
+    return "harModule"; //$NON-NLS-1$
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/JarModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/JarModule.java
new file mode 100644
index 0000000..781f3e5
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/JarModule.java
@@ -0,0 +1,73 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.JarModule
+ * 
+ * The {@link EarModule} implementation for a non J2EE module such as third party libraries. <p/> Such module is not
+ * incorporated in the generated <tt>application.xml<tt>
+ * but some application servers support it. To include it in the generated
+ * deployment descriptor anyway, set the <tt>includeInApplicationXml</tt> boolean flag. <p/> This class deprecates
+ * {@link org.apache.maven.plugin.ear.JavaModule}.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class JarModule extends AbstractEarModule {
+  
+  private boolean includeInApplicationXml = false;
+
+
+  public JarModule(Artifact a) {
+    super(a);
+  }
+
+  public JarModule() {
+    super();
+  }
+
+  public String getType() {
+    return "jar"; //$NON-NLS-1$
+  }
+
+  void setLibBundleDir(String defaultLibBundleDir) {
+    if(defaultLibBundleDir != null && bundleDir == null) {
+      this.bundleDir = defaultLibBundleDir;
+    }
+  }
+
+  public boolean isIncludeInApplicationXml() {
+    return includeInApplicationXml;
+  }
+
+  public void setIncludeInApplicationXml(boolean includeInApplicationXml) {
+    this.includeInApplicationXml = includeInApplicationXml;
+  }
+
+  protected void setCustomValues(Xpp3Dom module) {
+    Xpp3Dom contextRootDom = new Xpp3Dom("includeInApplicationXml"); //$NON-NLS-1$
+    contextRootDom.setValue(Boolean.toString(includeInApplicationXml));
+    module.addChild(contextRootDom); 
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/JbossEarModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/JbossEarModule.java
new file mode 100644
index 0000000..5cb30b7
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/JbossEarModule.java
@@ -0,0 +1,31 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.JbossEarModule
+ * 
+ * Represents a JBoss specific ear module.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public interface JbossEarModule {
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/ParModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/ParModule.java
new file mode 100644
index 0000000..b91bff1
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/ParModule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.apache.maven.artifact.Artifact;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.ParModule
+ *  
+ * The {@link EarModule} implementation for a Par module.
+ * 
+ * @author Stephane Nicoll <snicoll@apache.org>
+ */
+public class ParModule extends EjbModule {
+
+  public ParModule() {
+    super();
+  }
+
+  public ParModule(Artifact a) {
+    super(a);
+  }
+
+  public String getType() {
+    return "par"; //$NON-NLS-1$
+  }
+  
+  protected String getModuleType() {
+    return "parModule"; //$NON-NLS-1$
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/RarModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/RarModule.java
new file mode 100644
index 0000000..505cb74
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/RarModule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.apache.maven.artifact.Artifact;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.RarModule
+ * 
+ * The {@link EarModule} implementation for an J2EE connector module.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class RarModule extends AbstractEarModule {
+
+  public RarModule() {
+    super();
+  }
+
+  public RarModule(Artifact a) {
+    super(a);
+  }
+
+  public String getType() {
+    return "rar"; //$NON-NLS-1$
+  }
+  
+  protected String getModuleType() {
+    return "rarModule"; //$NON-NLS-1$
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/SarModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/SarModule.java
new file mode 100644
index 0000000..d0c7cef
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/SarModule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+import org.apache.maven.artifact.Artifact;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.SarModule
+ * 
+ * The {@link EarModule} implementation for a JBoss sar module.
+ * 
+ * @author Stephane Nicoll <snicoll@apache.org>
+ */
+public class SarModule extends AbstractEarModule implements JbossEarModule {
+
+  public SarModule() {
+    super();
+  }
+
+  public SarModule(Artifact a) {
+    super(a);
+  }
+
+  public String getType() {
+    return "sar"; //$NON-NLS-1$
+  }
+
+  protected String getModuleType() {
+    return "sarModule"; //$NON-NLS-1$
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/SecurityRoleKey.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/SecurityRoleKey.java
new file mode 100644
index 0000000..016f5de
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/SecurityRoleKey.java
@@ -0,0 +1,79 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.SecurityRole
+ * 
+ * SecurityRoleKey
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @author Fred Bricon
+ */
+public class SecurityRoleKey {
+  private String id;
+  
+  private String roleName;
+  
+  private String description;
+  
+  /**
+   * @return Returns the id.
+   */
+  public String getId() {
+    return id;
+  }
+
+  /**
+   * @param id The id to set.
+   */
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  /**
+   * @return Returns the roleName.
+   */
+  public String getRoleName() {
+    return roleName;
+  }
+
+  /**
+   * @param roleName The roleName to set.
+   */
+  public void setRoleName(String roleName) {
+    this.roleName = roleName;
+  }
+
+  /**
+   * @return Returns the description.
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  /**
+   * @param description The description to set.
+   */
+  public void setDescription(String description) {
+    this.description = description;
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/UnknownArtifactTypeException.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/UnknownArtifactTypeException.java
new file mode 100644
index 0000000..158d2a0
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/UnknownArtifactTypeException.java
@@ -0,0 +1,40 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.UnknownArtifactTypeException
+ * 
+ * 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 = -5780701119026576364L;
+
+  public UnknownArtifactTypeException() {
+    super();
+  }
+
+  public UnknownArtifactTypeException(String message) {
+    super(message);
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/WebModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/WebModule.java
new file mode 100644
index 0000000..196ccf1
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/WebModule.java
@@ -0,0 +1,90 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.WebModule
+ * 
+ * The {@link EarModule} implementation for a Web application module.
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class WebModule extends AbstractEarModule {
+  
+  private String contextRoot;
+
+  public WebModule() {
+    super();
+  }
+
+  public WebModule(Artifact a) {
+    super(a);
+  }
+
+  /**
+   * Returns the context root to use for the web module. <p/> Note that this might return <tt>null</tt> till the
+   * artifact has been resolved.
+   * 
+   * @return the context root
+   */
+  public String getContextRoot() {
+    // Context root has not been customized - using default
+    if(contextRoot == null) {
+      contextRoot = getDefaultContextRoot(getArtifact());
+    }
+    return contextRoot;
+  }
+
+  public String getType() {
+    return "war"; //$NON-NLS-1$
+  }
+
+  /**
+   * Generates a default context root for the given artifact, based on the <tt>artifactId</tt>.
+   * 
+   * @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."); //$NON-NLS-1$
+    }
+    return "/" + a.getArtifactId(); //$NON-NLS-1$
+  }
+
+  public void setContextRoot(String contextRoot) {
+    this.contextRoot = contextRoot;
+  }
+  
+  protected void setCustomValues(Xpp3Dom module) {
+    Xpp3Dom contextRootDom = new Xpp3Dom("contextRoot"); //$NON-NLS-1$
+    contextRootDom.setValue(getContextRoot());
+    module.addChild(contextRootDom);
+  }
+
+  protected String getModuleType() {
+    return "webModule"; //$NON-NLS-1$
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/WsrModule.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/WsrModule.java
new file mode 100644
index 0000000..a2a849c
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/earmodules/WsrModule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.eclipse.m2e.wtp.earmodules;
+
+
+import org.apache.maven.artifact.Artifact;
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.WsrModule
+ * 
+ * The {@link EarModule} implementation for a JBoss wsr module.
+ * 
+ * @author Brad O'Hearne <brado@neurofire.com>
+ */
+public class WsrModule extends RarModule {
+
+  public WsrModule() {
+    super();
+  }
+
+  public WsrModule(Artifact a) {
+    super(a);
+  }
+
+  public String getType() {
+    return "wsr"; //$NON-NLS-1$
+  }
+
+  protected String getModuleType() {
+    return "wsrModule"; //$NON-NLS-1$
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/facets/AbstractFacetDetector.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/facets/AbstractFacetDetector.java
new file mode 100644
index 0000000..118797a
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/facets/AbstractFacetDetector.java
@@ -0,0 +1,119 @@
+/*************************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.facets;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExecutableExtension;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * Base class to determine the project Facet
+ *
+ * @author Fred Bricon
+ * @since 0.18.0
+ */
+public abstract class AbstractFacetDetector implements IExecutableExtension, Comparable<AbstractFacetDetector> {
+  
+  public static final String ATTR_ID = "id"; //$NON-NLS-1$
+  
+  public static final String ATTR_FACET_ID = "facetId"; //$NON-NLS-1$
+  
+  public static final String ATTR_PRIORITY = "priority"; //$NON-NLS-1$
+  
+  public static final String ATTR_CLASS = "class"; //$NON-NLS-1$
+  
+  private String id;
+  
+  private String facetId;
+  
+  private int priority;
+  
+  /**
+   * Returns the id of this detector
+   */
+  public String getId() {
+    if(id == null) {
+      id = getClass().getName();
+    }
+    return id;
+  }
+  
+  /**
+   * returns the Facet Id this detector applies to.
+   */
+  public String getFacetId() {
+    return facetId;
+  }
+  
+
+  /**
+   * Identify the project Facet version for the given maven project facade.
+   * 
+   * @param mavenProjectFacade
+   * @param context - an optional map containing context sensitive data
+   * @param monitor a progress monitor
+   * @return the {@link IProjectFacetVersion} of the corresponding facetId, or <code>null</code> if not facet could be identified  
+   * @throws CoreException
+   */
+  public abstract IProjectFacetVersion findFacetVersion(IMavenProjectFacade mavenProjectFacade, Map<?, ?> context, IProgressMonitor monitor) throws CoreException;
+
+  /**
+   * Returns the priority
+   */
+  public int getPriority() {
+    return priority;
+  }
+  
+  /**
+   * Compare detectors priority
+   * 
+   * @see java.lang.Comparable#compareTo(java.lang.Object)
+   */
+  @Override
+public int compareTo(AbstractFacetDetector other) {
+    if (other == null) {
+      return priority;
+    }
+    int result = other.priority - priority;
+    if (result == 0) {
+      return 0;
+    }
+    return (result > 0)? -1 : 1;
+  }
+
+  /**
+   * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement, java.lang.String, java.lang.Object)
+   */
+  @Override
+public void setInitializationData(IConfigurationElement config, String propertyName, Object data)
+      throws CoreException {
+      this.id = config.getAttribute(ATTR_ID);
+      this.facetId = config.getAttribute(ATTR_FACET_ID);
+      try {
+        priority = Integer.parseInt(config.getAttribute(ATTR_PRIORITY));
+      } catch(Exception e) {
+        priority = 100;
+      }
+  }
+  
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
+   */
+  @Override
+public String toString() {
+    return getId();
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/facets/FacetDetectorExtensionReader.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/facets/FacetDetectorExtensionReader.java
new file mode 100644
index 0000000..319ac07
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/facets/FacetDetectorExtensionReader.java
@@ -0,0 +1,79 @@
+/*************************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.facets;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Extension reader used to instanciate {@link AbstractFacetDetector}s from plugin.xml extensions
+ * 
+ * @author Fred Bricon
+ * @since 0.18.0
+ */
+/* package */ class FacetDetectorExtensionReader {
+
+  private static final Logger LOG = LoggerFactory.getLogger(FacetDetectorExtensionReader.class);
+
+  private static final String EXTENSION_FACET_DETECTORS = "org.eclipse.m2e.wtp.facetDetectors"; //$NON-NLS-1$
+
+  private static final Object ELEMENT_FACET_DETECTOR = "facetDetector"; //$NON-NLS-1$
+
+  public static synchronized Map<String, List<AbstractFacetDetector>> readFacetDetectorExtensions() {
+    
+    Map<String, List<AbstractFacetDetector>> map = new HashMap<String, List<AbstractFacetDetector>>();
+
+    IExtensionRegistry registry = Platform.getExtensionRegistry();
+    IExtensionPoint configuratorsExtensionPoint = registry.getExtensionPoint(EXTENSION_FACET_DETECTORS);
+    if(configuratorsExtensionPoint != null) {
+      IExtension[] configuratorExtensions = configuratorsExtensionPoint.getExtensions();
+      for(IExtension extension : configuratorExtensions) {
+        IConfigurationElement[] elements = extension.getConfigurationElements();
+        for(IConfigurationElement element : elements) {
+          if(element.getName().equals(ELEMENT_FACET_DETECTOR)) {
+            try {
+              String facetId = element.getAttribute(AbstractFacetDetector.ATTR_FACET_ID);
+              Object o = element.createExecutableExtension(AbstractFacetDetector.ATTR_CLASS);
+              AbstractFacetDetector facetDetector = (AbstractFacetDetector) o;
+              List<AbstractFacetDetector> detectors = map.get(facetId);
+              if (detectors == null){
+                detectors = new ArrayList<>();
+                map.put(facetId, detectors);
+              }
+              detectors.add(facetDetector);
+            } catch(CoreException ex) {
+              LOG.error(Messages.FacetDetectorExtensionReader_Error_Configuring_Facet_Detector, ex);
+            }
+          }
+        }
+      }
+    }
+    //Sort each detector list
+    for ( List<AbstractFacetDetector> detectors : map.values()) {
+      Collections.sort(detectors);
+    }
+    return map;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/facets/FacetDetectorManager.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/facets/FacetDetectorManager.java
new file mode 100644
index 0000000..68de613
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/facets/FacetDetectorManager.java
@@ -0,0 +1,112 @@
+/*************************************************************************************
+ * Copyright (c) 2011-2013 Red Hat, Inc. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ************************************************************************************/
+package org.eclipse.m2e.wtp.facets;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Central class used to identify project Facets based on contributed {@link AbstractFacetDetector}s
+ *
+ * @author Fred Bricon
+ * @since 0.18.0
+ */
+public class FacetDetectorManager {
+  
+  private static final Logger LOG = LoggerFactory.getLogger(FacetDetectorManager.class); 
+  
+  private static final FacetDetectorManager instance = new FacetDetectorManager(); 
+  
+  private Map<String, List<AbstractFacetDetector>> facetDetectors = null;
+  
+  private FacetDetectorManager() {
+  }
+  
+  /**
+   * @return a singleton instance of {@link FacetDetectorManager} 
+   */
+  public static FacetDetectorManager getInstance() {
+    return instance;
+  }
+  
+  /**
+   * Inspects the given project to determine the {@link IProjectFacetVersion} of the given facetId. 
+   * Facet detection is delegated to contributed {@link AbstractFacetDetector} strategies. 
+   * If a detector fails to detect the corresponding Facet version or throws an error, the next detector is invoked, 
+   * in order of its priority.
+   * 
+   * @param mavenProjectFacade an {@link IMavenProjectFacade} instance
+   * @param facetId the id of the {@link IProjectFacet} to look for.
+   * @param monitor a progress monitor, can be <code>null</code>;
+   * @return an {@link IProjectFacetVersion} corresponding the facetId
+   * @throws CoreException
+   */
+  public IProjectFacetVersion findFacetVersion(IMavenProjectFacade mavenProjectFacade, String facetId, IProgressMonitor monitor) throws CoreException {
+    return findFacetVersion(mavenProjectFacade, facetId, null, monitor);
+  }
+  
+  /**
+   * Inspects the given project to determine the {@link IProjectFacetVersion} of the given facetId. 
+   * Facet detection is delegated to contributed {@link AbstractFacetDetector} strategies. 
+   * If a detector fails to detect the corresponding Facet version or throws an error, the next detector is invoked, 
+   * in order of its priority. An optional context map can be used by the different detectors to determine the facet version.  
+   * 
+   * @param mavenProjectFacade an {@link IMavenProjectFacade} instance
+   * @param facetId the id of the {@link IProjectFacet} to look for.
+   * @param context an optional context map, can be <code>null</code> 
+   * @param monitor a progress monitor, can be <code>null</code>;
+   * @return an {@link IProjectFacetVersion} corresponding the facetId
+   * @throws CoreException
+   */
+  public IProjectFacetVersion findFacetVersion(IMavenProjectFacade mavenProjectFacade, String facetId, Map<?, ?> context, IProgressMonitor monitor) throws CoreException {
+    if (facetId == null) {
+      return null;
+    }
+    List<AbstractFacetDetector> detectors = getFacetDetectors().get(facetId);
+    if (detectors == null || detectors.isEmpty()) {
+      return null;
+    }
+    IProjectFacetVersion version = null;
+    for (AbstractFacetDetector detector : detectors) {
+      if (monitor != null && monitor.isCanceled()) {
+        break;
+      }
+      try {
+        version = detector.findFacetVersion(mavenProjectFacade, context, monitor);
+        if (version != null) {
+          if (!facetId.equals(version.getProjectFacet().getId())) {
+            //throws exception 
+          }
+          break;
+        }
+      } catch (CoreException ce) {
+        LOG.error(ce.getLocalizedMessage());
+      }
+    }
+    return version;
+  }
+
+  private Map<String, List<AbstractFacetDetector>> getFacetDetectors() {
+    if (facetDetectors == null) {
+      facetDetectors = FacetDetectorExtensionReader.readFacetDetectorExtensions();
+    }
+    return facetDetectors;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/AntPathMatcher.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/AntPathMatcher.java
new file mode 100644
index 0000000..6416ae7
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/AntPathMatcher.java
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * 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.
+ */
+
+package org.eclipse.m2e.wtp.internal;
+
+
+/**
+ * PathMatcher implementation for Ant-style path patterns.
+ * Examples are provided below.
+ *
+ * <p>Part of this mapping code has been kindly borrowed from
+ * <a href="http://ant.apache.org">Apache Ant</a>.
+ *
+ * <p>The mapping matches URLs using the following rules:<br>
+ * <ul>
+ * <li>? matches one character</li>
+ * <li>* matches zero or more characters</li>
+ * <li>** matches zero or more 'directories' in a path</li>
+ * </ul>
+ *
+ * <p>Some examples:<br>
+ * <ul>
+ * <li><code>com/t?st.jsp</code> - matches <code>com/test.jsp</code> but also
+ * <code>com/tast.jsp</code> or <code>com/txst.jsp</code></li>
+ * <li><code>com/*.jsp</code> - matches all <code>.jsp</code> files in the
+ * <code>com</code> directory</li>
+ * <li><code>com/&#42;&#42;/test.jsp</code> - matches all <code>test.jsp</code>
+ * files underneath the <code>com</code> path</li>
+ * <li><code>org/springframework/&#42;&#42;/*.jsp</code> - matches all <code>.jsp</code>
+ * files underneath the <code>org/springframework</code> path</li>
+ * <li><code>org/&#42;&#42;/servlet/bla.jsp</code> - matches
+ * <code>org/springframework/servlet/bla.jsp</code> but also
+ * <code>org/springframework/testing/servlet/bla.jsp</code> and
+ * <code>org/servlet/bla.jsp</code></li>
+ * </ul>
+ *
+ * @author Alef Arendsen
+ * @author Juergen Hoeller
+ * @author Rob Harrop
+ * @since 16.07.2003
+ */
+public class AntPathMatcher  {
+
+	/** Default path separator: "/" */
+	public static final String DEFAULT_PATH_SEPARATOR = "/"; //$NON-NLS-1$
+
+	private String pathSeparator = DEFAULT_PATH_SEPARATOR;
+
+
+	/**
+	 * Set the path separator to use for pattern parsing.
+	 * Default is "/", as in Ant.
+	 */
+	public void setPathSeparator(String pathSeparator) {
+		this.pathSeparator = (pathSeparator != null ? pathSeparator : DEFAULT_PATH_SEPARATOR);
+	}
+
+
+	public boolean isPattern(String path) {
+		return (path.indexOf('*') != -1 || path.indexOf('?') != -1);
+	}
+
+	public boolean match(String pattern, String path) {
+		return doMatch(pattern, path, true);
+	}
+
+	public boolean matchStart(String pattern, String path) {
+		return doMatch(pattern, path, false);
+	}
+
+
+	/**
+	 * Actually match the given <code>path</code> against the given <code>pattern</code>.
+	 * @param pattern the pattern to match against
+	 * @param path the path String to test
+	 * @param fullMatch whether a full pattern match is required
+	 * (else a pattern match as far as the given base path goes is sufficient)
+	 * @return <code>true</code> if the supplied <code>path</code> matched,
+	 * <code>false</code> if it didn't
+	 */
+	protected boolean doMatch(String pattern, String path, boolean fullMatch) {
+		if (path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) {
+			return false;
+		}
+
+		String[] pattDirs = StringUtils.tokenizeToStringArray(pattern, this.pathSeparator);
+		String[] pathDirs = StringUtils.tokenizeToStringArray(path, this.pathSeparator);
+
+		int pattIdxStart = 0;
+		int pattIdxEnd = pattDirs.length - 1;
+		int pathIdxStart = 0;
+		int pathIdxEnd = pathDirs.length - 1;
+
+		// Match all elements up to the first **
+		while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {
+			String patDir = pattDirs[pattIdxStart];
+			if ("**".equals(patDir)) { //$NON-NLS-1$
+				break;
+			}
+			if (!matchStrings(patDir, pathDirs[pathIdxStart])) {
+				return false;
+			}
+			pattIdxStart++;
+			pathIdxStart++;
+		}
+
+		if (pathIdxStart > pathIdxEnd) {
+			// Path is exhausted, only match if rest of pattern is * or **'s
+			if (pattIdxStart > pattIdxEnd) {
+				return (pattern.endsWith(this.pathSeparator) ?
+						path.endsWith(this.pathSeparator) : !path.endsWith(this.pathSeparator));
+			}
+			if (!fullMatch) {
+				return true;
+			}
+			if (pattIdxStart == pattIdxEnd && pattDirs[pattIdxStart].equals("*") && //$NON-NLS-1$
+					path.endsWith(this.pathSeparator)) {
+				return true;
+			}
+			for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
+				if (!pattDirs[i].equals("**")) { //$NON-NLS-1$
+					return false;
+				}
+			}
+			return true;
+		}
+		else if (pattIdxStart > pattIdxEnd) {
+			// String not exhausted, but pattern is. Failure.
+			return false;
+		}
+		else if (!fullMatch && "**".equals(pattDirs[pattIdxStart])) { //$NON-NLS-1$
+			// Path start definitely matches due to "**" part in pattern.
+			return true;
+		}
+
+		// up to last '**'
+		while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {
+			String patDir = pattDirs[pattIdxEnd];
+			if (patDir.equals("**")) { //$NON-NLS-1$
+				break;
+			}
+			if (!matchStrings(patDir, pathDirs[pathIdxEnd])) {
+				return false;
+			}
+			pattIdxEnd--;
+			pathIdxEnd--;
+		}
+		if (pathIdxStart > pathIdxEnd) {
+			// String is exhausted
+			for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
+				if (!pattDirs[i].equals("**")) { //$NON-NLS-1$
+					return false;
+				}
+			}
+			return true;
+		}
+
+		while (pattIdxStart != pattIdxEnd && pathIdxStart <= pathIdxEnd) {
+			int patIdxTmp = -1;
+			for (int i = pattIdxStart + 1; i <= pattIdxEnd; i++) {
+				if (pattDirs[i].equals("**")) { //$NON-NLS-1$
+					patIdxTmp = i;
+					break;
+				}
+			}
+			if (patIdxTmp == pattIdxStart + 1) {
+				// '**/**' situation, so skip one
+				pattIdxStart++;
+				continue;
+			}
+			// Find the pattern between padIdxStart & padIdxTmp in str between
+			// strIdxStart & strIdxEnd
+			int patLength = (patIdxTmp - pattIdxStart - 1);
+			int strLength = (pathIdxEnd - pathIdxStart + 1);
+			int foundIdx = -1;
+
+			strLoop:
+			    for (int i = 0; i <= strLength - patLength; i++) {
+				    for (int j = 0; j < patLength; j++) {
+					    String subPat = pattDirs[pattIdxStart + j + 1];
+					    String subStr = pathDirs[pathIdxStart + i + j];
+					    if (!matchStrings(subPat, subStr)) {
+						    continue strLoop;
+					    }
+				    }
+				    foundIdx = pathIdxStart + i;
+				    break;
+			    }
+
+			if (foundIdx == -1) {
+				return false;
+			}
+
+			pattIdxStart = patIdxTmp;
+			pathIdxStart = foundIdx + patLength;
+		}
+
+		for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
+			if (!pattDirs[i].equals("**")) { //$NON-NLS-1$
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Tests whether or not a string matches against a pattern.
+	 * The pattern may contain two special characters:<br>
+	 * '*' means zero or more characters<br>
+	 * '?' means one and only one character
+	 * @param pattern pattern to match against.
+	 * Must not be <code>null</code>.
+	 * @param str string which must be matched against the pattern.
+	 * Must not be <code>null</code>.
+	 * @return <code>true</code> if the string matches against the
+	 * pattern, or <code>false</code> otherwise.
+	 */
+	private boolean matchStrings(String pattern, String str) {
+		char[] patArr = pattern.toCharArray();
+		char[] strArr = str.toCharArray();
+		int patIdxStart = 0;
+		int patIdxEnd = patArr.length - 1;
+		int strIdxStart = 0;
+		int strIdxEnd = strArr.length - 1;
+		char ch;
+
+		boolean containsStar = false;
+		for (int i = 0; i < patArr.length; i++) {
+			if (patArr[i] == '*') {
+				containsStar = true;
+				break;
+			}
+		}
+
+		if (!containsStar) {
+			// No '*'s, so we make a shortcut
+			if (patIdxEnd != strIdxEnd) {
+				return false; // Pattern and string do not have the same size
+			}
+			for (int i = 0; i <= patIdxEnd; i++) {
+				ch = patArr[i];
+				if (ch != '?') {
+					if (ch != strArr[i]) {
+						return false;// Character mismatch
+					}
+				}
+			}
+			return true; // String matches against pattern
+		}
+
+
+		if (patIdxEnd == 0) {
+			return true; // Pattern contains only '*', which matches anything
+		}
+
+		// Process characters before first star
+		while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {
+			if (ch != '?') {
+				if (ch != strArr[strIdxStart]) {
+					return false;// Character mismatch
+				}
+			}
+			patIdxStart++;
+			strIdxStart++;
+		}
+		if (strIdxStart > strIdxEnd) {
+			// All characters in the string are used. Check if only '*'s are
+			// left in the pattern. If so, we succeeded. Otherwise failure.
+			for (int i = patIdxStart; i <= patIdxEnd; i++) {
+				if (patArr[i] != '*') {
+					return false;
+				}
+			}
+			return true;
+		}
+
+		// Process characters after last star
+		while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {
+			if (ch != '?') {
+				if (ch != strArr[strIdxEnd]) {
+					return false;// Character mismatch
+				}
+			}
+			patIdxEnd--;
+			strIdxEnd--;
+		}
+		if (strIdxStart > strIdxEnd) {
+			// All characters in the string are used. Check if only '*'s are
+			// left in the pattern. If so, we succeeded. Otherwise failure.
+			for (int i = patIdxStart; i <= patIdxEnd; i++) {
+				if (patArr[i] != '*') {
+					return false;
+				}
+			}
+			return true;
+		}
+
+		// process pattern between stars. padIdxStart and patIdxEnd point
+		// always to a '*'.
+		while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
+			int patIdxTmp = -1;
+			for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
+				if (patArr[i] == '*') {
+					patIdxTmp = i;
+					break;
+				}
+			}
+			if (patIdxTmp == patIdxStart + 1) {
+				// Two stars next to each other, skip the first one.
+				patIdxStart++;
+				continue;
+			}
+			// Find the pattern between padIdxStart & padIdxTmp in str between
+			// strIdxStart & strIdxEnd
+			int patLength = (patIdxTmp - patIdxStart - 1);
+			int strLength = (strIdxEnd - strIdxStart + 1);
+			int foundIdx = -1;
+			strLoop:
+			for (int i = 0; i <= strLength - patLength; i++) {
+				for (int j = 0; j < patLength; j++) {
+					ch = patArr[patIdxStart + j + 1];
+					if (ch != '?') {
+						if (ch != strArr[strIdxStart + i + j]) {
+							continue strLoop;
+						}
+					}
+				}
+
+				foundIdx = strIdxStart + i;
+				break;
+			}
+
+			if (foundIdx == -1) {
+				return false;
+			}
+
+			patIdxStart = patIdxTmp;
+			strIdxStart = foundIdx + patLength;
+		}
+
+		// All characters in the string are used. Check if only '*'s are left
+		// in the pattern. If so, we succeeded. Otherwise failure.
+		for (int i = patIdxStart; i <= patIdxEnd; i++) {
+			if (patArr[i] != '*') {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	/**
+	 * Given a pattern and a full path, determine the pattern-mapped part.
+	 * <p>For example:
+	 * <ul>
+	 * <li>'<code>/docs/cvs/commit.html</code>' and '<code>/docs/cvs/commit.html</code> -> ''</li>
+	 * <li>'<code>/docs/*</code>' and '<code>/docs/cvs/commit</code> -> '<code>cvs/commit</code>'</li>
+	 * <li>'<code>/docs/cvs/*.html</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>commit.html</code>'</li>
+	 * <li>'<code>/docs/**</code>' and '<code>/docs/cvs/commit</code> -> '<code>cvs/commit</code>'</li>
+	 * <li>'<code>/docs/**\/*.html</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>cvs/commit.html</code>'</li>
+	 * <li>'<code>/*.html</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>docs/cvs/commit.html</code>'</li>
+	 * <li>'<code>*.html</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>/docs/cvs/commit.html</code>'</li>
+	 * <li>'<code>*</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>/docs/cvs/commit.html</code>'</li>
+	 * </ul>
+	 * <p>Assumes that {@link #match} returns <code>true</code> for '<code>pattern</code>'
+	 * and '<code>path</code>', but does <strong>not</strong> enforce this.
+	 */
+	public String extractPathWithinPattern(String pattern, String path) {
+		String[] patternParts = StringUtils.tokenizeToStringArray(pattern, this.pathSeparator);
+		String[] pathParts = StringUtils.tokenizeToStringArray(path, this.pathSeparator);
+
+		StringBuilder buffer = new StringBuilder();
+
+		// Add any path parts that have a wildcarded pattern part.
+		int puts = 0;
+		for (int i = 0; i < patternParts.length; i++) {
+			String patternPart = patternParts[i];
+			if ((patternPart.indexOf('*') > -1 || patternPart.indexOf('?') > -1) && pathParts.length >= i + 1) {
+				if (puts > 0 || (i == 0 && !pattern.startsWith(this.pathSeparator))) {
+					buffer.append(this.pathSeparator);
+				}
+				buffer.append(pathParts[i]);
+				puts++;
+			}
+		}
+
+		// Append any trailing path parts.
+		for (int i = patternParts.length; i < pathParts.length; i++) {
+			if (puts > 0 || i > 0) {
+				buffer.append(this.pathSeparator);
+			}
+			buffer.append(pathParts[i]);
+		}
+
+		return buffer.toString();
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/ExtensionReader.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/ExtensionReader.java
new file mode 100644
index 0000000..4cd8d2d
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/ExtensionReader.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.m2e.core.embedder.MavenRuntimeManager;
+import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager;
+import org.eclipse.m2e.core.project.IMavenProjectRegistry;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.wtp.AbstractDependencyConfigurator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Extension reader
+ * 
+ * @author Eugene Kuleshov
+ */
+public class ExtensionReader {
+
+  public static final String EXTENSION_DEPENDENCY_CONFIGURATORS = "org.eclipse.m2e.wtp.dependencyConfigurators"; //$NON-NLS-1$
+  
+  private static final Logger LOG = LoggerFactory.getLogger(ExtensionReader.class);
+      
+  private static final String ELEMENT_CONFIGURATOR = "configurator"; //$NON-NLS-1$
+  
+  private static ArrayList<AbstractDependencyConfigurator> dependencyConfigurators;
+
+  public static List<AbstractDependencyConfigurator> readDependencyConfiguratorExtensions(IMavenProjectRegistry projectManager,
+      MavenRuntimeManager runtimeManager, IMavenMarkerManager markerManager) {
+    if (dependencyConfigurators == null) {
+      dependencyConfigurators = new ArrayList<>();
+      
+      IExtensionRegistry registry = Platform.getExtensionRegistry();
+      IExtensionPoint configuratorsExtensionPoint = registry.getExtensionPoint(EXTENSION_DEPENDENCY_CONFIGURATORS);
+      if(configuratorsExtensionPoint != null) {
+        IExtension[] configuratorExtensions = configuratorsExtensionPoint.getExtensions();
+        for(IExtension extension : configuratorExtensions) {
+          IConfigurationElement[] elements = extension.getConfigurationElements();
+          for(IConfigurationElement element : elements) {
+            if(element.getName().equals(ELEMENT_CONFIGURATOR)) {
+              try {
+                Object o = element.createExecutableExtension(AbstractProjectConfigurator.ATTR_CLASS);
+  
+                AbstractDependencyConfigurator projectConfigurator = (AbstractDependencyConfigurator) o;
+                projectConfigurator.setProjectManager(projectManager);
+                projectConfigurator.setRuntimeManager(runtimeManager);
+                projectConfigurator.setMarkerManager(markerManager);
+                
+                dependencyConfigurators.add(projectConfigurator);
+              } catch(CoreException ex) {
+                LOG.error("Error configuring dependency configurator", ex); //$NON-NLS-1$
+              }
+            }
+          }
+        }
+      }
+      
+      return dependencyConfigurators;
+    }
+    
+    return dependencyConfigurators;
+  }
+}
+
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/Messages.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/Messages.java
new file mode 100644
index 0000000..31eb34f
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/Messages.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages
+ *
+ * @author Fred Bricon
+ */
+public class Messages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.m2e.wtp.internal.messages"; //$NON-NLS-1$
+	public static String AbstractProjectFacetConversionEnabler_Error_Accessing_Project;
+	public static String AppClientVersionChangeListener_Error_Notifying_Application_Client_Version_Change;
+	public static String VersionChangeListener_Unreadeable_Project_Nature;
+	public static String EarProjectConverter_Error_EAR_Root_Content_Folder;
+	public static String EarVersionChangeListener_Error_Notifying_EAR_Version_Change;
+	public static String EjbClientClassifierClasspathProvider_EJB_Client_Classpath_Provider;
+	public static String ClassifierClasspathProvider_Error_Loading_Maven_Instance;
+	public static String MavenPluginUtils_ArtifactId_Cant_Be_Null;
+	public static String MavenPluginUtils_Error_Cant_Retrieve_Latest_Plugin_Version;
+	public static String MavenPluginUtils_GroupId_Cant_Be_Null;
+	public static String MavenWtpPreferencePage_Configure_Workspace_Settings;
+	public static String MavenWtpPreferencePage_EAR_Project_Preferences;
+	public static String MavenWtpPreferencePage_Enable_Project_Specific_Settings;
+	public static String MavenWtpPreferencePage_Generate_ApplicationXml_Under_Build_Dir;
+	public static String MavenWtpPreferencePage_Generate_MavenArchiver_Files_Under_Build_Dir;
+	public static String MavenWtpPreferencePage_JavaEE_Integration_Settings;
+	public static String MavenWtpPreferencePage_Maven_JavaEE_Integration_Settings;
+	public static String MavenWtpPreferencePage_Select_Active_JavaEE_Configurators;
+	public static String MavenWtpPreferencePage_Update_Projects_After_Preference_Changes;
+	public static String MavenWtpPreferencePage_Updating_Configuration_For_Project;
+	public static String MavenWtpPreferencePage_Updating_Maven_Projects_Job;
+	public static String MavenWtpPreferencePage_Updating_Maven_Projects_Monitor;
+	public static String MavenWtpPreferencePage_Using_Build_Directory;
+	public static String MavenWtpPreferencePage_Using_EAR_Build_Directory;
+	public static String MavenWtpPreferencePage_WAR_Project_Preferences;
+	public static String MavenWtpPreferencesManagerImpl_0;
+	public static String ResourceFilteringBuildParticipant_Changed_Resources_Require_Clean_Build;
+	public static String ResourceFilteringBuildParticipant_Cleaning_Filtered_Folder;
+	public static String ResourceFilteringBuildParticipant_Error_While_Filtering_Resources;
+	public static String ResourceFilteringBuildParticipant_Executing_Resource_Filtering;
+	public static String WarClassesClassifierClasspathProvider_WAR_Classes_Classifier_Classpath_Provider;
+	public static String WarProjectBuildParticipant_Error_FailOnMissingWebXml;
+	public static String WarVersionChangeListener_Error_Notifying_WebApp_Version_Change;
+	public static String WTPResourcesContentProvider_Error_Getting_Pipelined_Children;
+	public static String WTPResourcesImages_Error_Creating_ImageDescriptor;
+	public static String WTPResourcesNode_Cant_Retrieve_Project_Facet;
+	public static String WTPResourcesNode_Deployed_Resources_Label;
+	public static String WTPResourcesNode_Error_Getting_WTP_Resources;
+	public static String FacetDetectorExtensionReader_Error_Configuring_Facet_Detector;
+	public static String AbstractProjectConfiguratorDelegate_Error_Inconsistent_Java_Configuration;
+	public static String AbstractProjectConfiguratorDelegate_Unable_To_Configure_Project;
+	public static String AcrPluginConfiguration_Error_Project_Not_appclient;
+	public static String ArtifactHelper_Error_Artifact_Must_Not_Be_Null;
+	public static String EarPluginConfiguration_Error_Reading_EAR_Version;
+	public static String EarPluginConfiguration_Project_Must_Have_ear_Packaging;
+	public static String EarProjectConfiguratorDelegate_Configuring_EAR_Project;
+	public static String EjbPluginConfiguration_Project_Must_Have_ejb_Packaging;
+	public static String Error_Cleaning_WTP_Files;
+	public static String Error_Maven_Project_Cant_Be_Null;
+	public static String Error_Reading_Project_Facet;
+    public static String markers_inclusion_patterns_problem;
+	public static String markers_unsupported_dependencies_warning;
+	public static String markers_mavenarchiver_output_settings_ignored_warning;
+	public static String MavenDeploymentDescriptorManagement_Error_Deleting_Temp_Folder;
+	public static String MavenSessionHelper_Error_Component_Lookup;
+	public static String RarPluginConfiguration_Project_Must_Have_rar_Packaging;
+    public static String WebProjectConfiguratorDelegate_File_Copy_Failed;
+	public static String WebProjectConfiguratorDelegate_Renamed_Dependencies_Will_Be_Copied;
+	public static String WTPProjectsUtil_Actions_Cant_Be_Null;
+	public static String WTPProjectsUtil_Facet_Version_Cant_Be_Null;
+	public static String WTPProjectsUtil_Project_Cant_Be_Null;
+	public static String WTPProjectsUtil_Unable_To_Add_ModuleCoreNature;
+	public static String EarPluginException_Default_Message;
+	static {
+		// initialize resource bundle
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	private Messages() {
+	}
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/StringUtils.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/StringUtils.java
new file mode 100644
index 0000000..4290b3d
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/StringUtils.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * StringUtils
+ *
+ * @author dyocum
+ */
+public class StringUtils {
+  public static boolean nullOrEmpty(String s){
+    return s == null || s.length() == 0;
+  }
+  
+  
+  /**
+   * Tokenize the given String into a String array via a StringTokenizer.
+   * Trims tokens and omits empty tokens.
+   * <p>The given delimiters string is supposed to consist of any number of
+   * delimiter characters. Each of those characters can be used to separate
+   * tokens. A delimiter is always a single character; for multi-character
+   * delimiters, consider using <code>delimitedListToStringArray</code>
+   * @param str the String to tokenize
+   * @param delimiters the delimiter characters, assembled as String
+   * (each of those characters is individually considered as delimiter).
+   * @return an array of the tokens
+   * @see java.util.StringTokenizer
+   * @see java.lang.String#trim()
+   * @see #delimitedListToStringArray
+   */
+  public static String[] tokenizeToStringArray(String str, String delimiters) {
+    return tokenizeToStringArray(str, delimiters, true, true);
+  }
+
+  /**
+   * Tokenize the given String into a String array via a StringTokenizer.
+   * <p>The given delimiters string is supposed to consist of any number of
+   * delimiter characters. Each of those characters can be used to separate
+   * tokens. A delimiter is always a single character; for multi-character
+   * delimiters, consider using <code>delimitedListToStringArray</code>
+   * @param str the String to tokenize
+   * @param delimiters the delimiter characters, assembled as String
+   * (each of those characters is individually considered as delimiter)
+   * @param trimTokens trim the tokens via String's <code>trim</code>
+   * @param ignoreEmptyTokens omit empty tokens from the result array
+   * (only applies to tokens that are empty after trimming; StringTokenizer
+   * will not consider subsequent delimiters as token in the first place).
+   * @return an array of the tokens (<code>null</code> if the input String
+   * was <code>null</code>)
+   * @see java.util.StringTokenizer
+   * @see java.lang.String#trim()
+   * @see #delimitedListToStringArray
+   */
+  public static String[] tokenizeToStringArray(
+      String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {
+
+    if (str == null) {
+      return null;
+    }
+    StringTokenizer st = new StringTokenizer(str, delimiters);
+    List<String> tokens = new ArrayList<>();
+    while (st.hasMoreTokens()) {
+      String token = st.nextToken();
+      if (trimTokens) {
+        token = token.trim();
+      }
+      if (!ignoreEmptyTokens || token.length() > 0) {
+        tokens.add(token);
+      }
+    }
+    return tokens.toArray(new String[tokens.size()]);
+  }
+  
+  /**
+   * Joins a String[] to a single String using a comma delimiter
+   * @param someArrays
+   * @return a non-null String
+   */
+  public static String joinAsString(String[] ... someArrays) {
+    Set<String> stringSet = new LinkedHashSet<>();
+    if (someArrays != null) {
+      for (String[] strings : someArrays)
+        if (strings != null) {
+          stringSet.addAll(Arrays.asList(strings));
+        }
+    }
+    return org.codehaus.plexus.util.StringUtils.join(stringSet.iterator(), ","); //$NON-NLS-1$
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesContentProvider.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesContentProvider.java
new file mode 100644
index 0000000..c79de12
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesContentProvider.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.model.BaseWorkbenchContentProvider;
+import org.eclipse.ui.navigator.ICommonContentExtensionSite;
+import org.eclipse.ui.navigator.IPipelinedTreeContentProvider;
+import org.eclipse.ui.navigator.PipelinedShapeModification;
+import org.eclipse.ui.navigator.PipelinedViewerUpdate;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * WTP resources content provider
+ *
+ * @author Eugene Kuleshov
+ */
+public class WTPResourcesContentProvider extends BaseWorkbenchContentProvider implements IPipelinedTreeContentProvider {
+
+  private static final Logger LOG = LoggerFactory.getLogger(WTPResourcesContentProvider.class); 
+  
+  @Override
+  public void init(ICommonContentExtensionSite config) {
+  }
+
+  @Override
+  public void restoreState(IMemento memento) {
+  }
+
+  @Override
+  public void saveState(IMemento memento) {
+  }
+
+  @Override
+  public Object[] getChildren(Object element) {
+    if(element instanceof WTPResourcesNode) {
+      return ((WTPResourcesNode) element).getResources();
+    }
+    return super.getChildren(element);
+  }
+
+  // IPipelinedTreeContentProvider
+
+  @Override
+  @SuppressWarnings("rawtypes")
+  public void getPipelinedElements(Object element, Set currentElements) {
+  }
+  
+  @Override
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  public void getPipelinedChildren(Object parent, Set currentChildren) {
+    if (parent instanceof IProject) {
+      IProject project = (IProject) parent;
+      if(project.isAccessible()) {
+        try {
+          if (!project.hasNature(IMavenConstants.NATURE_ID)) {
+        	  return;
+          }
+          IFacetedProject facetedProject = ProjectFacetsManager.create(project);//MNGECLIPSE-1992 there's no reason to actually create a ProjectFacet at this point
+          if(facetedProject != null && 
+              (facetedProject.hasProjectFacet(WTPProjectsUtil.DYNAMIC_WEB_FACET) || 
+               facetedProject.hasProjectFacet(WTPProjectsUtil.EAR_FACET))) {
+            List newChildren = new ArrayList<>(currentChildren.size()+1);
+            newChildren.add(new WTPResourcesNode(project));
+            newChildren.addAll(currentChildren);
+            currentChildren.clear();
+            currentChildren.addAll(newChildren);
+          }
+        } catch(CoreException ex) {
+          LOG.error(Messages.WTPResourcesContentProvider_Error_Getting_Pipelined_Children, ex);
+        }
+      }
+    }
+  }
+
+  @Override
+  public Object getPipelinedParent(Object element, Object suggestedParent) {
+    return suggestedParent;
+  }
+
+  @Override
+  public boolean interceptRefresh(PipelinedViewerUpdate refreshSynchronization) {
+    return false;
+  }
+  
+  @Override
+  public boolean interceptUpdate(PipelinedViewerUpdate updateSynchronization) {
+    return false;
+  }
+  
+  @Override
+  public PipelinedShapeModification interceptAdd(PipelinedShapeModification addModification) {
+    return addModification;
+  }
+
+  @Override
+  public PipelinedShapeModification interceptRemove(PipelinedShapeModification removeModification) {
+    return removeModification;
+  }
+  
+}
+
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesImages.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesImages.java
new file mode 100644
index 0000000..631e6ec
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesImages.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+/**
+ * @author Eugene Kuleshov
+ */
+public class WTPResourcesImages {
+
+  private static final Logger LOG = LoggerFactory.getLogger(WTPResourcesImages.class);
+
+  // descriptors
+  public static final ImageDescriptor WEB_RESOURCES = create("web-resources.gif"); //$NON-NLS-1$
+  
+  public static final ImageDescriptor APP_RESOURCES = create("ear-resources.gif"); //$NON-NLS-1$
+
+  private static ImageDescriptor create(String key) {
+    try {
+      ImageRegistry imageRegistry = getImageRegistry();
+      if(imageRegistry != null) {
+        ImageDescriptor imageDescriptor = imageRegistry.getDescriptor(key);
+        if(imageDescriptor==null) {
+          imageDescriptor = createDescriptor(key);
+          imageRegistry.put(key, imageDescriptor);
+        }
+        return imageDescriptor;
+      }
+    } catch(Exception ex) {
+      LOG.error(NLS.bind(Messages.WTPResourcesImages_Error_Creating_ImageDescriptor,key), ex);
+    }
+    return null;
+  }
+
+  private static ImageRegistry getImageRegistry() {
+    MavenWtpPlugin plugin = MavenWtpPlugin.getDefault();
+    return plugin == null ? null : plugin.getImageRegistry();
+  }
+
+  private static ImageDescriptor createDescriptor(String image) {
+    return AbstractUIPlugin.imageDescriptorFromPlugin(MavenWtpPlugin.ID, "icons/" + image); //$NON-NLS-1$
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesLabelProvider.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesLabelProvider.java
new file mode 100644
index 0000000..41d7ef2
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesLabelProvider.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal;
+
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.ui.navigator.ICommonContentExtensionSite;
+import org.eclipse.ui.navigator.ICommonLabelProvider;
+
+/**
+ * WTPResourcesLabelProvider
+ *
+ * @author Eugene Kuleshov
+ */
+public class WTPResourcesLabelProvider extends WorkbenchLabelProvider implements ICommonLabelProvider {
+
+  @Override
+public void init(ICommonContentExtensionSite config) {
+  }
+
+  @Override
+public void restoreState(IMemento memento) {
+  }
+
+  @Override
+public void saveState(IMemento memento) {
+  }
+
+  @Override
+public String getDescription(Object element) {
+    if(element instanceof WTPResourcesNode) {
+      return ((WTPResourcesNode)element).getLabel();
+    }
+    return null;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesNode.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesNode.java
new file mode 100644
index 0000000..1251207
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesNode.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * WTP Resources node
+ * 
+ * @author Eugene Kuleshov
+ */
+public class WTPResourcesNode implements IWorkbenchAdapter {
+
+  private static final int HASHCODE_ADDITION = 0x504;
+  private static final Logger LOG = LoggerFactory.getLogger(WTPResourcesNode.class);
+
+  private final IProject project;
+
+  public WTPResourcesNode(IProject project) {
+    this.project = project;
+  }
+
+  public Object[] getResources() {
+    IContainer[] folders = getRootFolders();
+    if(folders != null && folders.length == 1) {
+      try {
+        return folders[0].members();
+      } catch(CoreException ex) {
+        LOG.error(Messages.WTPResourcesNode_Error_Getting_WTP_Resources,ex);
+      }
+    }
+
+    return folders;
+  }
+
+  // IWorkbenchAdapter
+  
+  @Override
+  public String getLabel(Object o) {
+//    IContainer[] folders = getRootFolders();
+//    StringBuilder label = new StringBuilder(getLabel());
+//    if(folders.length == 1) {
+//      IContainer c = folders[0];
+//      label.append(" : ").append(c.getFullPath().removeFirstSegments(1));
+//    }
+//    return label.toString();
+    return getLabel();
+  }
+
+  @Override
+  public ImageDescriptor getImageDescriptor(Object object) {
+    try {
+      IFacetedProject facetedProject = ProjectFacetsManager.create(project);
+      if (facetedProject != null && facetedProject.hasProjectFacet(IJ2EEFacetConstants.ENTERPRISE_APPLICATION_FACET)) {
+        return WTPResourcesImages.APP_RESOURCES;
+      }
+    } catch(CoreException ex) {
+      LOG.error(Messages.WTPResourcesNode_Cant_Retrieve_Project_Facet,ex);
+    }    
+    return WTPResourcesImages.WEB_RESOURCES;
+  }
+
+  @Override
+  public Object getParent(Object o) {
+    return project;
+  }
+
+  @Override
+  public Object[] getChildren(Object o) {
+    return getResources();
+  }
+
+  // helper methods
+  
+  private IContainer[] getRootFolders() {
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    IContainer[] folders = null;
+    if (component != null) {
+      IVirtualFolder rootFolder = component.getRootFolder();
+      folders = rootFolder.getUnderlyingFolders();
+    } else {
+      folders = new IContainer[0];
+    }
+    return folders;
+  }
+  
+  public String getLabel() {  
+    return Messages.WTPResourcesNode_Deployed_Resources_Label;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if( !(o instanceof WTPResourcesNode))
+      return false;
+    IProject p = ((WTPResourcesNode)o).project;
+    return this.project == null ? p == null : this.project.equals(p);
+  }
+  @Override
+  public int hashCode() {
+    return HASHCODE_ADDITION + (project == null ? 0 : project.hashCode());
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesSorter.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesSorter.java
new file mode 100644
index 0000000..16ed1b8
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/WTPResourcesSorter.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal;
+
+import java.text.Collator;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+
+/**
+ * WTPResourcesSorter
+ *
+ * @author Eugene Kuleshov
+ */
+public class WTPResourcesSorter extends ViewerSorter {
+
+  public WTPResourcesSorter() {
+  }
+
+  public WTPResourcesSorter(Collator collator) {
+    super(collator);
+  }
+
+  @Override
+  public int category(Object element) {
+    if(element instanceof WTPResourcesNode) {
+      return 0;
+    }
+    return 1;
+  }
+  
+  @Override
+  public int compare(Viewer viewer, Object e1, Object e2) {
+    if(e1 instanceof WTPResourcesNode && e2 instanceof IResource) {
+        return -1;
+    } else if(e2 instanceof WTPResourcesNode && e1 instanceof IResource) {
+        return 1;
+    }
+	if (e1 instanceof IFolder && e2 instanceof IFile) {
+		return -1;
+	} else if (e2 instanceof IFolder && e1 instanceof IFile) {
+		return 1;
+	}
+    
+    return super.compare(viewer, e1, e2);
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/build/WarProjectBuildParticipant.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/build/WarProjectBuildParticipant.java
new file mode 100644
index 0000000..cc57dc6
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/build/WarProjectBuildParticipant.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.build;
+
+import static org.eclipse.m2e.wtp.MavenWtpConstants.WTP_MARKER_FAIL_ON_MISSING_WEBXML_ERROR;
+
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.internal.MavenPluginActivator;
+import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager;
+import org.eclipse.m2e.core.internal.markers.SourceLocation;
+import org.eclipse.m2e.core.internal.markers.SourceLocationHelper;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.m2e.wtp.WarPluginConfiguration;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.internal.filtering.ResourceFilteringBuildParticipant;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+
+/**
+ * WarProjectBuildParticipant
+ *
+ * @author Fred Bricon
+ */
+public class WarProjectBuildParticipant extends ResourceFilteringBuildParticipant {
+
+	@SuppressWarnings("restriction")
+	@Override
+	public Set<IProject> build(int kind, IProgressMonitor monitor) throws Exception {
+		super.build(kind, monitor);
+
+		IMavenProjectFacade facade = getMavenProjectFacade();
+		IProject project = facade.getProject();
+		boolean iswtp = WTPProjectsUtil.isWTPProject(project);
+		if (!iswtp) {
+			return null;
+		}
+
+		final Boolean[] requiresWebXmlCheck = new Boolean[1]; 
+		requiresWebXmlCheck[0]=Boolean.FALSE;
+		boolean deleteMarkers = true;
+		switch(kind) {
+			case IncrementalProjectBuilder.CLEAN_BUILD:
+				break;
+			case IncrementalProjectBuilder.FULL_BUILD:
+				requiresWebXmlCheck[0] = Boolean.TRUE;
+				break;
+			default :
+			IResourceDelta delta = getDelta(project);
+			if (delta != null) {
+				delta.accept(new IResourceDeltaVisitor() {
+					@Override
+					public boolean visit(IResourceDelta delta) {
+						boolean foundInterestingFile = false;
+						IResource resource = delta.getResource();
+						if (resource instanceof IFile) {
+							String name = resource.getName(); 
+							if ("web.xml".equals(name)//$NON-NLS-1$
+									|| IMavenConstants.POM_FILE_NAME.equals(name)) {
+								foundInterestingFile = true;
+								requiresWebXmlCheck[0] = Boolean.TRUE;
+							}
+						}
+						return !foundInterestingFile;
+					}
+				});
+			}
+			deleteMarkers = requiresWebXmlCheck[0];
+		}
+
+		IMavenMarkerManager markerManager  = MavenPluginActivator.getDefault().getMavenMarkerManager();
+		IFile pom = facade.getPom();
+
+		if (deleteMarkers && pom.findMarkers(WTP_MARKER_FAIL_ON_MISSING_WEBXML_ERROR, false, IResource.DEPTH_ZERO) != null) {
+			markerManager.deleteMarkers(pom, WTP_MARKER_FAIL_ON_MISSING_WEBXML_ERROR);
+		}
+
+		if (requiresWebXmlCheck[0]) {
+			MavenProject mavenProject = facade.getMavenProject(monitor);
+			WarPluginConfiguration warConfig = new WarPluginConfiguration(mavenProject, project);
+			if (warConfig.isFailOnMissingWebXml() 
+					   && isWebXmlMissing(project)) {
+				
+				SourceLocation sourceLocation = SourceLocationHelper.findLocation(mavenProject, 
+						new MojoExecutionKey("org.apache.maven.plugins", "maven-war-plugin", null, null, null, null)); //$NON-NLS-1$ //$NON-NLS-2$
+				markerManager.addMarker(pom, WTP_MARKER_FAIL_ON_MISSING_WEBXML_ERROR, 
+                        Messages.WarProjectBuildParticipant_Error_FailOnMissingWebXml, 
+                        sourceLocation.getLineNumber(), IMarker.SEVERITY_ERROR);
+			}
+		}
+		return null;
+	}
+
+	private boolean isWebXmlMissing(IProject project) {
+		IVirtualComponent component = ComponentCore.createComponent(project, true);
+	    if(component != null) {      
+	      IVirtualFolder rootFolder = component.getRootFolder();
+	      return rootFolder.findMember(new Path("WEB-INF/web.xml")) == null; //$NON-NLS-1$
+	    }
+		return false;
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AbstractProjectFacetConversionEnabler.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AbstractProjectFacetConversionEnabler.java
new file mode 100644
index 0000000..e3aa707
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AbstractProjectFacetConversionEnabler.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *      Red Hat, Inc - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.internal.conversion;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.m2e.core.project.conversion.AbstractProjectConversionEnabler;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract Project Conversion Enabler that accepts a {@link IProject} based on the presence of an {@link IProjectFacet} 
+ * on the given project.
+ *
+ * @author Fred Bricon
+ * @since 0.17.0
+ */
+public abstract class AbstractProjectFacetConversionEnabler extends AbstractProjectConversionEnabler {
+
+  private static final Logger LOG = LoggerFactory.getLogger(AbstractProjectFacetConversionEnabler.class); 
+  
+  private IProjectFacet requiredFacet;
+
+  public AbstractProjectFacetConversionEnabler(IProjectFacet requiredFacet) {
+    this.requiredFacet = requiredFacet;
+  }
+  
+  /**
+   * Checks the project has the required {@link IProjectFacet}
+   */
+  @Override
+  public boolean accept(IProject project) {
+    if (project != null) {
+      IFacetedProject facetedProject;
+      try {
+        facetedProject = ProjectFacetsManager.create(project);
+        return facetedProject != null && facetedProject.hasProjectFacet(requiredFacet);
+      } catch(CoreException ex) {
+        LOG.error(NLS.bind(Messages.AbstractProjectFacetConversionEnabler_Error_Accessing_Project,project.getName()), ex);
+      }
+    }
+    return false;
+  }
+  
+  
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AbstractWtpProjectConversionParticipant.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AbstractWtpProjectConversionParticipant.java
new file mode 100644
index 0000000..cae46a8
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AbstractWtpProjectConversionParticipant.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.m2e.core.project.conversion.AbstractProjectConversionParticipant;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * AbstractWtpProjectConversionParticipant
+ *
+ * @author Fred Bricon
+ */
+public abstract class AbstractWtpProjectConversionParticipant extends AbstractProjectConversionParticipant {
+
+  protected abstract IProjectFacet getRequiredFaced();
+  
+  protected static final String CONFIGURATION_KEY = "configuration"; //$NON-NLS-1$
+
+  @Override
+  public boolean accept(IProject project) throws CoreException {
+    IFacetedProject fp = ProjectFacetsManager.create(project);
+    if (fp != null && fp.hasProjectFacet(getRequiredFaced()))  {
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * @return a clone of the model's {@link Build} if it exists or a new instance.
+   */
+  protected Build getCloneOrCreateBuild(Model model) {
+    Build build;
+    if (model.getBuild() == null) {
+      build = new Build();
+    } else {
+      build = model.getBuild().clone();
+    }
+    return build;
+  }
+  
+  protected Plugin setPlugin(Build build, String pluginGroupId, String pluginArtifactId, String pluginVersion) {
+    build.flushPluginMap();//We need to force the re-generation of the plugin map as it may be stale
+    Plugin plugin = build.getPluginsAsMap().get(pluginGroupId+":"+pluginArtifactId); //$NON-NLS-1$  
+    if (plugin == null) {
+      plugin = build.getPluginsAsMap().get(pluginArtifactId);
+    }
+    if (plugin == null) {
+      plugin = new Plugin();
+      plugin.setGroupId(pluginGroupId);
+      plugin.setArtifactId(pluginArtifactId);
+      plugin.setVersion(pluginVersion);
+      build.addPlugin(plugin);
+    }
+    
+    return plugin;
+  }
+  
+  protected Xpp3Dom getOrCreateConfiguration(Plugin plugin) {
+    Xpp3Dom configuration = (Xpp3Dom)plugin.getConfiguration();
+    if (configuration == null) {
+      configuration = new Xpp3Dom(CONFIGURATION_KEY);
+    }
+    return configuration;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AppClientProjectConversionEnabler.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AppClientProjectConversionEnabler.java
new file mode 100644
index 0000000..2e251cb
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AppClientProjectConversionEnabler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *      Red Hat, Inc - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.wtp.JEEPackaging;
+
+/**
+ * Enables Maven project conversion on Faceted Application Client projects, 
+ * i.e having the {@link IJ2EEFacetConstants.APPLICATION_CLIENT_FACET} Facet. 
+ *
+ * @author Fred Bricon
+ * @since 0.17.0
+ */
+public class AppClientProjectConversionEnabler extends AbstractProjectFacetConversionEnabler {
+
+  public AppClientProjectConversionEnabler() {
+    super(IJ2EEFacetConstants.APPLICATION_CLIENT_FACET);
+  }
+  
+  /**
+   * Returns the <code>app-client</code> packaging
+   */
+  @Override
+public String[] getPackagingTypes(IProject project) {
+    return new String[]{JEEPackaging.APP_CLIENT.getName()};
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AppClientProjectConverter.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AppClientProjectConverter.java
new file mode 100644
index 0000000..22215ed
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/AppClientProjectConverter.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import static org.eclipse.m2e.wtp.DomUtils.getOrCreateChildNode;
+
+import java.io.InputStream;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+
+/**
+ * Converts Eclipse WTP Application Client project settings into maven-acr-plugin configuration 
+ *
+ * @author Fred Bricon
+ */
+public class AppClientProjectConverter extends AbstractWtpProjectConversionParticipant {
+
+  private static final String MAIN_CLASS = "Main-Class"; //$NON-NLS-1$
+  
+  @Override
+public void convert(IProject project, Model model, IProgressMonitor monitor) throws CoreException {
+    if (!accept(project) || !"app-client".equals(model.getPackaging())) { //$NON-NLS-1$
+      return;
+    }
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    if (component == null) {
+      return;
+    }
+
+    setAcrPlugin(component, model);
+  }
+
+  private void setAcrPlugin(IVirtualComponent component, Model model) {
+    Build build = getCloneOrCreateBuild(model);
+    String pluginVersion = getAcrPluginVersion();
+    Plugin acrPlugin = setPlugin(build, "org.apache.maven.plugins", "maven-acr-plugin", pluginVersion); //$NON-NLS-1$ //$NON-NLS-2$
+    acrPlugin.setExtensions(true);
+    
+    String mainClass = getMainClass(component.getProject());
+    if (mainClass != null) {
+      configureManifest(acrPlugin, mainClass);
+    }
+    
+    model.setBuild(build);
+  }
+
+  private void configureManifest(Plugin acrPlugin, String mainClass) {
+    Xpp3Dom archiver = getArchiver(acrPlugin);
+    
+    Xpp3Dom manifestEntriesDom = getOrCreateChildNode(archiver, "manifestEntries"); //$NON-NLS-1$
+    
+    for (Xpp3Dom entry : manifestEntriesDom.getChildren()) {
+      if (MAIN_CLASS.equals(entry.getName()) && StringUtils.isNotEmpty(entry.getValue())) {
+        //Main already set, no need to go further
+        return;
+      }
+    }
+    
+    Xpp3Dom  main = new Xpp3Dom(MAIN_CLASS);
+    main.setValue(mainClass);
+    manifestEntriesDom.addChild(main);
+  }
+  
+  private Xpp3Dom getArchiver(Plugin plugin) {
+    Xpp3Dom config = getOrCreateConfiguration(plugin);
+    plugin.setConfiguration(config);
+    return getOrCreateChildNode(config, "archive"); //$NON-NLS-1$
+  }
+  
+  private String getMainClass(IProject project) {
+    //Get Main attribute from existing MANIFEST.MF
+    IJavaProject javaProject = JavaCore.create(project);
+    if (javaProject == null) {
+      return null;
+    }
+    IFile manifest = null;
+    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+    IClasspathEntry[] classpath;
+    try {
+      classpath = javaProject.getRawClasspath();
+      for (IClasspathEntry cpe : classpath) {
+        if (IClasspathEntry.CPE_SOURCE == cpe.getEntryKind()) {
+          IFile sourceManifest = root.getFile(cpe.getPath().append("META-INF/MANIFEST.MF"));   //$NON-NLS-1$
+          if (sourceManifest.exists()) {
+            manifest = sourceManifest;
+            break;
+          }
+        }
+      }
+    } catch(JavaModelException ex) {
+      // TODO proper logging
+      ex.printStackTrace();
+    }
+    
+    if (manifest == null) {
+      return null;
+    }
+    
+    InputStream is = null;
+    try {
+      is = manifest.getContents();
+      Manifest mf = new Manifest(is);
+      Attributes mainAttributes = mf.getMainAttributes();
+      return mainAttributes.getValue(MAIN_CLASS);
+    } catch (Exception ex) {
+      ex.printStackTrace();//TODO proper logging
+    } finally {
+      IOUtil.close(is);
+    }
+    return null;
+  }
+
+  @Override
+  protected IProjectFacet getRequiredFaced() {
+    return WTPProjectsUtil.APP_CLIENT_FACET;
+  }
+
+  private String getAcrPluginVersion() {
+	 //For test purposes only, must not be considered API behavior.
+	 String version = System.getProperty("org.eclipse.m2e.wtp.conversion.acrplugin.version");//$NON-NLS-1$
+	 if(version != null) {
+	   return version;
+	 }
+	 return MavenPluginUtils.getMostRecentPluginVersion("org.apache.maven.plugins", "maven-acr-plugin", "1.1"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/ConnectorProjectConversionEnabler.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/ConnectorProjectConversionEnabler.java
new file mode 100644
index 0000000..9b3b345
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/ConnectorProjectConversionEnabler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *      Red Hat, Inc - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.wtp.JEEPackaging;
+
+/**
+ * Enables Maven project conversion on Faceted Connector projects, 
+ * i.e having the {@link IJ2EEFacetConstants.JCA_FACET} Facet. 
+ *
+ * @author Fred Bricon
+ * @since 0.17.0
+ */
+public class ConnectorProjectConversionEnabler extends AbstractProjectFacetConversionEnabler {
+
+  public ConnectorProjectConversionEnabler() {
+    super(IJ2EEFacetConstants.JCA_FACET);
+  }
+  
+  /**
+   * Returns the <code>rar</code> packaging
+   */
+  @Override
+public String[] getPackagingTypes(IProject project) {
+    return new String[]{JEEPackaging.RAR.getName()};
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/ConnectorProjectConverter.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/ConnectorProjectConverter.java
new file mode 100644
index 0000000..fb2e5d2
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/ConnectorProjectConverter.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import static org.eclipse.m2e.wtp.internal.conversion.MavenPluginUtils.configure;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+
+/**
+ * Converts Eclipse WTP Connector project settings into maven-rar-plugin configuration 
+ *
+ * @author Fred Bricon
+ */
+public class ConnectorProjectConverter extends AbstractWtpProjectConversionParticipant {
+
+  private static final String DEFAULT_RA_XML = "src/main/rar/META-INF/ra.xml"; //$NON-NLS-1$
+
+  @Override
+public void convert(IProject project, Model model, IProgressMonitor monitor) throws CoreException {
+    if (!accept(project) || !"rar".equals(model.getPackaging())) { //$NON-NLS-1$
+      return;
+    }
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    if (component == null) {
+      return;
+    }
+
+    //Setting the maven-jar-plugin is necessary in order to embed generated class files 
+    setJarPlugin(component, model);
+    
+    setRarPlugin(component, model);
+  }
+
+  private void setJarPlugin(IVirtualComponent component, Model model) {
+    Build build = getCloneOrCreateBuild(model);
+    //maven-jar-plugin 2.4 is not supported by the mavenarchiver plugin
+    //see https://github.com/sonatype/m2eclipse-extras/issues/10
+    Plugin jarPlugin = setPlugin(build, "org.apache.maven.plugins", "maven-jar-plugin", "2.3.2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+    PluginExecution jarExecution = new PluginExecution();
+    jarExecution.setId("build_jar"); //$NON-NLS-1$
+    //Tell maven to package the project classes as a jar
+    jarExecution.addGoal("jar"); //$NON-NLS-1$
+    //The .jar must be created before the rar is packaged.
+    jarExecution.setPhase("prepare-package"); //$NON-NLS-1$
+    jarPlugin.addExecution(jarExecution);
+
+    model.setBuild(build);
+  }
+
+  private void setRarPlugin(IVirtualComponent component, Model model) throws CoreException {
+    Build build = getCloneOrCreateBuild(model);
+    String pluginVersion = getRarPluginVersion();
+    Plugin rarPlugin = setPlugin(build, "org.apache.maven.plugins", "maven-rar-plugin", pluginVersion); //$NON-NLS-1$ //$NON-NLS-2$
+    IFile raXml = findRaXml(component);
+    if (raXml != null) {
+      String raXmlPath = raXml.getProjectRelativePath().toPortableString();
+      if (!DEFAULT_RA_XML.equals(raXmlPath)) {
+        //Failing to set up non default ra.xml would make maven-rar-plugin crash
+        configure(rarPlugin, "raXmlFile", raXmlPath); //$NON-NLS-1$
+        model.setBuild(build);
+      }
+    }
+  }
+
+  @Override
+protected IProjectFacet getRequiredFaced() {
+    return WTPProjectsUtil.JCA_FACET;
+  }
+
+  private IFile findRaXml(IVirtualComponent component) throws CoreException {
+    for (IVirtualResource vr : component.getRootFolder().members()) {
+      if (vr instanceof IVirtualFolder) {
+        IFolder f = (IFolder)((IVirtualFolder) vr).getUnderlyingFolder();
+        if ("META-INF".equals(f.getName())) { //$NON-NLS-1$
+          IFile ra = f.getFile("ra.xml"); //$NON-NLS-1$
+          if (ra.isAccessible()) {
+            return ra;
+          }
+        }
+      }
+    }
+    return null;
+  }
+  
+  private String getRarPluginVersion() {
+	 //For test purposes only, must not be considered API behavior.
+	 String version = System.getProperty("org.eclipse.m2e.wtp.conversion.rarplugin.version");//$NON-NLS-1$
+	 if(version != null) {
+	   return version;
+	 }
+	 return MavenPluginUtils.getMostRecentPluginVersion("org.apache.maven.plugins", "maven-rar-plugin", "2.4"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EarProjectConversionEnabler.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EarProjectConversionEnabler.java
new file mode 100644
index 0000000..f18b34f
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EarProjectConversionEnabler.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *      Red Hat, Inc - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.wtp.JEEPackaging;
+
+/**
+ * Enables Maven project conversion on Faceted EAR projects, 
+ * i.e having the {@link IJ2EEFacetConstants.ENTERPRISE_APPLICATION_FACET} Facet. 
+ *
+ * @author Fred Bricon
+ * @since 0.17.0
+ */
+public class EarProjectConversionEnabler extends AbstractProjectFacetConversionEnabler {
+
+  public EarProjectConversionEnabler() {
+    super(IJ2EEFacetConstants.ENTERPRISE_APPLICATION_FACET);
+  }
+
+  /**
+   * Returns the <code>ear</code> packaging
+   */
+  @Override
+public String[] getPackagingTypes(IProject project) {
+    return new String[]{JEEPackaging.EAR.getName()};
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EarProjectConverter.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EarProjectConverter.java
new file mode 100644
index 0000000..25365c9
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EarProjectConverter.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import static org.eclipse.m2e.wtp.internal.conversion.MavenPluginUtils.configure;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jst.j2ee.project.EarUtilities;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Converts Eclipse WTP EAR project settings into maven-ear-plugin configuration 
+ *
+ * @author Fred Bricon
+ */
+public class EarProjectConverter extends AbstractWtpProjectConversionParticipant {
+
+  private static final String DEFAULT_APPLICATION_FOLDER = "src/main/application"; //$NON-NLS-1$
+  
+  private static final String EAR_SOURCE_DIRECTORY_KEY = "earSourceDirectory"; //$NON-NLS-1$
+
+  private static final String EAR_VERSION = "version"; //$NON-NLS-1$
+
+  private static final String GENERATE_APPLICATION_XML = "generateApplicationXml"; //$NON-NLS-1$
+  
+  private static final Logger LOG = LoggerFactory.getLogger(EarProjectConverter.class);
+
+  @Override
+public void convert(IProject project, Model model, IProgressMonitor monitor) throws CoreException {
+    if (!accept(project) || !"ear".equals(model.getPackaging())) { //$NON-NLS-1$
+      return;
+    }
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    if (component == null) {
+      return;
+    }
+
+    setEarPlugin(component, model);
+  }
+
+  private void setEarPlugin(IVirtualComponent component, Model model) throws CoreException {
+    Build build = getCloneOrCreateBuild(model);
+    String pluginVersion = getEarPluginVersion();
+    Plugin earPlugin = setPlugin(build, "org.apache.maven.plugins", "maven-ear-plugin", pluginVersion); //$NON-NLS-1$ //$NON-NLS-2$
+  
+    // Set  <earSourceDirectory>EarContent</earSourceDirectory>
+    IFolder applicationContentFolder = findEarContentFolder(component);
+    boolean hasApplicationXml=true;
+    boolean customized = false;
+    IProject project = component.getProject();
+    if (applicationContentFolder != null) {
+      String applicationContent = applicationContentFolder.getProjectRelativePath().toPortableString();
+      if (!DEFAULT_APPLICATION_FOLDER.equals(applicationContent)) {
+        configure(earPlugin, EAR_SOURCE_DIRECTORY_KEY, applicationContent);
+        customized = true;
+      }
+      hasApplicationXml = applicationContentFolder.getFile("META-INF/application.xml").exists(); //$NON-NLS-1$
+    }
+    else{
+      String msg =  NLS.bind(Messages.EarProjectConverter_Error_EAR_Root_Content_Folder, (project!= null?project.getName():component.getName()));
+      String description = model.getDescription();
+      String warning = "!!!EAR resources from the root directory need to be moved under src/main/application!!!";
+      if (StringUtils.isNotEmpty(description)) {
+    	  description = description + "\n" + warning;
+      } else {
+    	  description = warning;
+      }
+      model.setDescription(description);
+      LOG.warn(msg);
+    }
+    
+    IFacetedProject fProject = ProjectFacetsManager.create(component.getProject());
+    if (fProject != null) {
+      IProjectFacetVersion earVersion = fProject.getProjectFacetVersion(IJ2EEFacetConstants.ENTERPRISE_APPLICATION_FACET);
+      if (!IJ2EEFacetConstants.ENTERPRISE_APPLICATION_13.equals(earVersion)) {
+        String version;
+        boolean isJavaEE = earVersion.compareTo(IJ2EEFacetConstants.ENTERPRISE_APPLICATION_50) >= 0;
+        if (isJavaEE) {
+          // maven-ear-plugin needs version 5 instead of 5.0
+          version = earVersion.getVersionString().substring(0, 1);//Yuck!
+          if (!hasApplicationXml){
+            configure(earPlugin, GENERATE_APPLICATION_XML, "false"); //$NON-NLS-1$
+          }
+        } else {
+          version = earVersion.getVersionString();
+        }
+        configure(earPlugin, EAR_VERSION, version);
+        customized = true;
+      }
+      
+      String libDir = EarUtilities.getEARLibDir(component);
+      if (libDir == null) {
+        IContainer libDirContainer = applicationContentFolder == null?project:applicationContentFolder;
+		libDir = inspectDefaultLibDirs(libDirContainer );
+      }
+      if (libDir != null) {
+        configure(earPlugin, "defaultLibBundleDir", libDir); //$NON-NLS-1$
+        customized = true;
+      }
+      
+    }
+
+    if (customized) {
+      model.setBuild(build);
+    }
+  }
+
+  /**
+   * Checks if a lib directory exists in the application content folder
+   * @return the relative path of the lib directory, if it exists, null otherwise
+   */
+  private String inspectDefaultLibDirs(IContainer applicationContentFolder) {
+    for (String candidate : new String[] {"lib", "APP-INF/lib"}) { //$NON-NLS-1$ //$NON-NLS-2$
+      if  (applicationContentFolder.getFolder(new Path(candidate)).exists()) {
+        return candidate;
+      }
+    }
+    return null;
+  }
+
+  private IFolder findEarContentFolder(IVirtualComponent component) {
+    return WTPProjectsUtil.getDefaultDeploymentDescriptorFolder(component.getRootFolder());
+  }
+
+  @Override
+  protected IProjectFacet getRequiredFaced() {
+    return WTPProjectsUtil.EAR_FACET;
+  }
+
+  private String getEarPluginVersion() {
+	 //For test purposes only, must not be considered API behavior.
+	 String version = System.getProperty("org.eclipse.m2e.wtp.conversion.earplugin.version");//$NON-NLS-1$
+	 if(version != null) {
+	   return version;
+	 }
+	 return MavenPluginUtils.getMostRecentPluginVersion("org.apache.maven.plugins", "maven-ear-plugin", "2.10"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EjbProjectConversionEnabler.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EjbProjectConversionEnabler.java
new file mode 100644
index 0000000..c510ed3
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EjbProjectConversionEnabler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *      Red Hat, Inc - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.wtp.JEEPackaging;
+
+/**
+ * Enables Maven project conversion on Faceted EJB projects, 
+ * i.e having the {@link IJ2EEFacetConstants.EJB_FACET} Facet. 
+ *
+ * @author Fred Bricon
+ * @since 0.17.0
+ */
+public class EjbProjectConversionEnabler extends AbstractProjectFacetConversionEnabler {
+
+  public EjbProjectConversionEnabler() {
+    super(IJ2EEFacetConstants.EJB_FACET);
+  }
+  
+  /**
+   * Returns the <code>ejb</code> packaging
+   */
+  @Override
+public String[] getPackagingTypes(IProject project) {
+    return new String[]{JEEPackaging.EJB.getName()};
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EjbProjectConverter.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EjbProjectConverter.java
new file mode 100644
index 0000000..85f41d1
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/EjbProjectConverter.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import static org.eclipse.m2e.wtp.internal.conversion.MavenPluginUtils.configure;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * Converts Eclipse WTP EJB project settings into maven-ejb-plugin configuration 
+ *
+ * @author Fred Bricon
+ */
+public class EjbProjectConverter extends AbstractWtpProjectConversionParticipant {
+
+  private static final String EJB_VERSION= "ejbVersion"; //$NON-NLS-1$
+
+  @Override
+public void convert(IProject project, Model model, IProgressMonitor monitor) throws CoreException {
+    if (!accept(project) || !"ejb".equals(model.getPackaging())) { //$NON-NLS-1$
+      return;
+    }
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    if (component == null) {
+      return;
+    }
+
+    setEjbPlugin(component, model);
+  }
+
+  private void setEjbPlugin(IVirtualComponent component, Model model) throws CoreException {
+    Build build = getCloneOrCreateBuild(model);
+    String pluginVersion = getEjbPluginVersion();
+    Plugin ejbPlugin = setPlugin(build, "org.apache.maven.plugins", "maven-ejb-plugin", pluginVersion); //$NON-NLS-1$ //$NON-NLS-2$
+  
+    IFacetedProject fProject = ProjectFacetsManager.create(component.getProject());
+    boolean customized = false;
+    if (fProject != null) {
+      IProjectFacetVersion ejbVersion = fProject.getProjectFacetVersion(IJ2EEFacetConstants.EJB_FACET);
+      if (!IJ2EEFacetConstants.EJB_21.equals(ejbVersion)) {
+        configure(ejbPlugin, EJB_VERSION, ejbVersion.getVersionString());
+        customized = true;
+      }
+    }
+
+    if (customized) {
+      model.setBuild(build);
+    }
+  }
+
+  @Override
+  protected IProjectFacet getRequiredFaced() {
+    return WTPProjectsUtil.EJB_FACET;
+  }
+
+  private String getEjbPluginVersion() {
+	 //For test purposes only, must not be considered API behavior.
+	 String version = System.getProperty("org.eclipse.m2e.wtp.conversion.ejbplugin.version");//$NON-NLS-1$
+	 if(version != null) {
+	   return version;
+	 }
+	 return MavenPluginUtils.getMostRecentPluginVersion("org.apache.maven.plugins", "maven-ejb-plugin", "2.5"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/MavenPluginUtils.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/MavenPluginUtils.java
new file mode 100644
index 0000000..927e515
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/MavenPluginUtils.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.versioning.ComparableVersion;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.internal.index.IIndex;
+import org.eclipse.m2e.core.internal.index.IndexedArtifact;
+import org.eclipse.m2e.core.internal.index.IndexedArtifactFile;
+import org.eclipse.m2e.core.internal.index.SearchExpression;
+import org.eclipse.m2e.core.internal.index.SourcedSearchExpression;
+import org.eclipse.m2e.jdt.internal.JavaProjectConversionParticipant;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class for {@link Plugin} manipulations.
+ *
+ * @author Fred Bricon
+ */
+public class MavenPluginUtils {
+
+  private static final Logger log = LoggerFactory.getLogger(MavenPlugin.class);
+  
+  private static final String CONFIGURATION_KEY = "configuration"; //$NON-NLS-1$
+
+  private MavenPluginUtils() {
+  }
+  
+  private static Xpp3Dom getOrCreateConfiguration(Plugin plugin) {
+    Xpp3Dom configuration = (Xpp3Dom)plugin.getConfiguration();
+    if (configuration == null) {
+      configuration = new Xpp3Dom(CONFIGURATION_KEY);
+      plugin.setConfiguration(configuration);
+    }
+    return configuration;
+  }
+  
+  public static void configure(Plugin plugin, String key, String value) {
+    if (plugin == null) {
+      return;
+    }
+    Xpp3Dom configuration = getOrCreateConfiguration(plugin);
+    Xpp3Dom keyDom = configuration.getChild(key);
+    if (keyDom == null) {
+      keyDom = new Xpp3Dom(key);
+      configuration.addChild(keyDom);
+    }  
+    keyDom.setValue(value);
+  }
+  
+
+  /**
+   * Returns the highest, non-snapshot plugin version between the given reference version and the versions found in the
+   * Nexus indexes.
+   * 
+   * This code was copied from {@link JavaProjectConversionParticipant}
+   */
+  @SuppressWarnings("restriction")
+  public static String getMostRecentPluginVersion(String groupId, String artifactId, String referenceVersion) {
+      Assert.isNotNull(groupId, Messages.MavenPluginUtils_GroupId_Cant_Be_Null);
+      Assert.isNotNull(artifactId, Messages.MavenPluginUtils_ArtifactId_Cant_Be_Null);
+      String version = referenceVersion;
+      String partialKey = artifactId + " : " + groupId; //$NON-NLS-1$
+      try {
+        IIndex index = MavenPlugin.getIndexManager().getAllIndexes();
+        SearchExpression a = new SourcedSearchExpression(artifactId);
+
+        //For some reason, an exact search using : 
+        //ISearchEngine searchEngine  = M2EUIPluginActivator.getDefault().getSearchEngine(null)
+        //searchEngine.findVersions(groupId, artifactId, searchExpression, packaging)
+        //
+        //doesn't yield the expected results (the latest versions are not returned), so we rely on a fuzzier search
+        //and refine the results.
+        Map<String, IndexedArtifact> values = index.search(a, IIndex.SEARCH_PLUGIN);
+        if(!values.isEmpty()) {
+          SortedSet<ComparableVersion> versions = new TreeSet<ComparableVersion>();
+          ComparableVersion referenceComparableVersion = referenceVersion == null ? null : new ComparableVersion(
+              referenceVersion);
+
+          for(Map.Entry<String, IndexedArtifact> e : values.entrySet()) {
+            if(!(e.getKey().endsWith(partialKey))) {
+              continue;
+            }
+            for(IndexedArtifactFile f : e.getValue().getFiles()) {
+              if(groupId.equals(f.group) && artifactId.equals(f.artifact) && !f.version.contains("-SNAPSHOT")) { //$NON-NLS-1$
+                ComparableVersion v = new ComparableVersion(f.version);
+                if(referenceComparableVersion == null || v.compareTo(referenceComparableVersion) > 0) {
+                  versions.add(v);
+                }
+              }
+            }
+            if(!versions.isEmpty()) {
+              List<String> sorted = new ArrayList<>(versions.size());
+              for(ComparableVersion v : versions) {
+                sorted.add(v.toString());
+              }
+              Collections.reverse(sorted);
+              version = sorted.iterator().next();
+            }
+          }
+        }
+      } catch(CoreException e) {
+        log.error(NLS.bind(Messages.MavenPluginUtils_Error_Cant_Retrieve_Latest_Plugin_Version, partialKey), e);
+      }
+      return version;
+    }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/WebProjectConversionEnabler.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/WebProjectConversionEnabler.java
new file mode 100644
index 0000000..333ec25
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/WebProjectConversionEnabler.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *      Red Hat, Inc - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.wtp.JEEPackaging;
+
+/**
+ * Enables Maven project conversion on Faceted Dynamic Web projects, 
+ * i.e having the {@link IJ2EEFacetConstants.DYNAMIC_WEB_FACET} Facet. 
+ *
+ * @author Fred Bricon
+ * @since 0.17.0
+ */
+public class WebProjectConversionEnabler extends AbstractProjectFacetConversionEnabler {
+
+  public WebProjectConversionEnabler() {
+    super(IJ2EEFacetConstants.DYNAMIC_WEB_FACET);
+  }
+  
+  /**
+   * Returns the <code>war</code> packaging
+   */
+  @Override
+public String[] getPackagingTypes(IProject project) {
+    return new String[]{JEEPackaging.WAR.getName()};
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/WebProjectConverter.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/WebProjectConverter.java
new file mode 100644
index 0000000..4378bc1
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/conversion/WebProjectConverter.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.conversion;
+
+import static org.eclipse.m2e.wtp.internal.conversion.MavenPluginUtils.configure;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.jst.j2ee.web.project.facet.WebFacetUtils;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * Converts Eclipse WTP Dynamic Web project settings into maven-war-plugin configuration 
+ *
+ * @author Fred Bricon
+ */
+public class WebProjectConverter extends AbstractWtpProjectConversionParticipant {
+
+  private static final String DEFAULT_WAR_SOURCE_FOLDER = "src/main/webapp"; //$NON-NLS-1$
+  
+  private static final String WAR_SOURCE_DIRECTORY_KEY = "warSourceDirectory"; //$NON-NLS-1$
+
+  private static final String FAIL_IF_MISSING_WEBXML_KEY = "failOnMissingWebXml"; //$NON-NLS-1$
+
+  @Override
+  public void convert(IProject project, Model model, IProgressMonitor monitor) throws CoreException {
+    if (!accept(project) || !"war".equals(model.getPackaging())) { //$NON-NLS-1$
+      return;
+    }
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    if (component == null) {
+      return;
+    }
+
+    setWarPlugin(component, model);
+  }
+
+  private void setWarPlugin(IVirtualComponent component, Model model) throws CoreException {
+    Build build = getCloneOrCreateBuild(model);
+    String warPluginVersion = getWarPluginVersion();
+    Plugin warPlugin = setPlugin(build, "org.apache.maven.plugins", "maven-war-plugin", warPluginVersion); //$NON-NLS-1$ //$NON-NLS-2$
+  
+    // Set  <warSourceDirectory>WebContent</warSourceDirectory>
+    IFolder webContentFolder = findWebRootFolder(component);
+    boolean customized = false;
+    if (webContentFolder != null) {
+      String webContent = webContentFolder.getProjectRelativePath().toPortableString();
+      if (!DEFAULT_WAR_SOURCE_FOLDER.equals(webContent)) {
+        configure(warPlugin, WAR_SOURCE_DIRECTORY_KEY, webContent);
+        customized = true;
+      }
+    }
+    
+    //Set <failOnMissingWebXml>false</failOnMissingWebXml> for web > 2.4
+    IFacetedProject fProject = ProjectFacetsManager.create(component.getProject());
+    if (fProject != null) {
+      IProjectFacetVersion webVersion = fProject.getProjectFacetVersion(IJ2EEFacetConstants.DYNAMIC_WEB_FACET);
+      if (webVersion != null && webVersion.compareTo(IJ2EEFacetConstants.DYNAMIC_WEB_24) > 0) {
+        configure(warPlugin, FAIL_IF_MISSING_WEBXML_KEY, "false"); //$NON-NLS-1$
+        customized = true;
+      }
+    }
+
+    if (customized) {
+      model.setBuild(build);
+    }
+  }
+
+  private IFolder findWebRootFolder(IVirtualComponent component) {
+    return WTPProjectsUtil.getDefaultDeploymentDescriptorFolder(component.getRootFolder());
+  }
+
+  @Override
+  protected IProjectFacet getRequiredFaced() {
+    return WebFacetUtils.WEB_FACET;
+  }
+
+  private String getWarPluginVersion() {
+	 //For test purposes only, must not be considered API behavior.
+	 String version = System.getProperty("org.eclipse.m2e.wtp.conversion.warplugin.version");//$NON-NLS-1$
+	 if(version != null) {
+	   return version;
+	 }
+	 return MavenPluginUtils.getMostRecentPluginVersion("org.apache.maven.plugins", "maven-war-plugin", "2.6"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+  }
+
+  
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/AppClientUninstallDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/AppClientUninstallDelegate.java
new file mode 100644
index 0000000..b95dced
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/AppClientUninstallDelegate.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+/**
+ * Application Client Facet uninstall delegate
+ * 
+ * @author Fred Bricon
+ */
+public class AppClientUninstallDelegate extends NoOpUninstallDelegate {
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/AppClientVersionChangeListener.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/AppClientVersionChangeListener.java
new file mode 100644
index 0000000..2699c4c
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/AppClientVersionChangeListener.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jst.j2ee.project.facet.IAppClientFacetInstallDataModelProperties;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.datamodel.FacetDataModelProvider;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
+import org.eclipse.wst.common.project.facet.core.events.IProjectFacetActionEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Application Client Facet version change listener
+ * 
+ * @author Fred Bricon
+ */
+public class AppClientVersionChangeListener implements IFacetedProjectListener {
+
+  private static final Logger LOG = LoggerFactory.getLogger(AppClientVersionChangeListener.class);
+
+  /* (non-Javadoc)
+   * @see org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener#handleEvent(org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent)
+   */
+  @Override
+public void handleEvent(IFacetedProjectEvent event) {
+    if (event.getType().equals(IFacetedProjectEvent.Type.POST_VERSION_CHANGE)) {
+      IProject project = ((IProjectFacetActionEvent) event).getProject().getProject();
+      //The action applies if the Project has Maven nature and AppClient facet
+      try {
+        if(project.hasNature(IMavenConstants.NATURE_ID)){
+          if(((IProjectFacetActionEvent) event)
+              .getProjectFacet().getId().equals(IJ2EEFacetConstants.APPLICATION_CLIENT)){
+
+            NullProgressMonitor monitor = new NullProgressMonitor();
+            Object cfg = ((IProjectFacetActionEvent) event).getActionConfig();
+
+            if(cfg == null)
+              return;
+
+            IDataModel model = (IDataModel) cfg;
+
+            if(model.isProperty(IAppClientFacetInstallDataModelProperties.CONFIG_FOLDER)){
+              IPath appClientContent = new Path("/" + model.getStringProperty(IAppClientFacetInstallDataModelProperties.CONFIG_FOLDER));//$NON-NLS-1$
+              if (!WTPProjectsUtil.hasLink(project, new Path("/"), appClientContent, monitor)) {//$NON-NLS-1$
+                final IVirtualComponent c = ComponentCore.createComponent(project, true);
+                if (c != null) {
+                  final IVirtualFolder root = c.getRootFolder();
+                  root.createLink(appClientContent , 0, null); 
+                }
+              }
+              try {
+                ((IDataModelOperation) model.getProperty(FacetDataModelProvider.NOTIFICATION_OPERATION)).execute(monitor, null);
+              } catch(ExecutionException e) {
+                LOG.error(Messages.AppClientVersionChangeListener_Error_Notifying_Application_Client_Version_Change, e);
+              } 
+            }
+          }
+        }
+      } catch(CoreException e) {
+        LOG.error(Messages.VersionChangeListener_Unreadeable_Project_Nature, e);
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EarUninstallDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EarUninstallDelegate.java
new file mode 100644
index 0000000..98ff7e4
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EarUninstallDelegate.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+
+
+/**
+ * EAR uninstall delegate
+ * 
+ * @author Eugene Kuleshov
+ */
+public class EarUninstallDelegate extends NoOpUninstallDelegate {
+	
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EarVersionChangeListener.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EarVersionChangeListener.java
new file mode 100644
index 0000000..537e26e
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EarVersionChangeListener.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jst.j2ee.earcreation.IEarFacetInstallDataModelProperties;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.datamodel.FacetDataModelProvider;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
+import org.eclipse.wst.common.project.facet.core.events.IProjectFacetActionEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Ear update listener. Based off the org.eclipse.jst.j2ee.web.project.facet.WebFacetInstallDelegate
+ * 
+ * @author Fred Bricon
+ */
+public class EarVersionChangeListener implements IFacetedProjectListener {
+
+  private static final Logger LOG = LoggerFactory.getLogger(EarVersionChangeListener.class);
+
+  /* (non-Javadoc)
+   * @see org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener#handleEvent(org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent)
+   */
+  @Override
+public void handleEvent(IFacetedProjectEvent event) {
+    if (event.getType().equals(IFacetedProjectEvent.Type.POST_VERSION_CHANGE)) {
+      IProject project = ((IProjectFacetActionEvent) event).getProject().getProject();
+      //The action applies if the Project has Maven nature and ear facet
+      try {
+        if(project.hasNature(IMavenConstants.NATURE_ID)){
+          if(((IProjectFacetActionEvent) event)
+              .getProjectFacet().getId().equals(IJ2EEFacetConstants.ENTERPRISE_APPLICATION)){
+
+            NullProgressMonitor monitor = new NullProgressMonitor();
+            Object cfg = ((IProjectFacetActionEvent) event).getActionConfig();
+
+            if(cfg == null)
+              return;
+            IDataModel model = (IDataModel) cfg;
+
+            if(model.isProperty(IEarFacetInstallDataModelProperties.CONTENT_DIR)){
+              IPath earContent = new Path("/" + model.getStringProperty(IEarFacetInstallDataModelProperties.CONTENT_DIR));//$NON-NLS-1$
+              final IVirtualComponent c = ComponentCore.createComponent(project, true);
+              if (c != null) {
+                final IVirtualFolder earroot = c.getRootFolder();
+                if (!WTPProjectsUtil.hasLink(project, new Path("/"), earContent, monitor)) {//$NON-NLS-1$
+                  earroot.createLink(earContent , 0, null); 
+                }
+                WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(earroot, earContent, monitor);
+              }
+
+              try {
+                ((IDataModelOperation) model.getProperty(FacetDataModelProvider.NOTIFICATION_OPERATION)).execute(monitor, null);
+              } catch(ExecutionException e) {
+                LOG.error(Messages.EarVersionChangeListener_Error_Notifying_EAR_Version_Change, e);
+              } 
+            } 
+          }
+        }
+      }catch(CoreException e) {
+          LOG.error(Messages.VersionChangeListener_Unreadeable_Project_Nature, e);
+      }
+    }
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EjbUninstallDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EjbUninstallDelegate.java
new file mode 100644
index 0000000..84859bc
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EjbUninstallDelegate.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+
+
+/**
+ * EJB uninstall delegate
+ * 
+ * @author Eugene Kuleshov
+ */
+public class EjbUninstallDelegate extends NoOpUninstallDelegate {
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EjbVersionChangeListener.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EjbVersionChangeListener.java
new file mode 100644
index 0000000..f0501f5
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/EjbVersionChangeListener.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+
+
+/**
+ * EJB version change listener
+ * 
+ * @author Fred Bricon
+ */
+public class EjbVersionChangeListener extends NoOpVersionChangeListener {
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/NoOpUninstallDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/NoOpUninstallDelegate.java
new file mode 100644
index 0000000..a0fd61b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/NoOpUninstallDelegate.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.wst.common.project.facet.core.IDelegate;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * No Operation Facet uninstall delegate
+ * 
+ * @author Fred Bricon
+ */
+public class NoOpUninstallDelegate implements IDelegate {
+
+	@Override
+	public void execute(IProject project, IProjectFacetVersion fv,
+			Object config, IProgressMonitor monitor) throws CoreException {
+		// do nothing
+	}
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/NoOpVersionChangeListener.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/NoOpVersionChangeListener.java
new file mode 100644
index 0000000..af3b6a6
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/NoOpVersionChangeListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
+
+
+/**
+ * No Op Version change delegate
+ * 
+ * @author Fred Bricon
+ */
+public class NoOpVersionChangeListener implements IFacetedProjectListener {
+  
+    /* (non-Javadoc)
+     * @see org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener#handleEvent(org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent)
+     */
+    @Override
+	public void handleEvent(IFacetedProjectEvent event) {
+        //Does nothing
+    }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/RarUninstallDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/RarUninstallDelegate.java
new file mode 100644
index 0000000..9478518
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/RarUninstallDelegate.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+/**
+ * RAR uninstall delegate
+ * 
+ * @author Fred Bricon
+ */
+public class RarUninstallDelegate extends NoOpUninstallDelegate {
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/RarVersionChangeListener.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/RarVersionChangeListener.java
new file mode 100644
index 0000000..01e3795
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/RarVersionChangeListener.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+
+
+/**
+ * RAR version change listener
+ * 
+ * @author Fred Bricon
+ */
+public class RarVersionChangeListener extends NoOpVersionChangeListener {
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/WarUninstallDelegate.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/WarUninstallDelegate.java
new file mode 100644
index 0000000..f5271fe
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/WarUninstallDelegate.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
+import org.eclipse.wst.common.project.facet.core.IDelegate;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+
+/**
+ * WAR uninstall delegate
+ * 
+ * @author Eugene Kuleshov
+ */
+public class WarUninstallDelegate implements IDelegate {
+
+  @Override
+public void execute(IProject project, IProjectFacetVersion fv, Object config, IProgressMonitor monitor)
+      throws CoreException {
+    // remove web containers
+    ArrayList<IClasspathEntry> entries = new ArrayList<>();
+
+    IClasspathEntry[] cp = JavaCore.create(project).getRawClasspath();
+    for(IClasspathEntry entry : cp) {
+      String segment = entry.getPath().segment(0);
+      if(!"org.eclipse.jst.j2ee.internal.web.container".equals(segment) //$NON-NLS-1$
+          && !"org.eclipse.jst.j2ee.internal.module.container".equals(segment)) { //$NON-NLS-1$
+        entries.add(entry);
+      }
+    }
+
+    if(entries.size() < cp.length) {
+      JavaCore.create(project).setRawClasspath(entries.toArray(new IClasspathEntry[entries.size()]), monitor);
+    }
+    
+    IVirtualComponent c = ComponentCore.createComponent(project);
+    IVirtualFolder rootFolder = c.getRootFolder();
+    
+    IPath runtimePath = rootFolder.getRuntimePath();
+    rootFolder.removeLink(runtimePath, IVirtualResource.FORCE, monitor);
+    
+    rootFolder.delete(IVirtualResource.IGNORE_UNDERLYING_RESOURCE, monitor);
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/WarVersionChangeListener.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/WarVersionChangeListener.java
new file mode 100644
index 0000000..2f31478
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/facets/WarVersionChangeListener.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.facets;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEFacetConstants;
+import org.eclipse.jst.j2ee.project.facet.IJ2EEModuleFacetInstallDataModelProperties;
+import org.eclipse.jst.j2ee.web.project.facet.IWebFacetInstallDataModelProperties;
+import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.datamodel.FacetDataModelProvider;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
+import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
+import org.eclipse.wst.common.project.facet.core.events.IProjectFacetActionEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * War Facet update Listener. Based off the org.eclipse.jst.j2ee.web.project.facet.WebFacetInstallDelegate
+ * 
+ * @author Fred Bricon
+ */
+public class WarVersionChangeListener implements IFacetedProjectListener {
+
+  private static final Logger LOG = LoggerFactory.getLogger(WarVersionChangeListener.class);
+
+  /* (non-Javadoc)
+   * @see org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener#handleEvent(org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent)
+   */
+  @Override
+public void handleEvent(IFacetedProjectEvent event) {
+    if (event.getType().equals(IFacetedProjectEvent.Type.POST_VERSION_CHANGE)) {
+      IProject project = ((IProjectFacetActionEvent) event).getProject().getProject();
+      //The action applies if the Project has Maven nature and web facet
+      try {
+        if(project.hasNature(IMavenConstants.NATURE_ID)){
+          if(((IProjectFacetActionEvent) event)
+              .getProjectFacet().getId().equals(IJ2EEFacetConstants.DYNAMIC_WEB)){
+
+            NullProgressMonitor monitor = new NullProgressMonitor();
+            Object cfg = ((IProjectFacetActionEvent) event).getActionConfig();
+
+            if(cfg == null)
+              return;
+
+            IDataModel model = (IDataModel) cfg;
+
+            final IVirtualComponent c = ComponentCore.createComponent(project, true);
+
+            if (c == null)
+              return;
+
+            try{
+              if (model != null) {
+                //The model could not provide us the property we require
+                if(model.isProperty(IWebFacetInstallDataModelProperties.CONTEXT_ROOT)){
+                  final IWorkspace ws = ResourcesPlugin.getWorkspace();
+                  final IPath pjpath = project.getFullPath();
+
+                  final IPath contentdir = setContentPropertyIfNeeded(model, pjpath, project);
+                  mkdirs(ws.getRoot().getFolder(contentdir), monitor);
+                  IVirtualFolder contentRootFolder = c.getRootFolder();
+                  WTPProjectsUtil.setDefaultDeploymentDescriptorFolder(contentRootFolder, contentdir, monitor);
+
+                  String contextRoot = model.getStringProperty(IWebFacetInstallDataModelProperties.CONTEXT_ROOT);
+                  setContextRootPropertyIfNeeded(c, contextRoot);
+
+
+                  IDataModelOperation notificationOperation = ((IDataModelOperation) model.getProperty(FacetDataModelProvider.NOTIFICATION_OPERATION));
+                  if (notificationOperation != null) {
+                    notificationOperation.execute(monitor, null);
+                  }
+                }
+              }
+            }catch (ExecutionException e) {
+              LOG.error(Messages.WarVersionChangeListener_Error_Notifying_WebApp_Version_Change, e);
+            }
+          }
+        }
+      }catch(CoreException e) {
+          LOG.error(Messages.VersionChangeListener_Unreadeable_Project_Nature, e);
+      }
+    }
+  }
+
+
+  private static void mkdirs(final IFolder folder, IProgressMonitor monitor) throws CoreException {
+    if (!folder.exists()) {
+      if (folder.getParent() instanceof IFolder) {
+        mkdirs((IFolder) folder.getParent(), monitor);
+      }
+      folder.create(true, true, null);
+    }
+    else
+    {
+      IContainer x = folder;
+      while( x instanceof IFolder && x.isDerived() )
+      {
+        x.setDerived( false, monitor);
+        x = x.getParent();
+      }
+    }
+  }
+
+  private void setContextRootPropertyIfNeeded(final IVirtualComponent c, String contextRoot) {
+    String existing = c.getMetaProperties().getProperty("context-root"); //$NON-NLS-1$
+    if (existing == null)
+      c.setMetaProperty("context-root", contextRoot); //$NON-NLS-1$
+  }
+
+  private IPath setContentPropertyIfNeeded(final IDataModel model, final IPath pjpath, IProject project) {
+    IVirtualComponent c = ComponentCore.createComponent(project, false);
+    if (c.exists()) {
+      if( !c.getRootFolder().getProjectRelativePath().isRoot() ){
+        return c.getRootFolder().getUnderlyingResource().getFullPath();
+      }
+    }
+    return pjpath.append(model.getStringProperty(IJ2EEModuleFacetInstallDataModelProperties.CONFIG_FOLDER));
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/AbstractResourceFilteringConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/AbstractResourceFilteringConfiguration.java
new file mode 100644
index 0000000..d0d060c
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/AbstractResourceFilteringConfiguration.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.filtering;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.AbstractFilteringSupportMavenPlugin;
+
+/**
+ * Base class for resource filtering configuration
+ *
+ * @author Fred Bricon
+ */
+public abstract class AbstractResourceFilteringConfiguration implements ResourceFilteringConfiguration {
+
+  protected IMavenProjectFacade mavenProjectFacade;
+  protected AbstractFilteringSupportMavenPlugin pluginConfiguration;
+  
+  public AbstractResourceFilteringConfiguration(IMavenProjectFacade mavenProjectFacade) {
+    this.mavenProjectFacade = mavenProjectFacade;
+  }
+  
+
+  @Override
+public List<String> getFilters() {
+    List<String> filters = new ArrayList<>(mavenProjectFacade.getMavenProject().getFilters());
+    if (pluginConfiguration != null) {
+      filters.addAll(pluginConfiguration.getFilters());
+    }
+    return filters;
+  }
+
+  @Override
+public String getEscapeString() {
+    if (pluginConfiguration == null) {
+      return null;
+    }
+    return pluginConfiguration.getEscapeString();
+  }
+
+  @Override
+public List<Xpp3Dom> getNonfilteredExtensions() {
+    if (pluginConfiguration == null) {
+      return Collections.emptyList();
+    }
+    Xpp3Dom[] domext = pluginConfiguration.getNonfilteredExtensions();
+    if(domext == null || domext.length == 0){
+      return Collections.emptyList();
+    }
+    return Arrays.asList(domext);
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/AppClientResourceFilteringConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/AppClientResourceFilteringConfiguration.java
new file mode 100644
index 0000000..f3a8f2f
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/AppClientResourceFilteringConfiguration.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.filtering;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.AcrPluginConfiguration;
+import org.eclipse.m2e.wtp.ProjectUtils;
+
+/**
+ * EarResourceFilteringConfiguration
+ *
+ * @author Fred Bricon
+ */
+public class AppClientResourceFilteringConfiguration extends AbstractResourceFilteringConfiguration {
+
+  private AcrPluginConfiguration acrPluginConfiguration;
+  
+  public AppClientResourceFilteringConfiguration(IMavenProjectFacade mavenProjectFacade) throws CoreException {
+    super(mavenProjectFacade);
+    acrPluginConfiguration = new AcrPluginConfiguration(mavenProjectFacade);
+  }
+
+  @Override
+public IPath getTargetFolder() {
+    String buildOutputDir = mavenProjectFacade.getMavenProject().getBuild().getOutputDirectory();
+    String relativeBuildOutputDir = ProjectUtils.getRelativePath(mavenProjectFacade.getProject(), buildOutputDir);
+    return new Path(relativeBuildOutputDir);
+  }
+
+  @Override
+public List<Xpp3Dom> getResources() {
+    if (!acrPluginConfiguration.isFilteringDeploymentDescriptorsEnabled()) {
+      return null;
+    }
+    IFile applicationClientXml = acrPluginConfiguration.getApplicationClientXml();
+    if (applicationClientXml == null) {
+      return null;
+    }
+    Xpp3Dom resource = new Xpp3Dom("resource"); //$NON-NLS-1$
+    Xpp3Dom directory = new Xpp3Dom("directory"); //$NON-NLS-1$
+    directory.setValue(applicationClientXml.getParent().getProjectRelativePath().toPortableString());
+    resource.addChild(directory);
+    Xpp3Dom filter = new Xpp3Dom("filtering"); //$NON-NLS-1$
+    filter.setValue(Boolean.TRUE.toString());
+    Xpp3Dom includes = new Xpp3Dom("includes"); //$NON-NLS-1$
+    Xpp3Dom include = new Xpp3Dom("include"); //$NON-NLS-1$
+    include.setValue(applicationClientXml.getName());
+    includes.addChild(include);
+    resource.addChild(includes);
+    Xpp3Dom targetPath = new Xpp3Dom("targetPath"); //$NON-NLS-1$
+    targetPath.setValue("META-INF/"); //$NON-NLS-1$
+    resource.addChild(targetPath);
+    resource.addChild(filter);
+    
+    return Arrays.asList(resource);
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/EarResourceBuildParticipant.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/EarResourceBuildParticipant.java
new file mode 100644
index 0000000..bac177d
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/EarResourceBuildParticipant.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.filtering;
+
+
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.DeploymentDescriptorManagement;
+import org.eclipse.m2e.wtp.EarPluginConfiguration;
+import org.eclipse.m2e.wtp.MavenWtpConstants;
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+import org.eclipse.m2e.wtp.ProjectUtils;
+import org.eclipse.m2e.wtp.preferences.IMavenWtpPreferencesManager;
+
+/**
+ * EAR Resource build participant, filters EAR resources and generates application.xml if it's missing.
+ *
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ * 
+ * @since 1.0.1
+ */
+public class EarResourceBuildParticipant extends ResourceFilteringBuildParticipant {
+  
+  @Override
+  public Set<IProject> build(int kind, IProgressMonitor monitor) throws Exception {
+	super.build(kind, monitor);
+	IMavenProjectFacade facade = getMavenProjectFacade();
+    
+    IProject project = facade.getProject();
+    MavenProject mavenProject = facade.getMavenProject(monitor);
+    EarPluginConfiguration config = new EarPluginConfiguration(mavenProject);
+    if (!config.isGenerateApplicationXml()) {
+    	return null;
+    }
+    
+    IMavenWtpPreferencesManager prefMgr = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager(); 
+    boolean useBuildDirectory = prefMgr.getPreferences(project).isApplicationXmGeneratedInBuildDirectory();
+    IFolder earResourcesFolder;
+    if (useBuildDirectory) {
+      String appResourcesDir = ProjectUtils.getM2eclipseWtpFolder(mavenProject, project).toPortableString()+Path.SEPARATOR+MavenWtpConstants.EAR_RESOURCES_FOLDER;
+      earResourcesFolder = project.getFolder(appResourcesDir);
+    } else {
+      earResourcesFolder = project.getFolder(config.getEarContentDirectory(project));
+    }
+
+    if (!earResourcesFolder.getFile("META-INF/application.xml").exists()) { //$NON-NLS-1$
+    	DeploymentDescriptorManagement.INSTANCE.updateConfiguration(project, mavenProject, config , useBuildDirectory, monitor);
+    }
+    return null;
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/EarResourceFilteringConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/EarResourceFilteringConfiguration.java
new file mode 100644
index 0000000..b8a05a5
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/EarResourceFilteringConfiguration.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2015 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.filtering;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.model.Resource;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.MavenProjectUtils;
+import org.eclipse.m2e.wtp.EarPluginConfiguration;
+import org.eclipse.m2e.wtp.MavenWtpConstants;
+import org.eclipse.m2e.wtp.ProjectUtils;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+
+/**
+ * EarResourceFilteringConfiguration
+ *
+ * @author Fred Bricon
+ */
+public class EarResourceFilteringConfiguration extends AbstractResourceFilteringConfiguration {
+
+	private EarPluginConfiguration earPluginConfiguration;
+
+	public EarResourceFilteringConfiguration(IMavenProjectFacade mavenProjectFacade) {
+		super(mavenProjectFacade);
+		earPluginConfiguration = new EarPluginConfiguration(mavenProjectFacade.getMavenProject());
+		pluginConfiguration = earPluginConfiguration;
+	}
+
+	@Override
+	public IPath getTargetFolder() {
+		return getTargetFolder(mavenProjectFacade.getMavenProject(), mavenProjectFacade.getProject());
+	}
+
+	public static IPath getTargetFolder(MavenProject mavenProject, IProject project) {
+		return ProjectUtils.getM2eclipseWtpFolder(mavenProject, project).append(MavenWtpConstants.EAR_RESOURCES_FOLDER);
+	}
+
+	@Override
+	public List<Xpp3Dom> getResources() {
+		MavenProject mavenProject = mavenProjectFacade.getMavenProject();  
+		IProject project = mavenProjectFacade.getProject();
+		
+		IPath cliPackageDir = getCLIPackageDir(project, mavenProject.getBuild().getDirectory());
+		
+		List<Xpp3Dom> resources = new ArrayList<>();
+		
+		IPath targetClasses = WTPProjectsUtil.getClassesFolder(mavenProjectFacade).getLocation();
+		
+		for (Resource r : mavenProject.getResources()) {
+			String targetPath = r.getTargetPath();
+			if (targetPath == null || targetPath.trim().isEmpty()) {
+				continue;
+			}
+			IPath originalTarget = Path.fromOSString(targetPath);
+			if (!originalTarget.isAbsolute()) {
+				originalTarget = targetClasses.append(originalTarget);
+			}
+			if (cliPackageDir.isPrefixOf(originalTarget)) {
+				Xpp3Dom resource = getAsXpp3Dom(r.getDirectory(), 
+						                        r.getFiltering(), 
+						                        originalTarget.makeRelativeTo(cliPackageDir).toPortableString(),
+						                        r.getIncludes(),
+						                        r.getExcludes());
+				resources.add(resource);
+			}
+		}
+
+		if (earPluginConfiguration.isFilteringDeploymentDescriptorsEnabled()) {
+			String earContentDir = earPluginConfiguration.getEarContentDirectory(project);
+			Xpp3Dom resource = getAsXpp3Dom(earContentDir, Boolean.TRUE.toString(), null, null, null);
+			resources.add(resource);
+		}
+		
+		return resources;
+	}
+
+	private IPath getCLIPackageDir(IProject project, String targetDir) {
+	    IPath relativeTargetPath = MavenProjectUtils.getProjectRelativePath(project, targetDir);
+	    if (relativeTargetPath == null) {
+	      // target folder not under the project directory, we bail
+	      return null;
+	    }
+	    IPath fullTargetPath = new Path(targetDir);
+	    return fullTargetPath.append(earPluginConfiguration.getFinalName());
+	}
+
+	private Xpp3Dom getAsXpp3Dom(String folder, String filtering, String targetPath, List<String> inclusions, List<String> exclusions) {
+		Xpp3Dom resource = new Xpp3Dom("resource"); //$NON-NLS-1$
+		Xpp3Dom directory = new Xpp3Dom("directory"); //$NON-NLS-1$
+		directory.setValue(folder);
+		resource.addChild(directory);
+		Xpp3Dom filter = new Xpp3Dom("filtering"); //$NON-NLS-1$
+		filter.setValue(filtering);
+		resource.addChild(filter);
+		if (targetPath != null && !targetPath.isEmpty()) {
+			Xpp3Dom targetPathDom = new Xpp3Dom("targetPath"); //$NON-NLS-1$
+			targetPathDom.setValue(targetPath);
+			resource.addChild(targetPathDom);
+		}
+		if (exclusions != null && !exclusions.isEmpty()) {
+			Xpp3Dom exclusionsDom = new Xpp3Dom("excludes"); //$NON-NLS-1$
+			for (String excl : exclusions) {
+				Xpp3Dom exclusion = new Xpp3Dom("exclude"); //$NON-NLS-1$
+				exclusion.setValue(excl);
+				exclusionsDom.addChild(exclusion);
+			}
+			resource.addChild(exclusionsDom);
+		}
+		if (inclusions != null && !inclusions.isEmpty()) {
+			Xpp3Dom inclusionsDom = new Xpp3Dom("includes"); //$NON-NLS-1$
+			for (String incl : inclusions) {
+				Xpp3Dom inclusion = new Xpp3Dom("include"); //$NON-NLS-1$
+				inclusion.setValue(incl);
+				inclusionsDom.addChild(inclusion);
+			}
+			resource.addChild(inclusionsDom);
+		}
+		return resource;
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/ResourceFilteringBuildParticipant.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/ResourceFilteringBuildParticipant.java
new file mode 100644
index 0000000..a6dce3c
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/ResourceFilteringBuildParticipant.java
@@ -0,0 +1,525 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.filtering;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.Scanner;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomUtils;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.embedder.IMaven;
+import org.eclipse.m2e.core.internal.MavenPluginActivator;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.IMavenProjectRegistry;
+import org.eclipse.m2e.core.project.ResolverConfiguration;
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
+import org.eclipse.m2e.wtp.DomUtils;
+import org.eclipse.m2e.wtp.MavenWtpConstants;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.osgi.util.NLS;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonatype.plexus.build.incremental.BuildContext;
+import org.sonatype.plexus.build.incremental.ThreadBuildContext;
+
+/**
+ * ResourceFilteringBuildParticipant
+ *
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+public class ResourceFilteringBuildParticipant extends AbstractBuildParticipant {
+  
+  private static final Logger LOG = LoggerFactory.getLogger(ResourceFilteringBuildParticipant.class );
+
+  private CleanBuildContext forceCopyBuildContext; 
+  
+  @Override
+  public Set<IProject> build(int kind, IProgressMonitor monitor) throws Exception {
+    IMavenProjectFacade facade = getMavenProjectFacade();
+    ResourceFilteringConfiguration configuration = ResourceFilteringConfigurationFactory.getConfiguration(facade);
+    List<Xpp3Dom> resources = null;
+    if (configuration == null || (resources = configuration.getResources()) == null) {
+      //Nothing to filter
+      return null;
+    }
+
+    IProject project = facade.getProject();
+    //FIXME assuming path relative to current project
+    IPath targetFolder = configuration.getTargetFolder();
+    IResourceDelta delta = getDelta(project);
+
+    BuildContext oldBuildContext = ThreadBuildContext.getContext();
+    
+    try {
+      forceCopyBuildContext = null;
+      List<String> filters = configuration.getFilters();
+      if (!project.getFolder(targetFolder).exists() || changeRequiresForcedCopy(facade, filters, delta)) {
+        LOG.info(NLS.bind(Messages.ResourceFilteringBuildParticipant_Changed_Resources_Require_Clean_Build,project.getName()));
+        //String id = "" + "-" + getClass().getName();
+        forceCopyBuildContext = new CleanBuildContext(oldBuildContext);
+        ThreadBuildContext.setThreadBuildContext(forceCopyBuildContext);
+      }
+      if (forceCopyBuildContext != null || hasResourcesChanged(facade, delta, resources)) {
+        LOG.info(NLS.bind(Messages.ResourceFilteringBuildParticipant_Executing_Resource_Filtering,project.getName()));
+        executeCopyResources(facade, configuration, targetFolder, resources, monitor);
+        //FIXME deal with absolute paths
+        IFolder destFolder = project.getFolder(targetFolder);
+        if (destFolder.exists()){
+          destFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+        }
+      }
+    } finally {
+      ThreadBuildContext.setThreadBuildContext(oldBuildContext);
+    }
+
+    return null;
+  }
+
+  @Override
+  protected BuildContext getBuildContext() {
+     return (forceCopyBuildContext == null)?super.getBuildContext() : forceCopyBuildContext;
+  }
+
+   /**
+  * If the pom.xml or any of the project's filters were changed, a forced copy is required
+  * @param facade
+  * @param delta
+  * @return
+  */
+   private boolean changeRequiresForcedCopy(IMavenProjectFacade facade, List<String> filters, IResourceDelta delta) {
+     if (delta == null) {
+       return false;
+     }
+  
+     if (delta.findMember(facade.getPom().getProjectRelativePath()) != null ) {
+       return true;
+     }
+     
+     for (String filter : filters) {       
+       IPath filterPath = facade.getProjectRelativePath(filter);
+       if (filterPath == null) {
+         filterPath =Path.fromOSString(filter);
+       }
+       if (delta.findMember(filterPath) != null){
+         return true;
+       }
+     }
+     return false;
+     
+   }
+ 
+  @Override
+public void clean(IProgressMonitor monitor) throws CoreException {
+    IMavenProjectFacade facade = getMavenProjectFacade();
+    ResourceFilteringConfiguration configuration = ResourceFilteringConfigurationFactory.getConfiguration(facade);
+    if (configuration == null) {
+      //Nothing to do
+      return;
+    }
+
+    IProject project = facade.getProject();
+    IPath targetFolderPath = configuration.getTargetFolder();
+    deleteFilteredResources(project, targetFolderPath);
+    super.clean(monitor);
+  }
+  
+  private void deleteFilteredResources(IProject project, IPath targetFolderPath) throws CoreException {
+    IFolder targetFolder = project.getFolder(targetFolderPath);
+    if (targetFolder.exists()) {
+      IContainer parent = targetFolder.getParent(); 
+      LOG.info(NLS.bind(Messages.ResourceFilteringBuildParticipant_Cleaning_Filtered_Folder,project.getName()));
+      IProgressMonitor monitor =new NullProgressMonitor();
+      targetFolder.delete(true, monitor);
+      if (parent != null) {
+        parent.refreshLocal(IResource.DEPTH_INFINITE, monitor ); 
+      }
+    }    
+  }
+
+  
+  /**
+   * @param mavenProject
+   * @param iResourceDelta 
+   * @param resources
+   * @return
+   */
+  private boolean hasResourcesChanged(IMavenProjectFacade facade, IResourceDelta delta, List<Xpp3Dom> resources) {
+    if (resources == null || resources.isEmpty()){
+      return false;
+    }
+      
+    Set<IPath> resourcePaths = getResourcePaths(facade, resources);
+  
+    if(delta == null) {
+      return !resourcePaths.isEmpty();
+    }
+  
+    for(IPath resourcePath : resourcePaths) {
+      IResourceDelta member = delta.findMember(resourcePath);
+      //XXX deal with member kind/flags
+      if(member != null) {
+          return true; 
+          //we need to deal with superceded resources on the maven level
+      }
+    }
+  
+    return false;
+  }
+
+  
+  private Set<IPath> getResourcePaths(IMavenProjectFacade facade, List<Xpp3Dom> resources) {
+    Set<IPath> resourcePaths = new LinkedHashSet<>();
+    for(Xpp3Dom resource : resources) {
+      IPath folder= null;
+      Xpp3Dom xpp3Directory = resource.getChild("directory"); //$NON-NLS-1$
+      if (xpp3Directory != null)
+      {
+        String dir = xpp3Directory.getValue();
+        if (StringUtils.isNotEmpty(dir)){
+          folder = WTPProjectsUtil.tryProjectRelativePath(facade.getProject(), dir);          
+        }
+      }
+      if(folder != null && !folder.isEmpty()) {
+        resourcePaths.add(folder);
+      }
+    }
+
+    return resourcePaths;
+  }
+  
+
+  private void executeCopyResources(IMavenProjectFacade facade,  ResourceFilteringConfiguration filteringConfiguration, IPath targetFolder, List<Xpp3Dom> resources, IProgressMonitor monitor) throws CoreException {
+
+    //Create a maven request + session
+    ResolverConfiguration resolverConfig = facade.getResolverConfiguration();
+    
+    List<String> filters = filteringConfiguration.getFilters();
+    IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry();
+    MavenExecutionRequest request = projectManager.createExecutionRequest(facade.getPom(), resolverConfig, monitor);
+    request.setRecursive(false);
+    request.setOffline(true);
+
+    IMaven maven = MavenPlugin.getMaven();
+    MavenProject mavenProject = facade.getMavenProject();
+    
+    MavenSession session = maven.createSession(request, mavenProject);
+    MavenExecutionPlan executionPlan = maven.calculateExecutionPlan(session, mavenProject, Collections.singletonList("resources:copy-resources"), true, monitor); //$NON-NLS-1$
+    
+    MojoExecution copyFilteredResourcesMojo = getExecution(executionPlan, "maven-resources-plugin"); //$NON-NLS-1$
+
+    if (copyFilteredResourcesMojo == null) return;
+
+    Xpp3Dom originalConfig = copyFilteredResourcesMojo.getConfiguration();
+    Xpp3Dom  configuration = Xpp3DomUtils.mergeXpp3Dom(new Xpp3Dom("configuration"), originalConfig); //$NON-NLS-1$
+    boolean parentHierarchyLoaded = false;
+    try {
+      parentHierarchyLoaded = loadParentHierarchy(facade, monitor);
+      
+      //Set resource directories to read
+      setupResources(configuration, resources);
+      
+      //Force overwrite
+      setValue(configuration, "overwrite", Boolean.TRUE); //$NON-NLS-1$
+      
+      //Limit placeholder delimiters, otherwise, pages containing @ wouldn't be filtered correctly
+      setupDelimiters(configuration);
+      
+      //Set output directory to the m2eclipse-wtp webresources directory
+      setValue(configuration, "outputDirectory", targetFolder.toPortableString()); //$NON-NLS-1$
+      
+      setValue(configuration, "escapeString", filteringConfiguration.getEscapeString()); //$NON-NLS-1$
+
+      setNonfilteredExtensions(configuration, filteringConfiguration.getNonfilteredExtensions());
+
+      //Setup filters
+      setupFilters(configuration, filters);
+
+      //Create a maven request + session
+      request.setRecursive(false);
+      request.setOffline(true);
+
+      //Execute our modified mojo 
+      copyFilteredResourcesMojo.setConfiguration(configuration);
+      copyFilteredResourcesMojo.getMojoDescriptor().setGoal("copy-resources"); //$NON-NLS-1$
+
+      maven.execute(session, copyFilteredResourcesMojo, monitor);
+      
+      if (session.getResult().hasExceptions()){
+        
+          MavenPluginActivator.getDefault().getMavenMarkerManager().addMarker(facade.getProject(), MavenWtpConstants.WTP_MARKER_FILTERING_ERROR,Messages.ResourceFilteringBuildParticipant_Error_While_Filtering_Resources, -1,  IMarker.SEVERITY_ERROR);
+          //move exceptions up to the original session, so they can be handled by the maven builder
+          //XXX current exceptions refer to maven-resource-plugin (since that's what we used), we should probably 
+          // throw a new exception instead to indicate the problem(s) come(s) from web resource filtering
+          for(Throwable t : session.getResult().getExceptions())
+          {
+            getSession().getResult().addException(t);    
+          }
+      }
+      
+    } finally {
+      //Restore original configuration
+      copyFilteredResourcesMojo.setConfiguration(originalConfig);
+      if (parentHierarchyLoaded) {
+        mavenProject.setParent(null);
+      }
+    }
+  }
+
+  /**
+   * @param configuration
+   * @param extensions
+   */
+  private void setNonfilteredExtensions(Xpp3Dom configuration, List<Xpp3Dom> extensions) {
+    if (extensions == null || extensions.isEmpty()) {
+      return;
+    }
+    Xpp3Dom nonFilteredFileExtensionsNode = configuration.getChild("nonFilteredFileExtensions"); //$NON-NLS-1$
+    if (nonFilteredFileExtensionsNode == null) {
+      nonFilteredFileExtensionsNode = new Xpp3Dom("nonFilteredFileExtensions"); //$NON-NLS-1$
+      configuration.addChild(nonFilteredFileExtensionsNode);
+    } else {
+      DomUtils.removeChildren(nonFilteredFileExtensionsNode);
+    }
+    
+    for (Xpp3Dom ext : extensions) {
+      nonFilteredFileExtensionsNode.addChild(ext);
+    }
+  }
+
+  private void setValue(Xpp3Dom configuration, String childName, Object value) {
+    Xpp3Dom  childNode = configuration.getChild(childName);
+    if (childNode==null){
+      childNode = new Xpp3Dom(childName);
+      configuration.addChild(childNode);
+    }
+    childNode.setValue((value == null)?null:value.toString());
+  }
+
+  private void setupFilters(Xpp3Dom configuration, List<String> filters) {
+    if (!filters.isEmpty()) {
+      Xpp3Dom  filtersNode = configuration.getChild("filters"); //$NON-NLS-1$
+      
+      if (filtersNode==null){
+        filtersNode = new Xpp3Dom("filters"); //$NON-NLS-1$
+        configuration.addChild(filtersNode);
+      } else {
+        DomUtils.removeChildren(filtersNode);
+      }
+      
+      for (String filter : filters) {
+        Xpp3Dom filterNode = new Xpp3Dom("filter"); //$NON-NLS-1$
+        //Workaround : when run via the BuildParticipant, the maven-resource-plugin won't 
+        //find a filter defined with a relative path, so we turn it into an absolute one
+        IPath filterPath = new Path(filter);
+        boolean isAbsolute = false;
+        if (filter.startsWith("${basedir}") ||filter.startsWith("/") || filterPath.getDevice() != null) { //$NON-NLS-1$ //$NON-NLS-2$
+          isAbsolute = true;
+        }
+        String filterAbsolutePath;
+        if (isAbsolute) {
+          filterAbsolutePath = filter;
+        } else {
+          filterAbsolutePath = "${basedir}/"+filter; //$NON-NLS-1$
+        }
+
+        filterNode.setValue(filterAbsolutePath);
+        filtersNode.addChild(filterNode );
+      }
+    }
+  }
+  
+  private void setupDelimiters(Xpp3Dom configuration) {
+    Xpp3Dom  useDefaultDelimitersNode = configuration.getChild("useDefaultDelimiters"); //$NON-NLS-1$
+    if (useDefaultDelimitersNode==null){
+      useDefaultDelimitersNode = new Xpp3Dom("useDefaultDelimiters"); //$NON-NLS-1$
+      configuration.addChild(useDefaultDelimitersNode);
+    }
+    useDefaultDelimitersNode.setValue(Boolean.FALSE.toString());
+
+    Xpp3Dom  delimitersNode = configuration.getChild("delimiters"); //$NON-NLS-1$
+    if (delimitersNode==null){
+      delimitersNode = new Xpp3Dom("delimiters"); //$NON-NLS-1$
+      configuration.addChild(delimitersNode);
+    } else {
+      DomUtils.removeChildren(delimitersNode);
+    }
+    Xpp3Dom delimiter = new Xpp3Dom("delimiter"); //$NON-NLS-1$
+    delimiter.setValue("${*}"); //$NON-NLS-1$
+    delimitersNode.addChild(delimiter);
+  }
+  
+
+  private void setupResources(Xpp3Dom configuration, List<Xpp3Dom> resources) {
+    Xpp3Dom  resourcesNode = configuration.getChild("resources"); //$NON-NLS-1$
+    if (resourcesNode==null){
+      resourcesNode = new Xpp3Dom("resources"); //$NON-NLS-1$
+      configuration.addChild(resourcesNode);
+    } else {
+      resourcesNode.setAttribute("default-value", ""); //$NON-NLS-1$ //$NON-NLS-2$
+      DomUtils.removeChildren(resourcesNode);
+    }
+    for (Xpp3Dom resource : resources)
+    {
+      resourcesNode.addChild(resource);
+    }
+  }
+  
+  private MojoExecution getExecution(MavenExecutionPlan executionPlan, String artifactId) {
+    if (executionPlan == null) return null;
+    for(MojoExecution execution : executionPlan.getMojoExecutions()) {
+      if(artifactId.equals(execution.getArtifactId()) ) {
+        return execution;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=356725. 
+   * Loads the parent project hierarchy if needed.
+   * @param facade
+   * @param monitor
+   * @return true if parent projects had to be loaded.
+   * @throws CoreException
+   */
+  private boolean loadParentHierarchy(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
+    boolean loadedParent = false; 
+    MavenProject mavenProject = facade.getMavenProject();
+    try {
+      if (mavenProject.getModel().getParent() == null || mavenProject.getParent() != null) {
+        //If the method is called without error, we can assume the project has been fully loaded
+        //No need to continue. 
+        return false;
+      }
+    } catch (IllegalStateException e) {
+    //The parent can not be loaded properly 
+    }
+    MavenExecutionRequest request = null;
+    while(mavenProject !=null && mavenProject.getModel().getParent() != null) {
+        if(monitor.isCanceled()) {
+          break;
+        }
+        if (request == null) {
+          request = MavenPlugin.getMavenProjectRegistry().createExecutionRequest(facade, monitor);
+        }
+        MavenProject parentProject = MavenPlugin.getMaven().resolveParentProject(request, mavenProject, monitor);
+        if (parentProject != null) {
+          mavenProject.setParent(parentProject);
+          loadedParent = true;            
+        }
+        mavenProject = parentProject;
+    }
+    return loadedParent; 
+  }
+  
+
+  private static class CleanBuildContext implements BuildContext {
+
+	private BuildContext originalContext;
+
+	CleanBuildContext(BuildContext originalContext) {
+		this.originalContext = originalContext;
+	}
+	  
+	public boolean hasDelta(String relpath) {
+		return true;
+	}
+
+	public boolean hasDelta(File file) {
+		return true;
+	}
+
+	public boolean hasDelta(List relpaths) {
+		return true;
+	}
+
+	public void refresh(File file) {
+		originalContext.refresh(file);
+	}
+
+	public OutputStream newFileOutputStream(File file) throws IOException {
+		return originalContext.newFileOutputStream(file);
+	}
+
+	public Scanner newScanner(File basedir) {
+		return originalContext.newScanner(basedir);
+	}
+
+	public Scanner newDeleteScanner(File basedir) {
+		return originalContext.newDeleteScanner(basedir);
+	}
+
+	public Scanner newScanner(File basedir, boolean ignoreDelta) {
+		return originalContext.newScanner(basedir, ignoreDelta);
+	}
+
+	public boolean isIncremental() {
+		return false;
+	}
+
+	public void setValue(String key, Object value) {
+		originalContext.setValue(key, value);
+	}
+
+	public Object getValue(String key) {
+		return originalContext.getValue(key);
+	}
+
+	public void addWarning(File file, int line, int column, String message,
+			Throwable cause) {
+		originalContext.addWarning(file, line, column, message, cause);
+	}
+
+	public void addError(File file, int line, int column, String message,
+			Throwable cause) {
+		originalContext.addError(file, line, column, message, cause);
+	}
+
+	public void addMessage(File file, int line, int column, String message,
+			int severity, Throwable cause) {
+		originalContext.addMessage(file, line, column, message, severity, cause);
+	}
+
+	public void removeMessages(File file) {
+		originalContext.removeMessages(file);
+	}
+
+	public boolean isUptodate(File target, File source) {
+		return false;
+	}
+
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/ResourceFilteringConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/ResourceFilteringConfiguration.java
new file mode 100644
index 0000000..4d8c622
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/ResourceFilteringConfiguration.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.filtering;
+
+import java.util.List;
+
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * ResourceFilteringConfiguration
+ *
+ * @author Fred Bricon
+ */
+public interface ResourceFilteringConfiguration {
+
+  /**
+   * @return the target folder in which filtered resources should be generated
+   */
+  IPath getTargetFolder();
+  
+  /**
+   * @return the list of resources to filter / copy
+   */
+  List<Xpp3Dom> getResources();
+  
+  /**
+   * Filters (property files) to include during the interpolation of the pom.xml.
+   * @return the list of Filters  
+   */
+  List<String> getFilters();
+
+  /**
+   * Expression preceded with this String won't be interpolated \${foo} will be replaced with ${foo}
+   * @return the escape String
+   */
+  String getEscapeString();
+
+  /**
+   * @return A list of file extensions that should not be filtered if filtering is enabled.
+   */
+  List<Xpp3Dom> getNonfilteredExtensions();
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/ResourceFilteringConfigurationFactory.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/ResourceFilteringConfigurationFactory.java
new file mode 100644
index 0000000..827061b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/ResourceFilteringConfigurationFactory.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.filtering;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.JEEPackaging;
+
+/**
+ * ResourceFilteringConfigurationFactory
+ *
+ * @author Fred Bricon
+ */
+public class ResourceFilteringConfigurationFactory {
+
+  //TODO Use an extension point to let 3rd party plugin register their own ResourceFilteringConfiguration 
+  public static ResourceFilteringConfiguration getConfiguration(IMavenProjectFacade mavenProjectFacade) throws CoreException {
+
+    JEEPackaging packaging = JEEPackaging.getValue(mavenProjectFacade.getPackaging());
+    if (packaging == null) {
+      return null;
+    }
+    switch(packaging) {
+      case WAR:
+        return new WebResourceFilteringConfiguration(mavenProjectFacade);
+      case EAR:
+        return new EarResourceFilteringConfiguration(mavenProjectFacade);
+      case APP_CLIENT:
+        return new AppClientResourceFilteringConfiguration(mavenProjectFacade);
+      case EJB:
+      default:
+          return null;
+    }
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/WebResourceFilteringConfiguration.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/WebResourceFilteringConfiguration.java
new file mode 100644
index 0000000..2ada9e3
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/filtering/WebResourceFilteringConfiguration.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.filtering;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.MavenWtpConstants;
+import org.eclipse.m2e.wtp.ProjectUtils;
+import org.eclipse.m2e.wtp.WarPluginConfiguration;
+
+/**
+ * WebResourceFilteringConfiguration
+ *
+ * @author Fred Bricon
+ */
+public class WebResourceFilteringConfiguration extends AbstractResourceFilteringConfiguration {
+
+  private static final String WEB_INF = "WEB-INF/"; //$NON-NLS-1$
+
+  private WarPluginConfiguration warPluginConfiguration;
+  
+  public WebResourceFilteringConfiguration(IMavenProjectFacade mavenProjectFacade) {
+    super(mavenProjectFacade);
+    warPluginConfiguration = new WarPluginConfiguration(mavenProjectFacade.getMavenProject(), mavenProjectFacade.getProject());
+    pluginConfiguration = warPluginConfiguration;
+  }
+
+  @Override
+public IPath getTargetFolder() {
+    return getTargetFolder(mavenProjectFacade.getMavenProject(), mavenProjectFacade.getProject());
+  }
+
+  public static IPath getTargetFolder(MavenProject mavenProject, IProject project) {
+    return ProjectUtils.getM2eclipseWtpFolder(mavenProject, project).append(MavenWtpConstants.WEB_RESOURCES_FOLDER);
+  }
+
+  @Override
+public List<Xpp3Dom> getResources() {
+    Xpp3Dom[] domResources = warPluginConfiguration.getWebResources();
+    List<Xpp3Dom> resources = new ArrayList<>();
+    
+    if(domResources != null && domResources.length > 0){
+      resources.addAll(Arrays.asList(domResources));
+    }    
+
+    Xpp3Dom webXmlResource = getWebXmlResource();
+    if (webXmlResource != null) {
+      resources.add(webXmlResource);
+    }
+
+    return resources;
+  }
+
+  //MECLIPSEWTP-159 : Handle web.xml filtering with <filteringDeploymentDescriptors> 
+  private Xpp3Dom getWebXmlResource() {
+    if (!pluginConfiguration.isFilteringDeploymentDescriptorsEnabled()) {
+      return null;
+    }
+    String warSourceDirectory = warPluginConfiguration.getWarSourceDirectory();
+    if (warSourceDirectory.startsWith("/")) { //$NON-NLS-1$
+      warSourceDirectory = warSourceDirectory.substring(1);
+    }
+    if (!warSourceDirectory.endsWith("/")) { //$NON-NLS-1$
+      warSourceDirectory = warSourceDirectory + "/"; //$NON-NLS-1$
+    }
+    Xpp3Dom resource = new Xpp3Dom("resource"); //$NON-NLS-1$
+    Xpp3Dom directory = new Xpp3Dom("directory"); //$NON-NLS-1$
+    directory.setValue(warSourceDirectory+WEB_INF);
+    resource.addChild(directory);
+    Xpp3Dom includes = new Xpp3Dom("includes"); //$NON-NLS-1$
+    Xpp3Dom include = new Xpp3Dom("include"); //$NON-NLS-1$
+    //TODO handle custom web.xml
+    include.setValue("web.xml"); //$NON-NLS-1$
+    includes.addChild(include);
+    resource.addChild(includes);
+    Xpp3Dom filter = new Xpp3Dom("filtering"); //$NON-NLS-1$
+    filter.setValue(Boolean.TRUE.toString());
+    Xpp3Dom targetPath = new Xpp3Dom("targetPath"); //$NON-NLS-1$
+    targetPath.setValue(WEB_INF);
+    resource.addChild(targetPath);
+    resource.addChild(filter);
+    return resource;
+  }
+
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/jdt/launch/EjbClientClassifierClasspathProvider.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/jdt/launch/EjbClientClassifierClasspathProvider.java
new file mode 100644
index 0000000..f5d398a
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/jdt/launch/EjbClientClassifierClasspathProvider.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *      Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.internal.jdt.launch;
+
+import java.util.Set;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.jdt.AbstractClassifierClasspathProvider;
+import org.eclipse.m2e.wtp.JEEPackaging;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Adds main classes of EJB project referenced using the "client" classifier to the runtime classpath. 
+ *
+ * @author Fred Bricon
+ */
+public class EjbClientClassifierClasspathProvider extends AbstractClassifierClasspathProvider {
+
+  private static final Logger LOG = LoggerFactory.getLogger(EjbClientClassifierClasspathProvider .class);
+  
+  /**
+   * Applies if project of type <code>ejb</code> and having maven-ejb-plugin > configuration > generateClient = true 
+   */
+  @Override
+  public boolean applies(IMavenProjectFacade mavenProjectFacade, String classifier) {
+    return getClassifier().equals(classifier) 
+        && JEEPackaging.EJB.getName().equals(mavenProjectFacade.getPackaging())
+        && generatesClient(mavenProjectFacade);
+  }
+
+  private boolean generatesClient(IMavenProjectFacade mavenProjectFacade) {
+    MavenProject mavenProject;
+    try {
+      mavenProject = mavenProjectFacade.getMavenProject(new NullProgressMonitor());
+    } catch(CoreException ex) {
+      LOG.error(Messages.ClassifierClasspathProvider_Error_Loading_Maven_Instance, ex);
+      return false;
+    }
+    Plugin ejbPlugin = mavenProject.getPlugin("org.apache.maven.plugins:maven-ejb-plugin"); //$NON-NLS-1$
+    if (ejbPlugin != null) {
+      Xpp3Dom config = (Xpp3Dom)ejbPlugin.getConfiguration();
+      if (config != null) {
+        Xpp3Dom generateClient = config.getChild("generateClient"); //$NON-NLS-1$
+        if (generateClient != null && Boolean.parseBoolean(generateClient.getValue())) {
+         return true; 
+        }
+      }
+    }
+    return false;
+  }
+
+  
+  @Override
+public String getClassifier() {
+    return "client"; //$NON-NLS-1$
+  }
+  
+  @Override
+public void setRuntimeClasspath(Set<IRuntimeClasspathEntry> runtimeClasspath, IMavenProjectFacade mavenProjectFacade,
+      IProgressMonitor monitor) throws CoreException {
+    addMainFolder(runtimeClasspath, mavenProjectFacade, monitor);
+  }
+
+  @Override
+public void setTestClasspath(Set<IRuntimeClasspathEntry> runtimeClasspath, IMavenProjectFacade mavenProjectFacade,
+      IProgressMonitor monitor) throws CoreException {
+    setRuntimeClasspath(runtimeClasspath, mavenProjectFacade, monitor);
+  }
+  
+  @Override
+public String getName() {
+    return Messages.EjbClientClassifierClasspathProvider_EJB_Client_Classpath_Provider;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/jdt/launch/WarClassesClassifierClasspathProvider.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/jdt/launch/WarClassesClassifierClasspathProvider.java
new file mode 100644
index 0000000..3d9f97c
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/jdt/launch/WarClassesClassifierClasspathProvider.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *      Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.internal.jdt.launch;
+
+import java.util.Set;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.jdt.AbstractClassifierClasspathProvider;
+import org.eclipse.m2e.wtp.JEEPackaging;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Adds main classes of war project referenced using the "classes" classifier to the runtime classpath. 
+ *
+ * @author Fred Bricon
+ */
+public class WarClassesClassifierClasspathProvider extends AbstractClassifierClasspathProvider {
+  
+  private static final Logger LOG = LoggerFactory.getLogger(WarClassesClassifierClasspathProvider.class);
+
+  /**
+   * Applies if project of type <code>war</code> and having maven-war-plugin > configuration > attachClasses = true 
+   */
+  @Override
+  public boolean applies(IMavenProjectFacade mavenProjectFacade, String classifier) {
+    return getClassifier().equals(classifier) 
+           && JEEPackaging.WAR.getName().equals(mavenProjectFacade.getPackaging()) 
+           && hasAttachedClasses(mavenProjectFacade);
+  }
+
+  private boolean hasAttachedClasses(IMavenProjectFacade mavenProjectFacade) {
+    MavenProject mavenProject;
+    try {
+      mavenProject = mavenProjectFacade.getMavenProject(new NullProgressMonitor());
+    } catch(CoreException ex) {
+      LOG.error(Messages.ClassifierClasspathProvider_Error_Loading_Maven_Instance, ex); 
+      return false;
+    }
+    Plugin warPlugin = mavenProject.getPlugin("org.apache.maven.plugins:maven-war-plugin"); //$NON-NLS-1$
+    if (warPlugin != null) {
+      Xpp3Dom config = (Xpp3Dom)warPlugin.getConfiguration();
+      if (config != null) {
+        Xpp3Dom attachClasses = config.getChild("attachClasses"); //$NON-NLS-1$
+        if (attachClasses != null && Boolean.parseBoolean(attachClasses.getValue())) {
+         return true; 
+        }
+      }
+    }
+    return false;
+  }
+
+  @Override
+public String getClassifier() {
+    return "classes"; //$NON-NLS-1$
+  }
+  
+  @Override
+public void setRuntimeClasspath(Set<IRuntimeClasspathEntry> runtimeClasspath, IMavenProjectFacade mavenProjectFacade,
+      IProgressMonitor monitor) throws CoreException {
+    addMainFolder(runtimeClasspath, mavenProjectFacade, monitor);
+  }
+  
+  @Override
+public void setTestClasspath(Set<IRuntimeClasspathEntry> runtimeClasspath, IMavenProjectFacade mavenProjectFacade,
+      IProgressMonitor monitor) throws CoreException {
+    setRuntimeClasspath(runtimeClasspath, mavenProjectFacade, monitor);
+  }
+
+  @Override
+public String getName() {
+    return Messages.WarClassesClassifierClasspathProvider_WAR_Classes_Classifier_Classpath_Provider;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/AcrLifecycleMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/AcrLifecycleMapping.java
new file mode 100644
index 0000000..77c4ca7
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/AcrLifecycleMapping.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.lifecycle;
+
+import org.eclipse.m2e.core.project.configurator.AbstractCustomizableLifecycleMapping;
+
+/**
+ * AcrLifecycleMapping
+ *
+ * @author Fred Bricon
+ */
+public class AcrLifecycleMapping extends AbstractCustomizableLifecycleMapping {
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/EarLifecycleMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/EarLifecycleMapping.java
new file mode 100644
index 0000000..c51135b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/EarLifecycleMapping.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.lifecycle;
+
+import org.eclipse.m2e.core.project.configurator.AbstractCustomizableLifecycleMapping;
+
+/**
+ * EarLifecycleMapping
+ *
+ * @author Fred Bricon
+ */
+public class EarLifecycleMapping extends AbstractCustomizableLifecycleMapping {
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/EjbLifecycleMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/EjbLifecycleMapping.java
new file mode 100644
index 0000000..891b20d
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/EjbLifecycleMapping.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.lifecycle;
+
+import org.eclipse.m2e.core.project.configurator.AbstractCustomizableLifecycleMapping;
+
+/**
+ * EjbLifecycleMapping
+ *
+ * @author Fred Bricon
+ */
+public class EjbLifecycleMapping extends AbstractCustomizableLifecycleMapping {
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/RarLifecycleMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/RarLifecycleMapping.java
new file mode 100644
index 0000000..e17bb2a
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/RarLifecycleMapping.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.lifecycle;
+
+import org.eclipse.m2e.core.project.configurator.AbstractCustomizableLifecycleMapping;
+
+/**
+ * RarLifecycleMapping
+ *
+ * @author Fred Bricon
+ */
+public class RarLifecycleMapping extends AbstractCustomizableLifecycleMapping {
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/WarLifecycleMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/WarLifecycleMapping.java
new file mode 100644
index 0000000..a2b6a0b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/lifecycle/WarLifecycleMapping.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.lifecycle;
+
+import org.eclipse.m2e.core.project.configurator.AbstractCustomizableLifecycleMapping;
+
+
+/**
+ * WarLifecycleMapping
+ * 
+ * @author Fred Bricon
+ */
+public class WarLifecycleMapping extends AbstractCustomizableLifecycleMapping {
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/AcrMavenArchiverConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/AcrMavenArchiverConfigurator.java
new file mode 100644
index 0000000..ce14670
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/AcrMavenArchiverConfigurator.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.mavenarchiver;
+
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.wtp.mavenarchiver.AbstractWTPArchiverConfigurator;
+
+/**
+ * AcrMavenArchiverConfigurator
+ *
+ * @author Fred Bricon
+ */
+public class AcrMavenArchiverConfigurator extends AbstractWTPArchiverConfigurator {
+
+  @Override
+  protected MojoExecutionKey getExecutionKey() {
+    MojoExecutionKey key = new MojoExecutionKey("org.apache.maven.plugins", "maven-acr-plugin", "", "acr", null, null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    return key;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/EarMavenArchiverConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/EarMavenArchiverConfigurator.java
new file mode 100644
index 0000000..19738e9
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/EarMavenArchiverConfigurator.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.mavenarchiver;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.wtp.MavenWtpConstants;
+import org.eclipse.m2e.wtp.ProjectUtils;
+import org.eclipse.m2e.wtp.mavenarchiver.AbstractWTPArchiverConfigurator;
+
+
+/**
+ * EarMavenArchiverConfigurator
+ */
+public class EarMavenArchiverConfigurator extends AbstractWTPArchiverConfigurator {
+
+  @Override
+  protected IPath getOutputDir(IMavenProjectFacade facade) {
+    IProject project = facade.getProject();
+    IPath localEarResourceFolder = ProjectUtils.getM2eclipseWtpFolder(facade.getMavenProject(), project);
+    return project.getFullPath().append(localEarResourceFolder).append(MavenWtpConstants.EAR_RESOURCES_FOLDER);
+  }
+
+  @Override
+  protected MojoExecutionKey getExecutionKey() {
+    MojoExecutionKey key = new MojoExecutionKey("org.apache.maven.plugins", "maven-ear-plugin", "", "ear", null, null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    return key;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/EjbMavenArchiverConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/EjbMavenArchiverConfigurator.java
new file mode 100644
index 0000000..80d5ba5
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/EjbMavenArchiverConfigurator.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.mavenarchiver;
+
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.wtp.mavenarchiver.AbstractWTPArchiverConfigurator;
+
+/**
+ * EjbMavenArchiverConfigurator
+ *
+ * @author Fred Bricon
+ */
+public class EjbMavenArchiverConfigurator extends AbstractWTPArchiverConfigurator {
+
+  @Override
+  protected MojoExecutionKey getExecutionKey() {
+    MojoExecutionKey key = new MojoExecutionKey("org.apache.maven.plugins", "maven-ejb-plugin", "", "ejb", null, null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    return key;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/RarMavenArchiverConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/RarMavenArchiverConfigurator.java
new file mode 100644
index 0000000..546bf73
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/RarMavenArchiverConfigurator.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.mavenarchiver;
+
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.wtp.mavenarchiver.AbstractWTPArchiverConfigurator;
+
+/**
+ * RarMavenArchiverConfigurator
+ *
+ * @author Fred Bricon
+ */
+public class RarMavenArchiverConfigurator extends AbstractWTPArchiverConfigurator {
+
+  @Override
+  protected MojoExecutionKey getExecutionKey() {
+    MojoExecutionKey key = new MojoExecutionKey("org.apache.maven.plugins", "maven-rar-plugin", "", "rar", null, null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    return key;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/WarMavenArchiverConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/WarMavenArchiverConfigurator.java
new file mode 100644
index 0000000..0ecb3c4
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/mavenarchiver/WarMavenArchiverConfigurator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.mavenarchiver;
+
+import org.apache.maven.project.MavenProject;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.wtp.MavenWtpConstants;
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+import org.eclipse.m2e.wtp.ProjectUtils;
+import org.eclipse.m2e.wtp.WarPluginConfiguration;
+import org.eclipse.m2e.wtp.mavenarchiver.AbstractWTPArchiverConfigurator;
+
+/**
+ * WarMavenArchiverConfigurator
+ *
+ * @author Fred Bricon
+ */
+public class WarMavenArchiverConfigurator extends AbstractWTPArchiverConfigurator {
+
+  //private static final Logger log = LoggerFactory.getLogger(WarMavenArchiverConfigurator.class);
+
+  @Override
+  protected IPath getOutputDir(IMavenProjectFacade facade) {
+    IProject project = facade.getProject();
+    MavenProject mavenProject = facade.getMavenProject();
+    
+    WarPluginConfiguration warPluginConfiguration = new WarPluginConfiguration(mavenProject, project);
+    
+    if (MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager().getPreferences(project).isWebMavenArchiverUsesBuildDirectory()
+        || warPluginConfiguration.getWebResources() != null && warPluginConfiguration.getWebResources().length > 0 //Uses filtering
+        || warPluginConfiguration.isFilteringDeploymentDescriptorsEnabled()) {
+
+      IPath localResourceFolder =  ProjectUtils.getM2eclipseWtpFolder(mavenProject, project);
+      return project.getFullPath().append(localResourceFolder)
+                                  .append(MavenWtpConstants.WEB_RESOURCES_FOLDER);
+    }
+    
+    return project.getFolder(warPluginConfiguration.getWarSourceDirectory()).getFullPath();
+  }
+  
+  @Override
+  protected String getArchiverFieldName() {
+    return "warArchiver"; //$NON-NLS-1$
+  }
+  
+  @Override
+  protected MojoExecutionKey getExecutionKey() {
+    MojoExecutionKey key = new MojoExecutionKey("org.apache.maven.plugins", "maven-war-plugin", "", "war", null, null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    return key;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/messages.properties b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/messages.properties
new file mode 100644
index 0000000..12d4074
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/messages.properties
@@ -0,0 +1,63 @@
+AbstractProjectFacetConversionEnabler_Error_Accessing_Project=Error accessing {0}
+AppClientVersionChangeListener_Error_Notifying_Application_Client_Version_Change=Unable to notify Application Client version change
+VersionChangeListener_Unreadeable_Project_Nature=Unable to read project nature
+EarProjectConverter_Error_EAR_Root_Content_Folder=The EAR project {0} does not have a content folder or uses root as content folder
+EarVersionChangeListener_Error_Notifying_EAR_Version_Change=Unable to notify EAR version change
+EjbClientClassifierClasspathProvider_EJB_Client_Classpath_Provider=EJB Client Classifier Classpath Provider
+ClassifierClasspathProvider_Error_Loading_Maven_Instance=Could not load mavenProject instance 
+MavenPluginUtils_ArtifactId_Cant_Be_Null=artifactId can not be null
+MavenPluginUtils_Error_Cant_Retrieve_Latest_Plugin_Version=Can not retrieve latest version of {0}
+MavenPluginUtils_GroupId_Cant_Be_Null=groupId can not be null
+MavenWtpPreferencePage_Configure_Workspace_Settings=Configure Workspace Settings...
+MavenWtpPreferencePage_EAR_Project_Preferences=EAR Project preferences
+MavenWtpPreferencePage_Enable_Project_Specific_Settings=Enable Project Specific Settings
+MavenWtpPreferencePage_Generate_ApplicationXml_Under_Build_Dir=Generate application.xml under the build directory
+MavenWtpPreferencePage_Generate_MavenArchiver_Files_Under_Build_Dir=Maven Archiver generates files under the build directory
+MavenWtpPreferencePage_JavaEE_Integration_Settings=Java EE Integration Settings
+MavenWtpPreferencePage_Maven_JavaEE_Integration_Settings=Maven Java EE Integration Settings
+MavenWtpPreferencePage_Select_Active_JavaEE_Configurators=Select active Java EE configurators
+MavenWtpPreferencePage_Update_Projects_After_Preference_Changes=Maven Java EE Integration settings have changed. Do you want to update project configuration?
+MavenWtpPreferencePage_Updating_Configuration_For_Project=Updating configuration for {0}
+MavenWtpPreferencePage_Updating_Maven_Projects_Job=Updating maven projects 
+MavenWtpPreferencePage_Updating_Maven_Projects_Monitor=Updating Maven projects
+MavenWtpPreferencePage_Using_Build_Directory=The build directory will always be used if Web resource filtering is enabled
+MavenWtpPreferencePage_Using_EAR_Build_Directory=The build directory will always be used if EAR resource filtering is enabled
+MavenWtpPreferencePage_WAR_Project_Preferences=WAR Project preferences
+MavenWtpPreferencesManagerImpl_0=Error_Saving_Preferences
+ResourceFilteringBuildParticipant_Changed_Resources_Require_Clean_Build=Changed resources require a complete clean of filtered resources of {0}
+ResourceFilteringBuildParticipant_Cleaning_Filtered_Folder=Cleaning filtered folder for {0}
+ResourceFilteringBuildParticipant_Error_While_Filtering_Resources=An error occurred while filtering resources
+ResourceFilteringBuildParticipant_Executing_Resource_Filtering=Executing resource filtering for {0}
+WarClassesClassifierClasspathProvider_WAR_Classes_Classifier_Classpath_Provider=War classes Classifier Classpath Provider
+WarProjectBuildParticipant_Error_FailOnMissingWebXml=web.xml is missing and <failOnMissingWebXml> is set to true
+WarVersionChangeListener_Error_Notifying_WebApp_Version_Change=Unable to notify Dynamic Web version change
+WTPResourcesContentProvider_Error_Getting_Pipelined_Children=Error getting pipelined children
+WTPResourcesImages_Error_Creating_ImageDescriptor=Error creating ImageDescriptor {0}
+WTPResourcesNode_Cant_Retrieve_Project_Facet=Cannot retrieve the project facet
+WTPResourcesNode_Deployed_Resources_Label=Deployed Resources
+WTPResourcesNode_Error_Getting_WTP_Resources=Error getting WTP resources
+FacetDetectorExtensionReader_Error_Configuring_Facet_Detector=Error configuring facet detector
+AbstractProjectConfiguratorDelegate_Error_Inconsistent_Java_Configuration={0} Utility Facet configuration is aborted as the Java Configuration is inconsistent
+AbstractProjectConfiguratorDelegate_Unable_To_Configure_Project=Unable to configure {0}
+AcrPluginConfiguration_Error_Project_Not_appclient=Maven project must have app-client packaging
+ArtifactHelper_Error_Artifact_Must_Not_Be_Null=artifact must not be null
+EarPluginConfiguration_Error_Reading_EAR_Version=unable to read ear version : {0}
+EarPluginConfiguration_Project_Must_Have_ear_Packaging=Maven project must have ear packaging
+EarProjectConfiguratorDelegate_Configuring_EAR_Project=Configuring EAR project {0}
+EjbPluginConfiguration_Project_Must_Have_ejb_Packaging=Maven project must have ejb packaging
+Error_Cleaning_WTP_Files=Error while cleaning up WTP's created files
+Error_Maven_Project_Cant_Be_Null=MavenProject can not be null
+Error_Reading_Project_Facet=Can not read project '{0}' facets
+markers_unsupported_dependencies_warning=Dependency to project {0} with type {1} is not fully supported. Classpath and/or deployment issues might arise. Try Maven->Disable Workspace Resolution
+markers_inclusion_patterns_problem=Using both <{0}> and <packagingIncludes> can not be translated reliably to the equivalent WTP inclusion patterns. Prefer using <packagingIncludes>.
+markers_mavenarchiver_output_settings_ignored_warning=Current Maven Archiver output settings are ignored as resource filtering is currently used
+MavenDeploymentDescriptorManagement_Error_Deleting_Temp_Folder=Could not delete temp file: {0}
+MavenSessionHelper_Error_Component_Lookup=Could not lookup required component
+RarPluginConfiguration_Project_Must_Have_rar_Packaging=Maven project must have rar packaging
+WebProjectConfiguratorDelegate_File_Copy_Failed=File copy failed
+WebProjectConfiguratorDelegate_Renamed_Dependencies_Will_Be_Copied=Renamed dependencies will be copied under target
+WTPProjectsUtil_Actions_Cant_Be_Null=actions can not be null
+WTPProjectsUtil_Facet_Version_Cant_Be_Null=Facet version can not be null
+WTPProjectsUtil_Project_Cant_Be_Null=project can not be null
+WTPProjectsUtil_Unable_To_Add_ModuleCoreNature=Unable to add the ModuleCoreNature to {0}
+EarPluginException_Default_Message=Error in ear plugin configuration
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/ConfiguratorEnablerComposite.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/ConfiguratorEnablerComposite.java
new file mode 100644
index 0000000..ad60bac
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/ConfiguratorEnablerComposite.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2013-2014 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *      Red Hat, Inc - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.preferences;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.m2e.wtp.preferences.ConfiguratorEnabler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * Composite displaying a checkbox {@link Control} based on a {@link ConfiguratorEnabler}
+ * 
+ * @author Fred Bricon
+ * @since 0.17.0
+ */
+public class ConfiguratorEnablerComposite extends Composite {
+  
+  private Button enableConfigurator;
+  
+  private ConfiguratorEnabler enabler;
+
+  public ConfiguratorEnablerComposite(Composite parent, ConfiguratorEnabler enabler, int style) {
+    super(parent, style);
+    Assert.isNotNull(enabler);
+    this.enabler = enabler;
+    enableConfigurator = new Button(parent, SWT.CHECK);
+    enableConfigurator.setSelection(enabler.isEnabled());
+    enableConfigurator.setText(enabler.getConfiguratorLabel());
+    enableConfigurator.setToolTipText(enabler.getDescription());
+  }
+
+  public void setDefaultValue() {
+    enableConfigurator.setSelection(true);
+  }
+  
+  public void savePreferences() {
+    if (enabler != null) {
+      enabler.setEnabled(enableConfigurator.getSelection());
+    }
+  }
+  
+  @Override
+  public void dispose() {
+    enabler = null;
+    enableConfigurator.dispose();
+    super.dispose();
+  }
+  
+  /**
+   * Enable configurator 
+   * 
+   * @since 1.1.0
+   */
+  public void enableConfigurator(boolean enable) {
+     if (enableConfigurator != null) {
+    	 enableConfigurator.setSelection(enable);
+      }
+  }
+  
+  @Override
+  public void setEnabled(boolean enabled) {
+	super.setEnabled(enabled);
+	if (enableConfigurator != null) {
+	  enableConfigurator.setEnabled(enabled);
+	}		
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferenceInitializer.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferenceInitializer.java
new file mode 100644
index 0000000..831662a
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferenceInitializer.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+import org.eclipse.m2e.wtp.preferences.MavenWtpPreferencesConstants;
+
+
+/**
+ * Maven WTP preferences initializer.
+ * 
+ * @author Fred Bricon
+ */
+public class MavenWtpPreferenceInitializer extends AbstractPreferenceInitializer {
+
+  /**
+   * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+   */
+  @Override
+  public void initializeDefaultPreferences() {
+    IPreferenceStore store = MavenWtpPlugin.getDefault().getPreferenceStore();
+    store.setDefault(MavenWtpPreferencesConstants.P_APPLICATION_XML_IN_BUILD_DIR, true);
+    store.setDefault(MavenWtpPreferencesConstants.P_WEB_MAVENARCHIVER_IN_BUILD_DIR, true);
+    store.setDefault(MavenWtpPreferencesConstants.P_ENABLE_M2EWTP, true);
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferencePage.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferencePage.java
new file mode 100644
index 0000000..1311482
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferencePage.java
@@ -0,0 +1,438 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.preferences;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.IMavenProjectRegistry;
+import org.eclipse.m2e.core.project.IProjectConfigurationManager;
+import org.eclipse.m2e.wtp.JEEPackaging;
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.preferences.ConfiguratorEnabler;
+import org.eclipse.m2e.wtp.preferences.IMavenWtpPreferences;
+import org.eclipse.m2e.wtp.preferences.IMavenWtpPreferencesManager;
+import org.eclipse.m2e.wtp.preferences.MavenWtpPreferencesConstants;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+
+public class MavenWtpPreferencePage extends PropertyPage implements IWorkbenchPreferencePage {
+
+  //Override elements
+  private Composite overrideComp;
+
+  private Button overrideButton;
+
+  private Link fChangeWorkspaceSettings;
+
+  //EAR elements
+  private Group earPrefGroup;
+
+  private Button genApplicationXmlButton;
+
+  //WAR elements
+  private Group warPrefGroup;
+
+  private Button warMavenArchiverButton;
+
+
+  private Group configuratorEnablerGroup;
+
+  private List<ConfiguratorEnablerComposite> enablersComposites;
+
+  private Button enableM2eWtpButton;
+
+  public MavenWtpPreferencePage() {
+    setTitle(Messages.MavenWtpPreferencePage_JavaEE_Integration_Settings);
+  }
+
+  @Override
+protected Control createContents(Composite parent) {
+    Composite main = new Composite(parent, SWT.NONE);
+    GridLayout mainGroupLayout = new GridLayout();
+    mainGroupLayout.numColumns = 1;
+    main.setLayout(mainGroupLayout);
+    GridDataFactory.fillDefaults().grab(true, true).applyTo(main);
+
+    IProject project = getProject();
+    createOverridePrefs(main, project);
+
+    createGlobalPrefs(main);
+
+    if (project == null || JavaEEProjectUtilities.isEARProject(project)) {
+      createEarPrefs(main);
+    }
+    if (project == null || JavaEEProjectUtilities.isDynamicWebProject(project)) {
+      createWarPrefs(main);
+    }
+    IMavenWtpPreferencesManager prefManager = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager();
+    fillValues(prefManager.getPreferences(project));
+
+    if (project == null) {
+      createJavaeeConfiguratorActivation(main, prefManager.getConfiguratorEnablers());
+    }
+
+    return main;
+  }
+
+  private void createJavaeeConfiguratorActivation(Composite main, ConfiguratorEnabler[] configuratorEnablers) {
+    if (configuratorEnablers == null || configuratorEnablers.length == 0) {
+      return;
+    }
+    configuratorEnablerGroup = new Group(main, SWT.NONE);
+    configuratorEnablerGroup.setText(Messages.MavenWtpPreferencePage_Select_Active_JavaEE_Configurators);
+    GridDataFactory.fillDefaults().applyTo(configuratorEnablerGroup);
+    GridLayoutFactory.fillDefaults().margins(5, 0).applyTo(configuratorEnablerGroup);
+    enablersComposites = new ArrayList<>(configuratorEnablers.length);
+
+    for (ConfiguratorEnabler configuratorEnabler : configuratorEnablers) {
+      ConfiguratorEnablerComposite enablerComposite = new ConfiguratorEnablerComposite(configuratorEnablerGroup, 
+          configuratorEnabler, SWT.NONE);
+      GridLayoutFactory.fillDefaults().margins(20, 0).applyTo(enablerComposite);
+      enablersComposites.add(enablerComposite);
+    }
+    
+    toggleWidgets(enableM2eWtpButton.getSelection());
+  }
+
+  private void createGlobalPrefs(Composite main) {
+    enableM2eWtpButton = new Button(main, SWT.CHECK);
+    enableM2eWtpButton.setText("Enable Java EE configuration"); //$NON-NLS-1$
+    enableM2eWtpButton.addSelectionListener(new SelectionListener() {
+        @Override
+		public void widgetDefaultSelected(SelectionEvent e) {
+          widgetSelected(e);
+        }
+
+        @Override
+		public void widgetSelected(SelectionEvent e) {
+          toggleWidgets(enableM2eWtpButton.getSelection());
+        }
+      });
+    
+  }
+  
+  private void createEarPrefs(Composite main) {
+    earPrefGroup = new Group(main, SWT.NONE);
+    earPrefGroup.setText(Messages.MavenWtpPreferencePage_EAR_Project_Preferences);
+    earPrefGroup.setLayout(new GridLayout(1, false));
+    earPrefGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    genApplicationXmlButton = new Button(earPrefGroup, SWT.CHECK);
+    genApplicationXmlButton.setText(Messages.MavenWtpPreferencePage_Generate_ApplicationXml_Under_Build_Dir);
+    genApplicationXmlButton.setToolTipText(Messages.MavenWtpPreferencePage_Using_EAR_Build_Directory);
+  }
+
+  private void createOverridePrefs(Composite main, IProject project) {
+    if(project != null) {
+      overrideComp = new Composite(main, SWT.NONE);
+	  GridLayout overrideCompLayout = new GridLayout();
+	  overrideCompLayout.numColumns = 2;
+	  overrideCompLayout.marginWidth = 0;
+	  overrideCompLayout.marginHeight = 0;
+	  overrideComp.setLayout(overrideCompLayout);
+	  GridDataFactory.fillDefaults().grab(true, false).applyTo(overrideComp);
+      
+      overrideButton = new Button(overrideComp, SWT.CHECK);
+      GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+      overrideButton.setLayoutData(gd);      
+      overrideButton.setText(Messages.MavenWtpPreferencePage_Enable_Project_Specific_Settings);
+
+      overrideButton.addSelectionListener(new SelectionListener() {
+        @Override
+		public void widgetDefaultSelected(SelectionEvent e) {
+          widgetSelected(e);
+        }
+
+        @Override
+		public void widgetSelected(SelectionEvent e) {
+          setWidgetsEnabled(overrideButton.getSelection());
+        }
+      });
+
+      fChangeWorkspaceSettings = createLink(overrideComp, Messages.MavenWtpPreferencePage_Configure_Workspace_Settings);
+      fChangeWorkspaceSettings.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false));
+      
+      Label horizontalLine= new Label(main, SWT.SEPARATOR | SWT.HORIZONTAL);
+	  horizontalLine.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1));
+	  horizontalLine.setFont(main.getFont());
+    }
+  }
+
+  private void createWarPrefs(Composite main) {
+    warPrefGroup = new Group(main, SWT.NONE);
+    warPrefGroup.setText(Messages.MavenWtpPreferencePage_WAR_Project_Preferences);
+    warPrefGroup.setLayout(new GridLayout(1, false));
+    warPrefGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    warMavenArchiverButton = new Button(warPrefGroup, SWT.CHECK);
+    warMavenArchiverButton.setText(Messages.MavenWtpPreferencePage_Generate_MavenArchiver_Files_Under_Build_Dir);
+    warMavenArchiverButton.setToolTipText(Messages.MavenWtpPreferencePage_Using_Build_Directory);
+  }
+
+  private Link createLink(Composite composite, String text) {
+    Link link = new Link(composite, SWT.NONE);
+    link.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+    link.setFont(composite.getFont());
+    link.setText("<A>" + text + "</A>"); //$NON-NLS-1$//$NON-NLS-2$
+    link.addSelectionListener(new SelectionListener() {
+      @Override
+	  public void widgetSelected(SelectionEvent e) {
+        openGlobalPrefs();
+      }
+
+      @Override
+	  public void widgetDefaultSelected(SelectionEvent e) {
+        openGlobalPrefs();
+      }
+    });
+    return link;
+  }
+
+  private void openGlobalPrefs() {
+    String id = MavenWtpPreferencesConstants.MAVEN_WTP_PREFERENCE_PAGE;
+    PreferencesUtil.createPreferenceDialogOn(getShell(), id, new String[] {id}, getElement()).open();
+  }
+
+  protected void setWidgetsEnabled(boolean isEnabled) {
+    if (fChangeWorkspaceSettings != null) {
+        fChangeWorkspaceSettings.setEnabled(!isEnabled);
+    }
+	if (enableM2eWtpButton != null) {
+	  enableM2eWtpButton.setEnabled(isEnabled);
+    }
+	toggleWidgets(isEnabled);
+  }
+
+  private void fillValues(IMavenWtpPreferences preferences) {
+    IProject project = getProject();
+
+    if(project != null) {
+      overrideButton.setSelection(preferences.isEnabledProjectSpecificSettings());
+      setWidgetsEnabled(overrideButton.getSelection());
+    }
+    //read from stored preferences
+    if (enableM2eWtpButton != null) {
+    	enableM2eWtpButton.setSelection(preferences.isEnabled());
+    }
+    if (genApplicationXmlButton != null) {
+      genApplicationXmlButton.setSelection(preferences.isApplicationXmGeneratedInBuildDirectory());
+    }
+    if (warMavenArchiverButton != null) {
+      warMavenArchiverButton.setSelection(preferences.isWebMavenArchiverUsesBuildDirectory());
+    }
+  }
+
+  private void toggleWidgets(boolean enabled) {
+    if (genApplicationXmlButton != null) {
+        genApplicationXmlButton.setEnabled(enabled);
+    }
+    if (warMavenArchiverButton != null) {
+        warMavenArchiverButton.setEnabled(enabled);
+    }
+	  
+    if (enablersComposites != null) {
+      for (ConfiguratorEnablerComposite enablerComposite : enablersComposites) {
+        enablerComposite.setEnabled(enabled);
+      }
+    }
+  }
+
+  public IProject getProject() {
+    IAdaptable el = getElement();
+    IProject p = (el == null) ? null : ((IProject) el.getAdapter(IProject.class));
+    return p;
+  }
+
+  /**
+   * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+   */
+  @Override
+  public void init(IWorkbench workbench) {
+  }
+
+  /**
+   * @see org.eclipse.jface.preference.PreferencePage#performOk()
+   */
+  @Override
+  public boolean performOk() {
+
+    IProject project = getProject();
+    IMavenWtpPreferencesManager preferencesManager = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager();
+    IMavenWtpPreferences preferences = preferencesManager.getPreferences(project);
+
+    IMavenWtpPreferences newPreferences = preferencesManager.createNewPreferences();
+
+    if(project != null) {
+      newPreferences.setEnabledProjectSpecificSettings(overrideButton.getSelection());
+    }
+    if (enableM2eWtpButton != null) {
+        newPreferences.setEnabled(enableM2eWtpButton.getSelection());
+    }
+    if (genApplicationXmlButton != null) {
+      newPreferences.setApplicationXmGeneratedInBuildDirectory(genApplicationXmlButton.getSelection());
+    }
+    if (warMavenArchiverButton != null) {
+      newPreferences.setWebMavenArchiverUsesBuildDirectory(warMavenArchiverButton.getSelection());
+    }
+
+    if (enablersComposites != null) {
+      for (ConfiguratorEnablerComposite enablerComposite : enablersComposites) {
+        enablerComposite.savePreferences();
+      }
+    }
+    
+    if(!newPreferences.equals(preferences)) {
+      preferencesManager.savePreferences(newPreferences, getProject());
+
+      boolean res = MessageDialog.openQuestion(getShell(), Messages.MavenWtpPreferencePage_Maven_JavaEE_Integration_Settings, //
+          Messages.MavenWtpPreferencePage_Update_Projects_After_Preference_Changes);
+      if(res) {
+        updateImpactedProjects();
+      }
+    }
+
+    return super.performOk();
+  }
+
+  /**
+   * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+   */
+  @Override
+  protected void performDefaults() {
+
+    IProject project = getProject();
+    IMavenWtpPreferencesManager preferencesManager = MavenWtpPlugin.getDefault().getMavenWtpPreferencesManager();
+    IMavenWtpPreferences workspacePreferences = preferencesManager.getWorkspacePreferences();
+
+    if(project == null) {
+      workspacePreferences.setEnabled(true);
+      workspacePreferences.setApplicationXmGeneratedInBuildDirectory(true);
+      workspacePreferences.setWebMavenArchiverUsesBuildDirectory(true);
+    }
+
+    fillValues(workspacePreferences);
+
+    if (enablersComposites != null) {
+      for (ConfiguratorEnablerComposite enablerComposite : enablersComposites) {
+        enablerComposite.setDefaultValue();
+      }
+    }
+    
+    super.performDefaults();
+  }
+
+  /**
+   * Update the configuration of maven projects impacted by the configuration change.
+   */
+  private void updateImpactedProjects() {
+
+    final IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry();
+
+    final List<IMavenProjectFacade> facades = getImpactedProjects(projectManager);
+
+    if(facades.isEmpty())
+      return;
+    
+    final IProjectConfigurationManager configurationManager = MavenPlugin.getProjectConfigurationManager();
+
+    WorkspaceJob job = new WorkspaceJob(Messages.MavenWtpPreferencePage_Updating_Maven_Projects_Job) {
+  
+      @Override
+	public IStatus runInWorkspace(IProgressMonitor monitor) {
+        try {
+          SubMonitor progress = SubMonitor.convert(monitor, Messages.MavenWtpPreferencePage_Updating_Maven_Projects_Monitor, 100);
+          SubMonitor subProgress = SubMonitor.convert(progress.newChild(5), facades.size() * 100);
+          //projectManager.sortProjects(facades, progress.newChild(5));
+          for(IMavenProjectFacade facade : facades) {
+            if(progress.isCanceled()) {
+              throw new OperationCanceledException();
+            }
+            IProject project = facade.getProject();
+            subProgress.subTask(NLS.bind(Messages.MavenWtpPreferencePage_Updating_Configuration_For_Project, project.getName()));
+
+            configurationManager.updateProjectConfiguration(project, subProgress);
+          }
+
+        } catch(CoreException ex) {
+          return ex.getStatus();
+        }
+        return Status.OK_STATUS;
+      }
+    };
+    job.setRule(configurationManager.getRule());
+    job.schedule();
+  }
+
+  /**
+   * Returns the list of Maven projects impacted by the configuration change.
+   * 
+   * @param projectManager
+   * @return
+   */
+  private List<IMavenProjectFacade> getImpactedProjects(final IMavenProjectRegistry projectManager) {
+    final List<IMavenProjectFacade> facades = new ArrayList<>();
+    IProject project = getProject();
+    if(project == null) {
+      //Get all workspace projects that might be impacted by the configuration change 
+      for(IMavenProjectFacade facade : projectManager.getProjects()) {
+        if(isImpacted(facade)) {
+          facades.add(facade);
+        }
+      }
+    } else {
+      facades.add(projectManager.getProject(project));
+    }
+    return facades;
+  }
+
+  /**
+   * Checks if the project is impacted by the configuration change.
+   * 
+   * @param facade
+   * @return
+   */
+  private boolean isImpacted(IMavenProjectFacade facade) {
+    if (JEEPackaging.getValue(facade.getPackaging()) != null) {
+       return true;
+    }
+    return false;
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferencesImpl.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferencesImpl.java
new file mode 100644
index 0000000..e36bf57
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferencesImpl.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.preferences;
+
+import org.eclipse.m2e.wtp.preferences.IMavenWtpPreferences;
+
+
+/**
+ * MavenWtpProjectPreferences
+ *
+ * @author Fred Bricon
+ */
+public class MavenWtpPreferencesImpl implements IMavenWtpPreferences {
+   
+  private boolean isEnabled;
+
+  private boolean isApplicationXmGeneratedInBuildDirectory;
+  
+  private boolean isEnabledProjectSpecificSettings; 
+  
+  private boolean isWebMavenArchiverUsesBuildDirectory;
+  
+  @Override
+  public boolean isApplicationXmGeneratedInBuildDirectory() {
+    return isApplicationXmGeneratedInBuildDirectory;
+  }
+
+  /**
+   * @see org.eclipse.m2e.wtp.preferences.IMavenWtpPreferences#setApplicationXmGeneratedInBuildDirectory(boolean)
+   */
+  @Override
+  public void setApplicationXmGeneratedInBuildDirectory(boolean isEnabled) {
+    isApplicationXmGeneratedInBuildDirectory = isEnabled;
+  }
+
+  /**
+   * @see org.eclipse.m2e.wtp.preferences.IMavenWtpPreferences#isEnabledProjectSpecificSettings()
+   */
+  @Override
+  public boolean isEnabledProjectSpecificSettings() {
+    return isEnabledProjectSpecificSettings;
+  }
+
+  /**
+   * @see org.eclipse.m2e.wtp.preferences.IMavenWtpPreferences#setEnabledProjectSpecificSettings(boolean)
+   */
+  @Override
+  public void setEnabledProjectSpecificSettings(boolean isEnabled) {
+    isEnabledProjectSpecificSettings = isEnabled;    
+  }
+
+  /**
+   * @return Returns the isWebMavenArchiverUsesBuildDirectory.
+   */
+  @Override
+  public boolean isWebMavenArchiverUsesBuildDirectory() {
+    return isWebMavenArchiverUsesBuildDirectory;
+  }
+
+  /**
+   * @param isWebMavenArchiverUsesBuildDirectory The isWebMavenArchiverUsesBuildDirectory to set.
+   */
+  @Override
+  public void setWebMavenArchiverUsesBuildDirectory(boolean isWebMavenArchiverUsesBuildDirectory) {
+    this.isWebMavenArchiverUsesBuildDirectory = isWebMavenArchiverUsesBuildDirectory;
+  }
+
+  /* (non-Javadoc)
+   * @see java.lang.Object#hashCode()
+   */
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + (isApplicationXmGeneratedInBuildDirectory ? 1231 : 1237);
+    result = prime * result + (isEnabledProjectSpecificSettings ? 1231 : 1237);
+    result = prime * result + (isWebMavenArchiverUsesBuildDirectory ? 1231 : 1237);
+    result = prime * result + (isEnabled ? 1231 : 1237);
+    return result;
+  }
+
+  /* (non-Javadoc)
+   * @see java.lang.Object#equals(java.lang.Object)
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if(this == obj)
+      return true;
+    if(obj == null)
+      return false;
+    if(getClass() != obj.getClass())
+      return false;
+    MavenWtpPreferencesImpl other = (MavenWtpPreferencesImpl) obj;
+    if(isApplicationXmGeneratedInBuildDirectory != other.isApplicationXmGeneratedInBuildDirectory)
+      return false;
+    if(isEnabledProjectSpecificSettings != other.isEnabledProjectSpecificSettings)
+      return false;
+    if(isWebMavenArchiverUsesBuildDirectory != other.isWebMavenArchiverUsesBuildDirectory)
+      return false;
+    if(isEnabled != other.isEnabled)
+        return false;
+    return true;
+  }
+
+  @Override
+  public boolean isEnabled() {
+	return isEnabled;
+  }
+
+  @Override
+  public void setEnabled(boolean isEnabled) {
+	this.isEnabled = isEnabled;
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferencesManagerImpl.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferencesManagerImpl.java
new file mode 100644
index 0000000..d201ee8
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/preferences/MavenWtpPreferencesManagerImpl.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.preferences;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+import org.eclipse.m2e.wtp.internal.Messages;
+import org.eclipse.m2e.wtp.internal.StringUtils;
+import org.eclipse.m2e.wtp.preferences.ConfiguratorEnabler;
+import org.eclipse.m2e.wtp.preferences.IMavenWtpPreferences;
+import org.eclipse.m2e.wtp.preferences.IMavenWtpPreferencesManager;
+import org.eclipse.m2e.wtp.preferences.MavenWtpPreferencesConstants;
+import org.osgi.service.prefs.BackingStoreException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An implementation of IMavenWtpPreferencesManager
+ *
+ * @author Fred Bricon
+ */
+public class MavenWtpPreferencesManagerImpl implements IMavenWtpPreferencesManager {
+
+  private static final String ATTR_ENABLER_ID = "id"; //$NON-NLS-1$
+  private static final String ATTR_CONFIGURATOR_IDS = "configuratorIds"; //$NON-NLS-1$
+  private static final String ATTR_LABEL = "label"; //$NON-NLS-1$
+  private static final String ATTR_DESCRIPTION = "description"; //$NON-NLS-1$
+
+
+  private static final Logger LOG = LoggerFactory.getLogger(MavenWtpPreferencesManagerImpl.class);
+  
+  private static final String CONFIGURATOR_ENABLER_EXTENSION_POINT = MavenWtpPlugin.ID+".javaeeConfiguratorEnabler"; //$NON-NLS-1$
+
+  private List<ConfiguratorEnabler> enablers;
+
+  /**
+   * @see org.eclipse.m2e.wtp.preferences.IMavenWtpPreferencesManager#getPreferences(org.eclipse.core.resources.IProject)
+   */
+  @Override
+  public IMavenWtpPreferences getPreferences(IProject project) {
+    if (project == null) {
+      return loadWorkspacePreferences();
+    }
+    
+    IEclipsePreferences eclipsePrefs = getEclipsePreferences(project);
+    if (eclipsePrefs.getBoolean(MavenWtpPreferencesConstants.P_ENABLED_PROJECT_SPECIFIC__PREFS, false)) {
+      return convertPreferences(eclipsePrefs);
+    }
+    return loadWorkspacePreferences();    
+  }
+
+  /**
+   * @see org.eclipse.m2e.wtp.preferences.IMavenWtpPreferencesManager#createNewPreferences()
+   */
+  @Override
+  public IMavenWtpPreferences createNewPreferences() {
+    return new MavenWtpPreferencesImpl();
+  }
+  
+  /**
+   * @see org.eclipse.m2e.wtp.preferences.IMavenWtpPreferencesManager#getWorkspacePreferences()
+   */
+  @Override
+  public IMavenWtpPreferences getWorkspacePreferences() {
+    return loadWorkspacePreferences();
+  }
+
+  
+  /**
+   * @see org.eclipse.m2e.wtp.preferences.IMavenWtpPreferencesManager#savePreferences(org.eclipse.m2e.wtp.preferences.IMavenWtpPreferences, org.eclipse.core.resources.IProject)
+   */
+  @Override
+  public void savePreferences(IMavenWtpPreferences preferences, IProject project) {
+    if (preferences == null) return;
+    
+    IEclipsePreferences eclipsePrefs;
+    if (project != null) {
+      eclipsePrefs = getEclipsePreferences(project);
+      if (preferences.isEnabledProjectSpecificSettings()) {
+        transformPreferences(preferences, eclipsePrefs);
+      } else {
+        removeSpecificSettings(eclipsePrefs);
+      }
+      eclipsePrefs.putBoolean(MavenWtpPreferencesConstants.P_ENABLED_PROJECT_SPECIFIC__PREFS, preferences.isEnabledProjectSpecificSettings());
+    } else {
+      eclipsePrefs = getEclipsePreferences();
+      transformPreferences(preferences, eclipsePrefs);
+    }
+    try {
+      eclipsePrefs.flush();
+    } catch (BackingStoreException e) { 
+      LOG.error(Messages.MavenWtpPreferencesManagerImpl_0, e);
+    } 
+  }
+  
+  private void removeSpecificSettings(IEclipsePreferences eclipsePrefs) {
+    eclipsePrefs.remove(MavenWtpPreferencesConstants.P_APPLICATION_XML_IN_BUILD_DIR);
+    eclipsePrefs.remove(MavenWtpPreferencesConstants.P_WEB_MAVENARCHIVER_IN_BUILD_DIR);
+    
+  }
+
+  private IMavenWtpPreferences loadWorkspacePreferences() {
+    return convertPreferences(getEclipsePreferences());
+  }
+  
+  private void transformPreferences(IMavenWtpPreferences preferences, IEclipsePreferences eclipsePrefs) {
+    eclipsePrefs.putBoolean(MavenWtpPreferencesConstants.P_APPLICATION_XML_IN_BUILD_DIR, preferences.isApplicationXmGeneratedInBuildDirectory());
+    eclipsePrefs.putBoolean(MavenWtpPreferencesConstants.P_WEB_MAVENARCHIVER_IN_BUILD_DIR, preferences.isWebMavenArchiverUsesBuildDirectory());
+    eclipsePrefs.putBoolean(MavenWtpPreferencesConstants.P_ENABLE_M2EWTP, preferences.isEnabled());
+  }
+
+  private IMavenWtpPreferences convertPreferences(IEclipsePreferences eclipsePrefs) {
+    IMavenWtpPreferences preferences = createNewPreferences();
+    preferences.setEnabledProjectSpecificSettings(eclipsePrefs.getBoolean(MavenWtpPreferencesConstants.P_ENABLED_PROJECT_SPECIFIC__PREFS, false));
+    preferences.setApplicationXmGeneratedInBuildDirectory(eclipsePrefs.getBoolean(MavenWtpPreferencesConstants.P_APPLICATION_XML_IN_BUILD_DIR, true));
+    preferences.setWebMavenArchiverUsesBuildDirectory(eclipsePrefs.getBoolean(MavenWtpPreferencesConstants.P_WEB_MAVENARCHIVER_IN_BUILD_DIR, true));
+    preferences.setEnabled(eclipsePrefs.getBoolean(MavenWtpPreferencesConstants.P_ENABLE_M2EWTP, true));
+    return preferences;
+  }
+
+  private static IEclipsePreferences getEclipsePreferences()
+  {
+    return InstanceScope.INSTANCE.getNode(MavenWtpPreferencesConstants.PREFIX);
+  }
+
+  private static IEclipsePreferences getEclipsePreferences(IProject project)
+  {
+    return new ProjectScope(project).getNode(MavenWtpPreferencesConstants.PREFIX);    
+  }
+
+  @Override
+  public ConfiguratorEnabler[] getConfiguratorEnablers() {
+    if (enablers == null) {
+      enablers = loadConfiguratorEnablers();
+    }
+    ConfiguratorEnabler[] enablersArray = new ConfiguratorEnabler[enablers.size()];
+    enablers.toArray(enablersArray);
+    return enablersArray;
+  }
+
+  private static List<ConfiguratorEnabler> loadConfiguratorEnablers() {
+    IExtensionRegistry registry = Platform.getExtensionRegistry();
+    IConfigurationElement[] enablerConfigs = registry.getConfigurationElementsFor(CONFIGURATOR_ENABLER_EXTENSION_POINT);
+    if (enablerConfigs == null) {
+      return Collections.emptyList();
+    }
+    ArrayList<ConfiguratorEnabler> enablers = new ArrayList<>();
+    for (IConfigurationElement config : enablerConfigs) {
+        String enablerId = config.getAttribute(ATTR_ENABLER_ID);
+        String[] configuratorIds = split(config.getAttribute(ATTR_CONFIGURATOR_IDS));
+        String label = config.getAttribute(ATTR_LABEL);
+        String description = config.getAttribute(ATTR_DESCRIPTION);
+        enablers.add(new ConfiguratorEnabler(enablerId, label, configuratorIds, description));
+    }
+    return enablers;
+  }
+
+  private static String[] split(String str) {
+    return StringUtils.tokenizeToStringArray(str, ","); //$NON-NLS-1$
+  }
+
+  /* (non-Javadoc)
+   * @see org.eclipse.m2e.wtp.preferences.IMavenWtpPreferencesManager#isEnabled(java.lang.String)
+   */
+  @Override
+  public boolean isEnabled(String configuratorId) {
+    for (ConfiguratorEnabler enabler : getConfiguratorEnablers()) {
+      if (enabler.appliesTo(configuratorId)) {
+        return enabler.isEnabled();
+      }
+    }
+    return true;
+  }
+  
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/utilities/ComponentModuleUtil.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/utilities/ComponentModuleUtil.java
new file mode 100644
index 0000000..2ca3b1b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/utilities/ComponentModuleUtil.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.utilities;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.internal.StructureEdit;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+
+/**
+ * ComponentModule Utility class
+ *
+ * @author Fred Bricon
+ */
+@SuppressWarnings("restriction")
+public class ComponentModuleUtil {
+
+	private ComponentModuleUtil() {
+	}
+
+	public static IVirtualComponent getOrCreateComponent(IProject project, IProgressMonitor monitor) {
+		IVirtualComponent component = ComponentCore.createComponent(project, true);
+		if (component != null) {
+			StructureEdit core = null;
+			try {
+					core = StructureEdit.getStructureEditForRead(project);
+					if(core != null) {
+						//For some reason, we're facing a lot of issues with
+						// component.setReferences failing with an NPE because of
+						// the underlying core.getComponent() being null but not being Null-Checked
+
+						if (core.getComponent() == null){
+							//We could try to fix the missing workbench module but we're already
+							//drowning in a sea of hacks to workaround WTP quirks
+
+							//core.createWorkbenchModule(project.getName());
+							//core.saveIfNecessary(monitor);
+							return null;
+						}
+					}
+			} finally {
+				if(core != null) {
+					core.dispose();
+				}
+			}
+		}
+		return component;
+	}
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/utilities/DebugUtilities.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/utilities/DebugUtilities.java
new file mode 100644
index 0000000..7ad5a63
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/utilities/DebugUtilities.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.utilities;
+
+import java.io.InputStream;
+
+import org.codehaus.plexus.util.IOUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.m2e.core.MavenPlugin;
+import org.eclipse.wst.common.componentcore.ComponentCore;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Debug Utilities
+ * 
+ * @author Fred Bricon
+ */
+public class DebugUtilities {
+
+  private static final Logger LOG = LoggerFactory.getLogger(DebugUtilities.class);
+  
+  public static String SEP = System.getProperty("line.separator"); //$NON-NLS-1$
+
+  /**
+   * Dumps the project's following informations :
+   * <ul>
+   * <li>underlying resources, if the project can return a IVirtualComponent</li>
+   * <li>deploy-name</li>
+   * <li>content of .settings/org.eclipse.wst.common.component</li>
+   * <li>if the project is a FelixibleProject and has the ModuleCoreNature nature</li>
+   * <li>list of all the installed project facets</li>
+   * </ul>
+   * 
+   * @param startMessage The message to display before the informations
+   * @param project The project to inspect
+   * @return a dump of the project state
+   */
+  public static String dumpProjectState(String startMessage, IProject project) {
+    StringBuilder dump = new StringBuilder((startMessage == null) ? "" : startMessage); //$NON-NLS-1$
+    dump.append("Current ").append(Thread.currentThread()).append(SEP); //$NON-NLS-1$
+    String projectName = project.getName();
+    IVirtualComponent component = ComponentCore.createComponent(project);
+    if(component == null) {
+      dump.append(projectName).append(" is not a IVirtualComponent").append(SEP); //$NON-NLS-1$
+    } else {
+      dump.append(projectName).append(" is a ").append(component.getClass().getSimpleName()).append(SEP); //$NON-NLS-1$
+      dump.append("Underlying resources for the root folder are :").append(SEP); //$NON-NLS-1$
+      for(IResource resource : component.getRootFolder().getUnderlyingResources()) {
+        dump.append("  -").append(resource.getFullPath().append(SEP)); //$NON-NLS-1$
+      }
+      dump.append("deploy-name = ").append(component.getDeployedName()).append(SEP); //$NON-NLS-1$
+      dumpFile(dump, project.getFile(".settings/org.eclipse.wst.common.component")); //$NON-NLS-1$
+    }
+    boolean hasModulecoreNature = ModuleCoreNature.getModuleCoreNature(project) != null;
+    boolean isFlexible = ModuleCoreNature.isFlexibleProject(project);
+    dump.append(projectName).append(" hasModuleCoreNature:").append(hasModulecoreNature).append(", isFlexible:") //$NON-NLS-1$ //$NON-NLS-2$
+        .append(isFlexible).append(SEP);
+    dumpFacetInformations(project, dump);
+    return dump.toString();
+  }
+
+  /**
+   * Lists all the project facets associated to a project
+   * 
+   * @param project The project to analyze
+   * @param dump The StringBuilder to append project facets informations to
+   */
+  private static void dumpFacetInformations(IProject project, StringBuilder dump) {
+    try {
+      IFacetedProject fProj = ProjectFacetsManager.create(project);
+      if(fProj == null) {
+        dump.append(project.getName()).append(" is not a faceted project").append(SEP); //$NON-NLS-1$
+      } else {
+        for(IProjectFacet facet : ProjectFacetsManager.getProjectFacets()) {
+          if(fProj.hasProjectFacet(facet)) {
+            dump.append("  - has ").append(fProj.getInstalledVersion(facet)).append(" facet").append(SEP); //$NON-NLS-1$ //$NON-NLS-2$
+          }
+        }
+      }
+    } catch(CoreException ex) {
+      dump.append("An exception occured while accessing facet informations ").append(ex.getMessage()).append(SEP); //$NON-NLS-1$
+    }
+  }
+
+  /**
+   * Reads the contents of a file and appends it to a StringBuilder;
+   * 
+   * @param The StringBuilder to append the file content to
+   * @param file The file to read
+   */
+  private static void dumpFile(StringBuilder dump, IFile file) {
+    if(!file.exists()) {
+      dump.append(file.getFullPath()).append(" does not exist").append(SEP); //$NON-NLS-1$
+      return;
+    }
+    InputStream ins = null;
+    try {
+      dump.append("Contents of ").append(file.getFullPath()).append(SEP); //$NON-NLS-1$
+      ins = file.getContents();
+      dump.append(IOUtil.toString(ins));
+    } catch(Exception e) {
+      dump.append("An exception occured while reading ").append(file.getFullPath()).append(" :").append(e.getMessage()) //$NON-NLS-1$ //$NON-NLS-2$
+          .append(SEP);
+    } finally {
+      IOUtil.close(ins);
+    }
+  }
+
+  /**
+   * Writes to the system output if Debug Output is enabled in the Maven Preferences Page
+   * 
+   * @param text The text to display in the standard output
+   */
+  public static void debug(String text) {
+    if(isDebugEnabled()) {
+      LOG.warn(text);
+    }
+  }
+
+  /**
+   * @return true if Debug Output is enabled in the Maven Preferences Page
+   */
+  public static boolean isDebugEnabled() {
+    return MavenPlugin.getDefault().getMavenConfiguration().isDebugOutput();
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/utilities/PathUtil.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/utilities/PathUtil.java
new file mode 100644
index 0000000..75d5852
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/utilities/PathUtil.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.m2e.wtp.internal.utilities;
+
+import java.io.File;
+
+public class PathUtil {
+
+  private static final char BACKSLASH = '\\';
+
+  private static final char SLASH = '/';
+
+  public static String toOsPath(String path) {
+		if (path == null) return null;
+		return path.replace(SLASH, File.separatorChar)
+	            .replace(BACKSLASH, File.separatorChar);
+	}
+	
+	public static String toPortablePath(String path) {
+	  if (path == null) return null;
+	  return path.replace(BACKSLASH, SLASH);
+	}
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/webfragment/WebFragmentQuickPeek.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/webfragment/WebFragmentQuickPeek.java
new file mode 100644
index 0000000..1f052d7
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/webfragment/WebFragmentQuickPeek.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+  *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.m2e.wtp.internal.webfragment;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
+import org.eclipse.jst.jee.util.internal.XMLRootHandler;
+import org.xml.sax.InputSource;
+
+@SuppressWarnings("restriction")
+public class WebFragmentQuickPeek {
+
+	private static final String WEB_FRAGMENT_SCHEMA_ID_3_0 = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"; //$NON-NLS-1$
+	private static final String WEB_FRAGMENT_SCHEMA_ID_3_1 = "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"; //$NON-NLS-1$
+	private static final String WEB_FRAGMENT_3_0 = "3.0"; //$NON-NLS-1$
+	private static final String WEB_FRAGMENT_3_1 = "3.1"; //$NON-NLS-1$
+	
+	private XMLRootHandler handler;
+
+	private String storedVersion = null;
+	
+	private boolean versionSet = false;
+	
+	public WebFragmentQuickPeek(InputStream in) {
+		if (in != null) {
+			try {
+				InputSource inputSource = new InputSource(in);
+				handler = new XMLRootHandler();
+				handler.parseContents(inputSource);
+			} catch (Exception ex) {
+				// ignore
+			} finally {
+				try {
+					in.reset();
+				} catch (IOException ex) {
+					// ignore
+				}
+			}
+		}
+	}
+	
+	public String getVersion() {
+		if (!versionSet) {
+			if (handler != null && "web-fragment".equals(handler.getRootName())) { //$NON-NLS-1$
+				String version = null;
+				if (handler.getRootAttributes() != null) {
+					version = handler.getRootAttributes().getValue("version"); //$NON-NLS-1$
+				}
+				if (version == null || version.trim().length() == 0) {
+					version = getVersionFromDtdSchema();
+				}
+				storedVersion = version;
+				versionSet = true;
+			}
+			
+		}
+		return storedVersion;
+	}
+
+	private String getVersionFromDtdSchema() {
+		//Algorithm copied from org.eclipse.jst.jee.util.internal.JavaEEQuickPeek
+		if (handler == null) {
+			return null;
+		}
+		String schemaName = null;
+		if (handler.getRootAttributes() != null) {
+			schemaName = JavaEEQuickPeek.normalizeSchemaLocation(handler.getRootAttributes().getValue("xsi:schemaLocation")); //$NON-NLS-1$
+		}
+		if (schemaName == null) {
+			return null;
+		}
+		String version = null;
+		if (schemaName.equals(WEB_FRAGMENT_SCHEMA_ID_3_0)) {
+			version = WEB_FRAGMENT_3_0;
+		} else if (schemaName.equals(WEB_FRAGMENT_SCHEMA_ID_3_1)) {
+			version = WEB_FRAGMENT_3_1;
+		} 
+		return version;
+	}
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/webfragment/WebFragmentUtil.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/webfragment/WebFragmentUtil.java
new file mode 100644
index 0000000..3ea8536
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/internal/webfragment/WebFragmentUtil.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+  *     Fred Bricon (Red Hat, Inc.) - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.m2e.wtp.internal.webfragment;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+
+/**
+ * Utility class for WebFragment type projects
+ * 
+ * @author Fred Bricon
+ * @since 1.2.0
+ */
+public class WebFragmentUtil {
+
+	  /**
+	   * Checks if a given {@link IMavenProjectFacade} qualifies as a Web Fragment project, 
+	   * i.e, has a META-INF/web-fragment.xml file
+	   * @param facade an {@link IMavenProjectFacade}
+	   * @return true if a META-INF/web-fragment.xml file can be found in the project build directory or source folder.
+	   */
+	  public static boolean isQualifiedAsWebFragment(IMavenProjectFacade facade) {
+	    return getWebFragment(facade) != null;
+	  }
+	  
+	  /**
+	   * Gets a {@link IMavenProjectFacade}' META-INF/web-fragment.xml, if it exists.
+	   * @param facade an {@link IMavenProjectFacade}
+	   * @return an {@link IFile} pointing to web-fragment.xml if it exists, <code>null</code> otherwise.
+	   */
+	  public static IFile getWebFragment(IMavenProjectFacade facade) {
+	      IFile webFragment = null;
+	      IFolder classes = WTPProjectsUtil.getClassesFolder(facade);
+	      if (classes != null) {
+	    	  webFragment = classes.getFile("META-INF/web-fragment.xml");//$NON-NLS-1$
+	    	  if (webFragment.exists()) { 
+	    		  return webFragment;
+	    	  } 
+	      }
+	      
+	      //No processed/filtered web-fragment.xml found 
+	      //fall back : iterate over the resource folders
+	      IProject project = facade.getProject();
+	      for (IPath resourceFolderPath : facade.getResourceLocations()) {
+	        if (resourceFolderPath != null) {
+	        	webFragment = project.getFile(resourceFolderPath.append("META-INF/web-fragment.xml")); //$NON-NLS-1$
+	        	if (webFragment.exists()) {
+	        		return webFragment;
+	        	}
+	        }
+	      }
+	    return null;
+	  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/mavenarchiver/AbstractWTPArchiverConfigurator.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/mavenarchiver/AbstractWTPArchiverConfigurator.java
new file mode 100644
index 0000000..5c163dd
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/mavenarchiver/AbstractWTPArchiverConfigurator.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.mavenarchiver;
+
+import org.apache.maven.plugin.MojoExecution;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.m2e.core.lifecyclemapping.model.IPluginExecutionMetadata;
+import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.MavenProjectChangedEvent;
+import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
+import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration;
+import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
+import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
+import org.eclipse.m2e.wtp.WTPProjectsUtil;
+import org.eclipse.wst.common.componentcore.ModuleCoreNature;
+import org.sonatype.m2e.mavenarchiver.internal.JarArchiverConfigurator;
+
+/**
+ * Base Maven Archiver configurator for WTP projects
+ * 
+ * @author Fred Bricon
+ */
+public class AbstractWTPArchiverConfigurator extends JarArchiverConfigurator {
+
+	@Override
+	public void configure(ProjectConfigurationRequest request,
+			IProgressMonitor monitor) throws CoreException {
+		if (WTPProjectsUtil.isM2eWtpDisabled(request.getMavenProjectFacade(), monitor)) {
+			return;
+		}
+		super.configure(request, monitor);
+	}
+
+	@Override
+	public void mavenProjectChanged(MavenProjectChangedEvent event,
+			IProgressMonitor monitor) throws CoreException {
+		if (WTPProjectsUtil.isM2eWtpDisabled(event.getMavenProject(), monitor)) {
+			return;
+		}
+	    IMavenProjectFacade oldFacade = event.getOldMavenProject();
+	    IMavenProjectFacade newFacade = event.getMavenProject();
+	    if(oldFacade == null && newFacade == null) {
+	      return;
+	    }
+	    mavenProjectChanged(newFacade, oldFacade, true, monitor);
+	}
+	
+	@Override
+	public AbstractBuildParticipant getBuildParticipant(
+			IMavenProjectFacade projectFacade, MojoExecution execution,
+			IPluginExecutionMetadata executionMetadata) {
+		if (WTPProjectsUtil.isM2eWtpDisabled(projectFacade, new NullProgressMonitor())) {
+			return null;
+		}		
+		return super.getBuildParticipant(projectFacade, execution,
+				executionMetadata);
+	}
+
+	/**
+	 * Ensures the project is WTP enabled before generating the manifest.
+	 */
+	@Override
+	protected boolean needsNewManifest(IFile manifest,
+			IMavenProjectFacade oldFacade, IMavenProjectFacade newFacade,
+			IProgressMonitor monitor) {
+
+		if (!ModuleCoreNature.isFlexibleProject(newFacade.getProject())) {
+			return false;
+		}
+		return super.needsNewManifest(manifest, oldFacade, newFacade, monitor);
+	}
+	
+	@Override
+	public boolean hasConfigurationChanged(IMavenProjectFacade newFacade,
+			ILifecycleMappingConfiguration oldProjectConfiguration,
+			MojoExecutionKey key, IProgressMonitor monitor) {
+		return false;
+	}
+	
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/AbstractFileNameMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/AbstractFileNameMapping.java
new file mode 100644
index 0000000..d277366
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/AbstractFileNameMapping.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.eclipse.m2e.wtp.namemapping;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.eclipse.m2e.wtp.ArtifactHelper;
+
+
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.output.AbstractFileNameMapping 
+ * 
+ * A base class used to generate the standard name of an
+ * artifact instead of relying on the (potentially) wrong
+ * file name provided by {@link org.apache.maven.artifact.Artifact#getFile()}.
+ *
+ * 
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public abstract class AbstractFileNameMapping
+    implements FileNameMapping
+{
+
+
+    private boolean useBaseVersion;
+
+	/**
+     * Generates a standard file name for the specified {@link Artifact}.
+     * <p/>
+     * Returns something like <tt>artifactId-version[-classifier].extension</tt>
+     * if <tt>addVersion</tt> is true. Otherwise it generates something
+     * like <tt>artifactId[-classifier].extension</tt>
+     *
+     * @param a          the artifact to generate a filename from
+     * @param addVersion whether the version should be added
+     * @return the filename, with a standard format
+     */
+    protected String generateFileName( final Artifact a, boolean addVersion )
+    {
+    	ArtifactHandler artifactHandler = a.getArtifactHandler();
+    	ArtifactHelper.fixArtifactHandler(artifactHandler);
+        String extension = artifactHandler.getExtension();
+        final StringBuilder buffer = new StringBuilder( 128 );
+        buffer.append( a.getArtifactId() );
+        if ( addVersion )
+        {
+            buffer.append( '-' );
+            if (useBaseVersion) {
+            	buffer.append( a.getBaseVersion() );
+            } else {
+            	buffer.append( a.getVersion() );
+            }
+            
+        }
+        if ( a.hasClassifier() )
+        {
+            buffer.append( '-' ).append( a.getClassifier() );
+        }
+        if ( extension != null && extension.length() > 0 )
+        {
+            buffer.append( '.' ).append( extension );
+        }
+
+        return buffer.toString();
+    }
+    
+    /**
+     * Introduced in maven-ear-plugin 2.9 : when using a fileNameMapping with versions, either use the 
+     * <code>baseVersion</code> or the <code>version</code>. When the artifact is a SNAPSHOT, version 
+     * will always return a value with a -SNAPSHOT postfix instead of the possible timestamped value.
+     * 
+     * @since 1.1.0
+     */
+    public void setUseBaseVersion(boolean useBaseVersion) {
+		this.useBaseVersion = useBaseVersion;
+    }
+
+    /**
+     * @since 1.1.0
+     */
+    public boolean isUseBaseVersion() {
+    	return useBaseVersion;
+    }
+    
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/EjbNoVersionFileNameMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/EjbNoVersionFileNameMapping.java
new file mode 100644
index 0000000..6f4573b
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/EjbNoVersionFileNameMapping.java
@@ -0,0 +1,41 @@
+/*
+ * 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.eclipse.m2e.wtp.namemapping;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Does not add the version in the generated file name for ejb artifacts.
+ *
+ * @author Fred Bricon
+ * 
+ * @since 0.17.0
+ */
+public class EjbNoVersionFileNameMapping
+    extends AbstractFileNameMapping
+{
+
+    @Override
+	public String mapFileName( Artifact a )
+    {
+        return generateFileName( a, !"ejb".equals(a.getType())); //$NON-NLS-1$
+    }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/FileNameMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/FileNameMapping.java
new file mode 100644
index 0000000..3eda332
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/FileNameMapping.java
@@ -0,0 +1,45 @@
+/*
+ * 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.eclipse.m2e.wtp.namemapping;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.output.FileNameMapping 
+ * 
+ * Maps file name {@link Artifact}.
+ * <p/>
+ * TODO: it might be easier to use a token-based approach instead.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @version $Id: FileNameMapping.java 992370 2010-09-03 16:48:59Z snicoll $
+ */
+public interface FileNameMapping
+{
+
+    /**
+     * Returns the file name of the specified artifact.
+     *
+     * @param a the artifact
+     * @return the name of the file for the specified artifact
+     */
+    String mapFileName( final Artifact a );
+    
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/FileNameMappingFactory.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/FileNameMappingFactory.java
new file mode 100644
index 0000000..1cdb9e4
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/FileNameMappingFactory.java
@@ -0,0 +1,109 @@
+/*
+ * 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.eclipse.m2e.wtp.namemapping;
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.output.FileNameMapping 
+ * 
+ * Provides access to {@link FileNameMapping} implementations.
+ * <p/>
+ * Two basic implementations are provided by default:
+ * <ul>
+ * <li>standard: the default implementation</li>
+ * <li>full: an implementation that maps to a 'full' file name, i.e. containing the groupId</li>
+ * </ul>
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @version $Id: FileNameMappingFactory.java 992847 2010-09-05 18:16:55Z snicoll $
+ */
+public final class FileNameMappingFactory
+{
+    static final String STANDARD_FILE_NAME_MAPPING = "standard"; //$NON-NLS-1$
+
+    static final String FULL_FILE_NAME_MAPPING = "full"; //$NON-NLS-1$
+
+    static final String NO_VERSION_FILE_NAME_MAPPING = "no-version"; //$NON-NLS-1$
+
+    static final String NO_VERSION_FOR_EJB_NAME_MAPPING = "no-version-for-ejb"; //$NON-NLS-1$
+
+
+    private FileNameMappingFactory()
+    {
+    }
+
+    public static FileNameMapping getDefaultFileNameMapping()
+    {
+        return new StandardFileNameMapping();
+    }
+
+    /**
+     * Returns the file name mapping implementation based on a logical name
+     * of a fully qualified name of the class.
+     *
+     * @param nameOrClass a name of the fqn of the implementation
+     * @return the file name mapping implementation
+     * @throws IllegalStateException if the implementation is not found
+     */
+    public static FileNameMapping getFileNameMapping( final String nameOrClass )
+        throws IllegalStateException
+    {
+        if ( STANDARD_FILE_NAME_MAPPING.equals( nameOrClass ) )
+        {
+            return getDefaultFileNameMapping();
+        }
+        if ( FULL_FILE_NAME_MAPPING.equals( nameOrClass ) )
+        {
+            return new FullFileNameMapping();
+        }
+        if ( NO_VERSION_FILE_NAME_MAPPING.equals( nameOrClass ) )
+        {
+            return new NoVersionFileNameMapping();
+        }
+        if ( NO_VERSION_FOR_EJB_NAME_MAPPING.equals( nameOrClass ) )
+        {
+            return new EjbNoVersionFileNameMapping();
+        }
+        try
+        {
+            final Class<? extends FileNameMapping> c = Class.forName( nameOrClass ).asSubclass(FileNameMapping.class);
+            return c.newInstance();
+        }
+        catch ( ClassNotFoundException e )
+        {
+            throw new IllegalStateException(
+                "File name mapping implementation[" + nameOrClass + "] was not found " + e.getMessage() ); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        catch ( InstantiationException e )
+        {
+            throw new IllegalStateException( "Could not instantiate file name mapping implementation[" + nameOrClass + //$NON-NLS-1$
+                                                 "] make sure it has a default public constructor" ); //$NON-NLS-1$
+        }
+        catch ( IllegalAccessException e )
+        {
+            throw new IllegalStateException( "Could not access file name mapping implementation[" + nameOrClass + //$NON-NLS-1$
+                                                 "] make sure it has a default public constructor" ); //$NON-NLS-1$
+        }
+        catch ( ClassCastException e )
+        {
+            throw new IllegalStateException(
+                "Specified class[" + nameOrClass + "] does not implement[" + FileNameMapping.class.getName() + "]" ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        }
+    }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/FullFileNameMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/FullFileNameMapping.java
new file mode 100644
index 0000000..c98c7a0
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/FullFileNameMapping.java
@@ -0,0 +1,43 @@
+/*
+ * 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.eclipse.m2e.wtp.namemapping;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.output.FullFileNameMapping 
+ * 
+ * A full file name mapping, useful if artifacts might have the same
+ * name across groups.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @version $Id: FullFileNameMapping.java 992847 2010-09-05 18:16:55Z snicoll $
+ */
+public class FullFileNameMapping
+    extends AbstractFileNameMapping
+{
+
+    @Override
+	public String mapFileName( final Artifact a )
+    {
+        final String dashedGroupId = a.getGroupId().replace( '.', '-' );
+        return dashedGroupId + "-" + generateFileName( a, true ); //$NON-NLS-1$
+    }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/NoVersionFileNameMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/NoVersionFileNameMapping.java
new file mode 100644
index 0000000..336dec1
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/NoVersionFileNameMapping.java
@@ -0,0 +1,42 @@
+/*
+ * 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.eclipse.m2e.wtp.namemapping;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.output.NoVersionFileNameMapping 
+ * 
+ * A simplified version of the standard file name mapping which does not
+ * retain the version in the generated file name.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ */
+public class NoVersionFileNameMapping
+    extends AbstractFileNameMapping
+{
+
+    @Override
+	public String mapFileName( Artifact a )
+    {
+        return generateFileName( a, false );
+    }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/PatternBasedFileNameMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/PatternBasedFileNameMapping.java
new file mode 100644
index 0000000..8b2448e
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/PatternBasedFileNameMapping.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.namemapping;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.war.util.MappingUtils;
+import org.codehaus.plexus.interpolation.InterpolationException;
+
+/**
+ * Pattern Based FileName Mapping
+ *
+ * @author Fred Bricon
+ */
+public class PatternBasedFileNameMapping implements FileNameMapping {
+
+  private String pattern;
+  
+  public PatternBasedFileNameMapping(String pattern) {
+    if (pattern == null || pattern.trim().length() == 0) {
+      //pattern = "@{artifactId}@-@{version}@@{dashClassifier?}@.@{extension}@";
+      //MECLIPSEWTP-215 temporary fix until https://bugs.eclipse.org/bugs/show_bug.cgi?id=359385 is fixed
+      //Then we'll switch back to using @{version}
+      pattern = "@{artifactId}@-@{baseVersion}@@{dashClassifier?}@.@{extension}@"; //$NON-NLS-1$
+    }
+    this.pattern = pattern;
+  }
+
+  @Override
+public String mapFileName(Artifact artifact) {
+    try {
+      return MappingUtils.evaluateFileNameMapping(pattern, artifact);
+    } catch(InterpolationException ex) {
+      throw new RuntimeException(ex);
+      //throw new CoreException(new Status(IStatus.ERROR, MavenWtpPlugin.ID, "File name can not be resolved", ex));
+    }
+  }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/StandardFileNameMapping.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/StandardFileNameMapping.java
new file mode 100644
index 0000000..5928821
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/namemapping/StandardFileNameMapping.java
@@ -0,0 +1,43 @@
+/*
+ * 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.eclipse.m2e.wtp.namemapping;
+ 
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * This class was derived from maven-ear-plugin's org.apache.maven.plugin.ear.output.StandardFileNameMapping 
+ * 
+ * The standard file name mapping. It returns the name
+ * of the file in the local repository.
+ *
+ * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
+ * @version $Id: StandardFileNameMapping.java 992847 2010-09-05 18:16:55Z snicoll $
+ */
+public class StandardFileNameMapping
+    extends AbstractFileNameMapping
+{
+
+    @Override
+	public String mapFileName( final Artifact a )
+    {
+        return generateFileName( a, true );
+    }
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/ConfiguratorEnabler.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/ConfiguratorEnabler.java
new file mode 100644
index 0000000..d377fe1
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/ConfiguratorEnabler.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.preferences;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+import org.osgi.service.prefs.BackingStoreException;
+
+
+/**
+ * This class allows clients to enable or disable optional Java EE project configurators.
+ * 
+ * @provisional This class has been added as part of a work in progress. 
+ * It is not guaranteed to work or remain the same in future releases. 
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ * 
+ * @author Fred Bricon
+ * @since 0.17.0
+ */
+public class ConfiguratorEnabler {
+
+  private String label;
+
+  private String description;
+
+  private String id;
+
+  private Set<String> projectConfiguratorIds = new LinkedHashSet<>();
+
+  IEclipsePreferences preferenceStore;
+
+  public ConfiguratorEnabler(String enablerId, String label, String[] configuratorIds, String description) {
+    //Keep new DefaultScope() to maintain Helios compatibility
+    preferenceStore = new InstanceScope().getNode(MavenWtpPlugin.ID);
+    this.id = enablerId;
+    this.label = label;
+    this.description = description;
+    if(configuratorIds != null) {
+      for(String id : configuratorIds) {
+        projectConfiguratorIds.add(id);
+      }
+    }
+  }
+
+  /**
+   * @return the label of the meta project configurator this enabler applies to.
+   */
+  public String getConfiguratorLabel() {
+    return label == null ? id : label;
+  }
+
+  public String getDescription() {
+    return description == null ? getConfiguratorLabel() : description;
+  }
+
+  public String getId() {
+    return id;
+  }
+
+  /**
+   * Checks the <code>org.eclipse.m2e.wtp</code> plugin preferences to see if the configurators this enabler applies to
+   * are enabled.
+   * 
+   * @return <code>true</code> if the configurators are enabled, or no preference has been set yet.
+   */
+  public boolean isEnabled() {
+    return preferenceStore.getBoolean(getPreferenceKey(), true);
+  }
+
+  /**
+   * Stores in the <code>org.eclipse.m2e.wtp</code> plugin preferences the activation status of this enabler.
+   */
+  public void setEnabled(boolean enabled) {
+    preferenceStore.putBoolean(getPreferenceKey(), enabled);
+    try {
+      preferenceStore.flush();
+    } catch(BackingStoreException ex) {
+      ex.printStackTrace();
+    }
+  }
+
+  private String getPreferenceKey() {
+    return getId() + ".enabled"; //$NON-NLS-1$
+  }
+
+  /**
+   * @return true if the given <code>configuratorId</code> is controlled by this enabler.
+   */
+  public boolean appliesTo(String configuratorId) {
+    return projectConfiguratorIds.contains(configuratorId);
+  }
+
+  @Override
+public String toString() {
+    return getId() + " : " + getConfiguratorLabel(); //$NON-NLS-1$
+  }
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/IMavenWtpPreferences.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/IMavenWtpPreferences.java
new file mode 100644
index 0000000..085f3a8
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/IMavenWtpPreferences.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.preferences;
+
+/**
+ * Preferences for Maven WTP
+ *
+ * @author Fred Bricon
+ */
+public interface IMavenWtpPreferences {
+
+  /**
+   * Indicates if the application.xml should be generated under the build directory.
+   * false indicates the first resource directory of the project will be used instead.
+   *  
+   * @return true if the application.xml should be generated under the build directory
+   */
+  boolean isApplicationXmGeneratedInBuildDirectory();
+
+  void setApplicationXmGeneratedInBuildDirectory(boolean isEnabled);
+
+  /**
+   * Indicates if the project uses specific settings.
+   * @return true if the project settings override the workspace preferences.
+   */
+  boolean isEnabledProjectSpecificSettings();
+  
+  void setEnabledProjectSpecificSettings(boolean isEnabled);
+
+  /**
+   * Indicates if the Maven Archiver should try to generate files in the build directory.
+   * false indicates the content directory of the project will be used instead, unless resource filtering is activated.
+   *  
+   * @return true if the Maven Archiver should try to generate files in the build directory.
+   */
+  boolean isWebMavenArchiverUsesBuildDirectory();
+ 
+  void setWebMavenArchiverUsesBuildDirectory(boolean isEnabled);
+  
+  /**
+   * Checks if m2e-wtp is enabled.
+   * 
+   * @since 1.1
+   */
+  boolean isEnabled();
+
+  /**
+   * Disable or enable m2e-wtp.
+   * 
+   * @since 1.1
+   */
+  void setEnabled(boolean isEnabled);
+
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/IMavenWtpPreferencesManager.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/IMavenWtpPreferencesManager.java
new file mode 100644
index 0000000..0ffd73e
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/IMavenWtpPreferencesManager.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.preferences;
+
+import org.eclipse.core.resources.IProject;
+
+
+/**
+ * An instance of this interface allows clients to access and interact with <code>m2e-wtp</code> preferences.
+ * <p>
+ * This interface is not intended to be extended or implemented by clients.
+ * </p>
+
+ * @provisional This class has been added as part of a work in progress.
+ * It is not guaranteed to work or remain the same in future releases.
+ * For more information contact <a href="mailto:m2e-wtp-dev@eclipse.org">m2e-wtp-dev@eclipse.org</a>.
+ *
+ * @author Fred Bricon
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMavenWtpPreferencesManager {
+
+  /**
+   * Returns the <code>m2e-wtp</code> preferences for the project.
+   */
+  IMavenWtpPreferences getPreferences(IProject project);
+
+  /**
+   * Creates a new the instance {@link IMavenWtpPreferences}.
+   */
+  IMavenWtpPreferences createNewPreferences();
+
+  /**
+   * Returns the <code>m2e-wtp</code> preferences for the workspace.
+   */
+  IMavenWtpPreferences getWorkspacePreferences();
+
+  /**
+   * saves the given {@link IMavenWtpPreferences} for the project, or for the workspace,
+   * if project is <code>null</code>.
+   */
+  void savePreferences(IMavenWtpPreferences preferences, IProject project);
+
+  /**
+   * Returns all {@link ConfiguratorEnabler}s for optional Java EE project configurators.
+   *
+   * @since 0.17.0
+   */
+  ConfiguratorEnabler[] getConfiguratorEnablers();
+
+  /**
+   * Checks if an optional configurator is enabled. If no preferences are set for that configurator,
+   * it's assumed it's enabled by default.
+   *
+   * @since 0.17.0
+   */
+  boolean isEnabled(String configuratorId);
+}
diff --git a/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/MavenWtpPreferencesConstants.java b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/MavenWtpPreferencesConstants.java
new file mode 100644
index 0000000..69f95f1
--- /dev/null
+++ b/org.eclipse.m2e.wtp/src/org/eclipse/m2e/wtp/preferences/MavenWtpPreferencesConstants.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2008-2014 Sonatype, Inc. and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.m2e.wtp.preferences;
+
+import org.eclipse.m2e.wtp.MavenWtpPlugin;
+
+
+/**
+ * m2e-wtp preferences constants 
+ */
+public final class MavenWtpPreferencesConstants {
+
+  /**
+   * m2e-wtp preference page id.
+   */
+  public static final String MAVEN_WTP_PREFERENCE_PAGE = "org.eclipse.m2e.wtp.preferences.MavenWtpPreferencePage"; //$NON-NLS-1$
+
+  /**
+   * m2e-wtp preference keys prefix.
+   */
+
+  public static final String PREFIX = MavenWtpPlugin.ID;
+
+  /**
+   * Key to toggle application.xml file generation in build directory.
+   */
+  public static final String P_APPLICATION_XML_IN_BUILD_DIR = PREFIX + ".ear.applicationXmlInBuilDir"; //$NON-NLS-1$
+
+  /**
+   * Key to toggle MANIFEST.MF and pom properties file generation 
+   * in build directory.
+   */
+  public static final String P_WEB_MAVENARCHIVER_IN_BUILD_DIR = PREFIX + ".war.archiverFilesInBuilDir"; //$NON-NLS-1$
+
+  /**
+   * Key to (en|dis)able project specific m2e-wtp settings.
+   */
+  public static final String P_ENABLED_PROJECT_SPECIFIC__PREFS = PREFIX + ".enabledProjectSpecificPrefs"; //$NON-NLS-1$
+
+  /**
+   * Key to (en|dis)able m2e-wtp
+   * 
+   * @since 1.1.0
+   */
+  public static final String P_ENABLE_M2EWTP = PREFIX + ".enableM2eWtp"; //$NON-NLS-1$
+
+  /**
+   * Private constructor to avoid instanciation
+   */
+  private MavenWtpPreferencesConstants() {}
+
+}
diff --git a/pom.xml b/pom.xml
index fae0897..0648795 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  Copyright (c) 2008 Sonatype, Inc.
+  Copyright (c) 2008-2015 Sonatype, Inc. and others
   All rights reserved. This program and the accompanying materials
   are made available under the terms of the Eclipse Public License v1.0
   which accompanies this distribution, and is available at
@@ -11,34 +11,332 @@
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
-    <groupId>org.eclipse.m2e.wtp</groupId>
-    <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
-    <version>1.3.0-SNAPSHOT</version>
+    <groupId>org.sonatype.forge</groupId>
+    <artifactId>forge-parent</artifactId>
+    <version>10</version>
   </parent>
 
   <groupId>org.eclipse.m2e.wtp</groupId>
-  <artifactId>org.eclipse.m2e.wtp.jpa.parent</artifactId>
+  <artifactId>org.eclipse.m2e.wtp.parent</artifactId>
+  <version>1.3.0-SNAPSHOT</version>
   <packaging>pom</packaging>
-  <name>M2E-WTP JPA :: Parent</name>
+
+  <name>M2E-WTP :: Parent</name>
+  <url>http://www.eclipse.org/m2e-wtp</url>
+  <inceptionYear>2008</inceptionYear>
 
   <properties>
-    <m2e-wtp.url>http://download.eclipse.org/m2e-wtp/snapshots/</m2e-wtp.url>
-    <tycho.scmUrl>scm:git:http://git.eclipse.org/gitroot/m2e-wtp/org.eclipse.m2e.wtp.jpa.git</tycho.scmUrl>
+    <tycho-version>0.23.1</tycho-version>
+    <tycho-extras-version>${tycho-version}</tycho-extras-version>
+    <tycho.scmUrl>scm:git:http://git.eclipse.org/gitroot/m2e-wtp/org.eclipse.m2e.wtp.git</tycho.scmUrl>
+
+    <test.timeout>1800</test.timeout><!--  30 mins -->
+    <tycho.test.jvmArgs>-Xmx512m -XX:MaxPermSize=256m</tycho.test.jvmArgs>
+    <eclipse.target>mars</eclipse.target>
+    <eclipse-repo.url>http://download.eclipse.org/releases/${eclipse.target}</eclipse-repo.url>
+    <webtools-repo.url>http://download.eclipse.org/webtools/repository/${eclipse.target}</webtools-repo.url>
+    <orbit-repo.url>http://download.eclipse.org/tools/orbit/downloads/drops/R20140525021250/repository/</orbit-repo.url>
+    <!--
+    <m2e-repo.url>http://download.eclipse.org/technology/m2e/releases/1.6/</m2e-repo.url>
+    -->
+    <m2e-repo.url>http://download.eclipse.org/technology/m2e/milestones/1.7/</m2e-repo.url>
+    <!-- Warning : changing the mavenarchiver version requires submitting a new CQ in ipzilla -->
+    <!-- Use signed version of m2eclipse-mavenarchiver 0.17.0.201502101659, built on build.eclipse.org -->
+    <mavenarchiver-repo.url>http://download.eclipse.org/m2e-wtp/signed/mavenarchiver/0.17.0/</mavenarchiver-repo.url>
+
   </properties>
 
+  <prerequisites>
+   <maven>3.0</maven>
+  </prerequisites>
+
+  <organization>
+    <name>Eclipse foundation</name>
+    <url>http://www.eclipse.org</url>
+  </organization>
+
+  <licenses>
+    <license>
+      <name>Eclipse Public License - v 1.0</name>
+      <url>http://www.eclipse.org/legal/epl-v10.html</url>
+    </license>
+  </licenses>
+
+  <issueManagement>
+    <url>https://bugs.eclipse.org/bugs/enter_bug.cgi?product=M2E-WTP</url>
+    <system>Bugzilla</system>
+  </issueManagement>
+
+  <ciManagement>
+    <system>Hudson</system>
+    <url>http://hudson.eclipse.org/</url>
+  </ciManagement>
+
   <modules>
+    <module>org.eclipse.m2e.wtp.overlay</module>
+    <module>org.eclipse.m2e.wtp.overlay.ui</module>
+    <module>org.eclipse.m2e.wtp</module>
+    <module>org.eclipse.m2e.wtp.feature</module>
+    <module>org.eclipse.m2e.wtp.sdk.feature</module>
+    <module>org.eclipse.m2e.wtp.jaxrs</module>
+    <module>org.eclipse.m2e.wtp.jaxrs.feature</module>
+    <module>org.eclipse.m2e.wtp.jsf</module>
+    <module>org.eclipse.m2e.wtp.jsf.feature</module>
     <module>org.eclipse.m2e.wtp.jpa</module>
     <module>org.eclipse.m2e.wtp.jpa.feature</module>
-    <module>org.eclipse.m2e.wtp.jpa.site</module>
+    <module>org.eclipse.m2e.wtp.site</module>
   </modules>
 
   <repositories>
     <repository>
-      <id>m2e-wtp</id>
+      <id>m2e-core</id>
       <layout>p2</layout>
-      <url>${m2e-wtp.url}</url>
+      <url>${m2e-repo.url}</url>
+    </repository>
+    <repository>
+      <id>eclipse</id>
+      <layout>p2</layout>
+      <url>${eclipse-repo.url}</url>
+    </repository>
+    <repository>
+      <id>orbit</id>
+      <layout>p2</layout>
+      <url>${orbit-repo.url}</url>
+    </repository>
+    <!--
+    <repository>
+      <id>webtools</id>
+      <layout>p2</layout>
+      <url>${webtools-repo.url}</url>
+    </repository>
+    -->
+    <repository>
+      <id>eclipse-license</id>
+      <layout>p2</layout>
+      <url>http://download.eclipse.org/cbi/updates/license</url>
+    </repository>
+    <repository>
+      <id>mavenarchiver</id>
+      <layout>p2</layout>
+      <url>${mavenarchiver-repo.url}</url>
+    </repository>
+    <repository>
+      <id>RSO-public-group</id>
+      <url>http://repository.sonatype.org/content/groups/sonatype-public-grid</url>
+      <releases>
+        <enabled>true</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
     </repository>
   </repositories>
 
-  <version>1.3.0-SNAPSHOT</version>
+  <pluginRepositories>
+    <pluginRepository>
+      <id>RSO-public-group</id>
+      <url>http://repository.sonatype.org/content/groups/sonatype-public-grid</url>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </pluginRepository>
+  </pluginRepositories>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-packaging-plugin</artifactId>
+        <version>${tycho-version}</version>
+        <configuration>
+          <format>yyyyMMdd-HHmm</format>
+          <sourceReferences>
+            <generate>true</generate>
+          </sourceReferences>
+        </configuration>
+       <dependencies>
+          <dependency>
+            <groupId>org.eclipse.tycho.extras</groupId>
+            <artifactId>tycho-sourceref-jgit</artifactId>
+            <version>${tycho-extras-version}</version>
+          </dependency>
+       </dependencies>
+      </plugin>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-maven-plugin</artifactId>
+        <version>${tycho-version}</version>
+        <extensions>true</extensions>
+      </plugin>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>target-platform-configuration</artifactId>
+        <version>${tycho-version}</version>
+        <configuration>
+          <pomDependencies>consider</pomDependencies>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-source-plugin</artifactId>
+        <version>${tycho-version}</version>
+        <executions>
+          <execution>
+            <id>plugin-source</id>
+            <goals>
+              <goal>plugin-source</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-resources-plugin</artifactId>
+          <version>2.6</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>osx</id>
+      <activation>
+        <os>
+          <family>mac</family>
+        </os>
+      </activation>
+      <properties>
+        <tycho.test.jvmArgs>-Xmx512m -XX:MaxPermSize=256m -Dosgi.ws=cocoa -XstartOnFirstThread</tycho.test.jvmArgs>
+        <osgi.ws>cocoa</osgi.ws>
+      </properties>
+    </profile>
+    <profile>
+      <id>sdk</id>
+      <activation>
+      <file>
+        <exists>sdk</exists>
+      </file>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.eclipse.tycho.extras</groupId>
+            <artifactId>tycho-source-feature-plugin</artifactId>
+            <version>${tycho-extras-version}</version>
+            <executions>
+              <execution>
+                <id>source-feature</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>source-feature</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.eclipse.tycho</groupId>
+            <artifactId>tycho-p2-plugin</artifactId>
+            <version>${tycho-version}</version>
+            <executions>
+              <execution>
+                <id>attach-p2-metadata</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>p2-metadata</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>eclipse-sign</id>
+
+      <pluginRepositories>
+        <pluginRepository>
+          <id>m2e-cbi</id>
+          <url>http://download.eclipse.org/technology/m2e/maven/</url>
+        </pluginRepository>
+      </pluginRepositories>
+
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.eclipse.tycho</groupId>
+            <artifactId>target-platform-configuration</artifactId>
+            <version>${tycho-version}</version>
+            <configuration>
+              <includePackedArtifacts>true</includePackedArtifacts>
+            </configuration>
+          </plugin>
+
+          <plugin>
+            <groupId>org.eclipse.tycho.extras</groupId>
+            <artifactId>tycho-pack200a-plugin</artifactId>
+            <version>${tycho-extras-version}</version>
+            <executions>
+              <execution>
+                <id>pack200-normalize</id>
+                <goals>
+                  <goal>normalize</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+
+          <plugin>
+            <groupId>org.eclipse.cbi.maven.plugins</groupId>
+            <artifactId>eclipse-jarsigner-plugin</artifactId>
+            <version>1.0.1</version>
+            <executions>
+              <execution>
+                <id>sign</id>
+                <goals>
+                  <goal>sign</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+
+          <plugin>
+            <groupId>org.eclipse.tycho.extras</groupId>
+            <artifactId>tycho-pack200b-plugin</artifactId>
+            <version>${tycho-extras-version}</version>
+            <executions>
+              <execution>
+                <id>pack200-pack</id>
+                <goals>
+                  <goal>pack</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+
+          <plugin>
+            <groupId>org.eclipse.tycho</groupId>
+            <artifactId>tycho-p2-plugin</artifactId>
+            <version>${tycho-version}</version>
+            <executions>
+              <execution>
+                <id>p2-metadata</id>
+                <goals>
+                  <goal>p2-metadata</goal>
+                </goals>
+                <phase>package</phase>
+              </execution>
+              </executions>
+            <configuration>
+              <defaultP2Metadata>false</defaultP2Metadata>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    </profiles>
 </project>