Merge commit
diff --git a/.gitignore b/.gitignore
index 7e27cd8..60d351c 100755
--- a/.gitignore
+++ b/.gitignore
@@ -31,5 +31,9 @@
 .fbwarnings
 javaCompiler...args
 
+<<<<<<< HEAD
 # maven
+=======
+# maven 
+>>>>>>> 5f48a07d3516fa5c4baca8276da4de29170c0ab3
 target/
\ No newline at end of file
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/.project b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/.project
new file mode 100644
index 0000000..83aaabf
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jst.common.fproj.enablement.jdt.feature.patch</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/build.properties b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/build.properties
new file mode 100644
index 0000000..cb50260
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/build.properties
@@ -0,0 +1,5 @@
+bin.includes = feature.xml,\
+               license.html,\
+               feature.properties,\
+               epl-v10.html,\
+               eclipse_update_120.jpg
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/buildnotes_org.eclipse.jst.common.fproj.enablement.jdt.feature.patch.html b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/buildnotes_org.eclipse.jst.common.fproj.enablement.jdt.feature.patch.html
new file mode 100644
index 0000000..e98ba68
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/buildnotes_org.eclipse.jst.common.fproj.enablement.jdt.feature.patch.html
@@ -0,0 +1,19 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="Build" content="Build">
+<title>WTP 3.2.5 Patches</title>
+</head>
+
+<body>
+
+	<h1>WTP 3.2.5 Patches</h1>
+
+	<h2>org.eclipse.jst.common.fproj.enablement.jdt</h2>
+	
+	<p>Bug <a href='https://bugs.eclipse.org/373666'>373666</a>. Adopter-only patch for allowing Static web project facets to coexist with Java facet</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/eclipse_update_120.jpg b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/eclipse_update_120.jpg
new file mode 100644
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/epl-v10.html b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/epl-v10.html
new file mode 100644
index 0000000..abeecc4
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/epl-v10.html
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Public License - Version 1.0</title>
+<style type="text/css">
+  body {
+    size: 8.5in 11.0in;
+    margin: 0.25in 0.5in 0.25in 0.5in;
+    tab-interval: 0.5in;
+    }
+  p {  	
+    margin-left: auto;
+    margin-top:  0.5em;
+    margin-bottom: 0.5em;
+    }
+  p.list {
+  	margin-left: 0.5in;
+    margin-top:  0.05em;
+    margin-bottom: 0.05em;
+    }
+  </style>
+
+</head>
+
+<body lang="EN-US">
+
+<h2>Eclipse Public License - v 1.0</h2>
+
+<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
+AGREEMENT.</p>
+
+<p><b>1. DEFINITIONS</b></p>
+
+<p>&quot;Contribution&quot; means:</p>
+
+<p class="list">a) in the case of the initial Contributor, the initial
+code and documentation distributed under this Agreement, and</p>
+<p class="list">b) in the case of each subsequent Contributor:</p>
+
+<p class="list">i) changes to the Program, and</p>
+<p class="list">ii) additions to the Program;</p>
+<p class="list">where such changes and/or additions to the Program
+originate from and are distributed by that particular Contributor. A
+Contribution 'originates' from a Contributor if it was added to the
+Program by such Contributor itself or anyone acting on such
+Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii)
+are not derivative works of the Program.</p>
+
+<p>&quot;Contributor&quot; means any person or entity that distributes
+the Program.</p>
+
+<p>&quot;Licensed Patents&quot; mean patent claims licensable by a
+Contributor which are necessarily infringed by the use or sale of its
+Contribution alone or when combined with the Program.</p>
+
+<p>&quot;Program&quot; means the Contributions distributed in accordance
+with this Agreement.</p>
+
+<p>&quot;Recipient&quot; means anyone who receives the Program under
+this Agreement, including all Contributors.</p>
+
+<p><b>2. GRANT OF RIGHTS</b></p>
+
+<p class="list">a) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free copyright license to reproduce, prepare derivative works
+of, publicly display, publicly perform, distribute and sublicense the
+Contribution of such Contributor, if any, and such derivative works, in
+source code and object code form.</p>
+
+<p class="list">b) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free patent license under Licensed Patents to make, use, sell,
+offer to sell, import and otherwise transfer the Contribution of such
+Contributor, if any, in source code and object code form. This patent
+license shall apply to the combination of the Contribution and the
+Program if, at the time the Contribution is added by the Contributor,
+such addition of the Contribution causes such combination to be covered
+by the Licensed Patents. The patent license shall not apply to any other
+combinations which include the Contribution. No hardware per se is
+licensed hereunder.</p>
+
+<p class="list">c) Recipient understands that although each Contributor
+grants the licenses to its Contributions set forth herein, no assurances
+are provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility to
+secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow Recipient
+to distribute the Program, it is Recipient's responsibility to acquire
+that license before distributing the Program.</p>
+
+<p class="list">d) Each Contributor represents that to its knowledge it
+has sufficient copyright rights in its Contribution, if any, to grant
+the copyright license set forth in this Agreement.</p>
+
+<p><b>3. REQUIREMENTS</b></p>
+
+<p>A Contributor may choose to distribute the Program in object code
+form under its own license agreement, provided that:</p>
+
+<p class="list">a) it complies with the terms and conditions of this
+Agreement; and</p>
+
+<p class="list">b) its license agreement:</p>
+
+<p class="list">i) effectively disclaims on behalf of all Contributors
+all warranties and conditions, express and implied, including warranties
+or conditions of title and non-infringement, and implied warranties or
+conditions of merchantability and fitness for a particular purpose;</p>
+
+<p class="list">ii) effectively excludes on behalf of all Contributors
+all liability for damages, including direct, indirect, special,
+incidental and consequential damages, such as lost profits;</p>
+
+<p class="list">iii) states that any provisions which differ from this
+Agreement are offered by that Contributor alone and not by any other
+party; and</p>
+
+<p class="list">iv) states that source code for the Program is available
+from such Contributor, and informs licensees how to obtain it in a
+reasonable manner on or through a medium customarily used for software
+exchange.</p>
+
+<p>When the Program is made available in source code form:</p>
+
+<p class="list">a) it must be made available under this Agreement; and</p>
+
+<p class="list">b) a copy of this Agreement must be included with each
+copy of the Program.</p>
+
+<p>Contributors may not remove or alter any copyright notices contained
+within the Program.</p>
+
+<p>Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.</p>
+
+<p><b>4. COMMERCIAL DISTRIBUTION</b></p>
+
+<p>Commercial distributors of software may accept certain
+responsibilities with respect to end users, business partners and the
+like. While this license is intended to facilitate the commercial use of
+the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create
+potential liability for other Contributors. Therefore, if a Contributor
+includes the Program in a commercial product offering, such Contributor
+(&quot;Commercial Contributor&quot;) hereby agrees to defend and
+indemnify every other Contributor (&quot;Indemnified Contributor&quot;)
+against any losses, damages and costs (collectively &quot;Losses&quot;)
+arising from claims, lawsuits and other legal actions brought by a third
+party against the Indemnified Contributor to the extent caused by the
+acts or omissions of such Commercial Contributor in connection with its
+distribution of the Program in a commercial product offering. The
+obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In
+order to qualify, an Indemnified Contributor must: a) promptly notify
+the Commercial Contributor in writing of such claim, and b) allow the
+Commercial Contributor to control, and cooperate with the Commercial
+Contributor in, the defense and any related settlement negotiations. The
+Indemnified Contributor may participate in any such claim at its own
+expense.</p>
+
+<p>For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.</p>
+
+<p><b>5. NO WARRANTY</b></p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
+responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to
+the risks and costs of program errors, compliance with applicable laws,
+damage to or loss of data, programs or equipment, and unavailability or
+interruption of operations.</p>
+
+<p><b>6. DISCLAIMER OF LIABILITY</b></p>
+
+<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
+NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p>
+
+<p><b>7. GENERAL</b></p>
+
+<p>If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further action
+by the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.</p>
+
+<p>If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other
+software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the
+date such litigation is filed.</p>
+
+<p>All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of time
+after becoming aware of such noncompliance. If all Recipient's rights
+under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive.</p>
+
+<p>Everyone is permitted to copy and distribute copies of this
+Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The
+Agreement Steward reserves the right to publish new versions (including
+revisions) of this Agreement from time to time. No one other than the
+Agreement Steward has the right to modify this Agreement. The Eclipse
+Foundation is the initial Agreement Steward. The Eclipse Foundation may
+assign the responsibility to serve as the Agreement Steward to a
+suitable separate entity. Each new version of the Agreement will be
+given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the
+Agreement under which it was received. In addition, after a new version
+of the Agreement is published, Contributor may elect to distribute the
+Program (including its Contributions) under the new version. Except as
+expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
+rights or licenses to the intellectual property of any Contributor under
+this Agreement, whether expressly, by implication, estoppel or
+otherwise. All rights in the Program not expressly granted under this
+Agreement are reserved.</p>
+
+<p>This Agreement is governed by the laws of the State of New York and
+the intellectual property laws of the United States of America. No party
+to this Agreement will bring a legal action under this Agreement more
+than one year after the cause of action arose. Each party waives its
+rights to a jury trial in any resulting litigation.</p>
+
+</body>
+
+</html>
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/feature.properties b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/feature.properties
new file mode 100644
index 0000000..1f3fb70
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/feature.properties
@@ -0,0 +1,173 @@
+###############################################################################
+# Copyright (c) 2008 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
+###############################################################################
+# 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=WTP Patches for org.eclipse.jst.common.fproj.enablement.jdt
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse Web Tools Platform
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Web Tools Platform (WTP) Project update site
+
+# "description" property - description of the feature
+description=\
+Contains fixes described in the following bugzilla(s):\n\
+\n\
+Bug https://bugs.eclipse.org/373666 Adopter-only patch for allowing Static web project facets to coexist with Java facet\n\
+\n\
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2011 IBM Corporation 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\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+Eclipse Foundation Software User Agreement\n\
+April 14, 2010\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the\n\
+Eclipse Foundation is provided to you under the terms and conditions of\n\
+the Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is\n\
+provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse Foundation source code\n\
+repository ("Repository") in software modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+       - Content may be structured and packaged into modules to facilitate delivering,\n\
+         extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+         plug-in fragments ("Fragments"), and features ("Features").\n\
+       - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java(TM) ARchive)\n\
+         in a directory named "plugins".\n\
+       - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+         Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+         Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+         numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+       - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+         named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+       - The top-level (root) directory\n\
+       - Plug-in and Fragment directories\n\
+       - Inside Plug-ins and Fragments packaged as JARs\n\
+       - Sub-directories of the directory named "src" of certain Plug-ins\n\
+       - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Provisioning Technology (as defined below), you must agree to a license ("Feature \n\
+Update License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties" found within a Feature.\n\
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the\n\
+terms and conditions (or references to such terms and conditions) that\n\
+govern your use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+       - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+       - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+       - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+       - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+       - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+\n\Use of Provisioning Technology\n\
+\n\
+The Eclipse Foundation makes available provisioning software, examples of which include,\n\
+but are not limited to, p2 and the Eclipse Update Manager ("Provisioning Technology") for\n\
+the purpose of allowing users to install software, documentation, information and/or\n\
+other materials (collectively "Installable Software"). This capability is provided with\n\
+the intent of allowing such users to install, extend and update Eclipse-based products.\n\
+Information about packaging Installable Software is available at\n\
+http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\
+\n\
+You may use Provisioning Technology to allow other parties to install Installable Software.\n\
+You shall be responsible for enabling the applicable license agreements relating to the\n\
+Installable Software to be presented to, and accepted by, the users of the Provisioning Technology\n\
+in accordance with the Specification. By using Provisioning Technology in such a manner and\n\
+making it available in accordance with the Specification, you further acknowledge your\n\
+agreement to, and the acquisition of all necessary rights to permit the following:\n\
+\n\
+       1. A series of actions may occur ("Provisioning Process") in which a user may execute\n\
+          the Provisioning Technology on a machine ("Target Machine") with the intent of installing,\n\
+          extending or updating the functionality of an Eclipse-based product.\n\
+       2. During the Provisioning Process, the Provisioning Technology may cause third party\n\
+          Installable Software or a portion thereof to be accessed and copied to the Target Machine.\n\
+       3. Pursuant to the Specification, you will provide to the user the terms and conditions that\n\
+          govern the use of the Installable Software ("Installable Software Agreement") and such\n\
+          Installable Software Agreement shall be accessed from the Target Machine in accordance\n\
+          with the Specification. Such Installable Software Agreement must inform the user of the\n\
+          terms and conditions that govern the Installable Software and must solicit acceptance by\n\
+          the end user in the manner prescribed in such Installable Software Agreement. Upon such\n\
+          indication of agreement by the user, the provisioning Technology will complete installation\n\
+          of the Installable Software.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use, and\n\
+re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/feature.xml b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/feature.xml
new file mode 100644
index 0000000..4595e6d
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/feature.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.jst.common.fproj.enablement.jdt.feature.patch"
+      label="%featureName"
+      version="3.2.5.qualifier"
+      provider-name="%providerName">
+
+   <description>
+      %description
+   </description>
+
+   <copyright>
+      %copyright
+   </copyright>
+
+   <license url="%licenseURL">
+      %license
+   </license>
+
+   <requires>
+      <import feature="org.eclipse.jst.common.fproj.enablement.jdt" version="3.2.2.v201008170019-377AB8s73533J5J759F " patch="true"/>
+   </requires>
+
+</feature>
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/license.html b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/license.html
new file mode 100644
index 0000000..c184ca3
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/license.html
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!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>Eclipse Foundation Software User Agreement</title>
+</head>
+
+<body lang="EN-US">
+<h2>Eclipse Foundation Software User Agreement</h2>
+<p>April 14, 2010</p>
+
+<h3>Usage Of Content</h3>
+
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+   (COLLECTIVELY &quot;CONTENT&quot;).  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p>
+
+<h3>Applicable Licenses</h3>
+
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation 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 provided with this Content and is also 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>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code
+   repository (&quot;Repository&quot;) in software modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p>
+
+<ul>
+       <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li>
+       <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li>
+       <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;.  Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
+      and/or Fragments associated with that Feature.</li>
+       <li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li>
+</ul>
+
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
+Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;).  Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p>
+
+<ul>
+       <li>The top-level (root) directory</li>
+       <li>Plug-in and Fragment directories</li>
+       <li>Inside Plug-ins and Fragments packaged as JARs</li>
+       <li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li>
+       <li>Feature directories</li>
+</ul>
+
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license (&quot;Feature Update License&quot;) during the
+installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them.  Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p>
+
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p>
+
+<ul>
+       <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li>
+       <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li>
+       <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li>
+       <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li>
+       <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li>
+</ul>
+
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p>
+
+
+<h3>Use of Provisioning Technology</h3>
+
+<p>The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse
+   Update Manager (&quot;Provisioning Technology&quot;) for the purpose of allowing users to install software, documentation, information and/or
+   other materials (collectively &quot;Installable Software&quot;). This capability is provided with the intent of allowing such users to
+   install, extend and update Eclipse-based products. Information about packaging Installable Software is available at <a
+       href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
+   (&quot;Specification&quot;).</p>
+
+<p>You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the
+   applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology
+   in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the
+   Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:</p>
+
+<ol>
+       <li>A series of actions may occur (&quot;Provisioning Process&quot;) in which a user may execute the Provisioning Technology
+       on a machine (&quot;Target Machine&quot;) with the intent of installing, extending or updating the functionality of an Eclipse-based
+       product.</li>
+       <li>During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be
+       accessed and copied to the Target Machine.</li>
+       <li>Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable
+       Software (&quot;Installable Software Agreement&quot;) and such Installable Software Agreement shall be accessed from the Target
+       Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern
+       the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such
+       indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.</li>
+</ol>
+
+<h3>Cryptography</h3>
+
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+   possession, or use, and re-export of encryption software, to see if this is permitted.</p>
+
+<p><small>Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.</small></p>
+</body>
+</html>
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/pom.xml b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/pom.xml
new file mode 100644
index 0000000..1a47335
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature.patch/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright (c) 2012, 2013 Eclipse Foundation and others.

+  All rights reserved. This program and the accompanying materials

+  are made available under the terms of the Eclipse Distribution License v1.0

+  which accompanies this distribution, and is available at

+  http://www.eclipse.org/org/documents/edl-v10.php

+ 

+  Contributors:

+    Thanh Ha (Eclipse Foundation) - initial implementation

+-->

+

+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"

+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

+  <modelVersion>4.0.0</modelVersion>

+  <parent>

+    <groupId>org.eclipse.webtools.common</groupId>

+    <artifactId>org.eclipse.webtools.common.fproj</artifactId>

+    <version>3.6.0-SNAPSHOT</version>

+    <relativePath>../../</relativePath>

+  </parent>

+

+  <groupId>org.eclipse.webtools.common</groupId>

+  <artifactId>org.eclipse.jst.common.fproj.enablement.jdt.feature.patch</artifactId>

+  <version>3.2.5-SNAPSHOT</version>

+  <packaging>eclipse-feature</packaging>

+</project>
\ No newline at end of file
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/.project b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/.project
new file mode 100644
index 0000000..1eabbef
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jst.common.fproj.enablement.jdt.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/build.properties b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/build.properties
new file mode 100644
index 0000000..3e69ba2
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/build.properties
@@ -0,0 +1,4 @@
+bin.includes = feature.xml,\
+               eclipse_update_120.jpg,\
+               feature.properties
+
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/eclipse_update_120.jpg b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/feature.properties b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/feature.properties
new file mode 100644
index 0000000..9a326a1
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/feature.properties
@@ -0,0 +1,31 @@
+# "featureName" property - name of the feature
+featureName=Eclipse Faceted Project Framework JDT Enablement
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse Web Tools Platform
+
+
+# "description" property - description of the feature
+description=The Faceted Project Framework allows the plugin developer to think of projects \n\
+as composed of units of functionality, otherwise known as facets, that can be added and removed \n\
+by the user.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2009 Oracle 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
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+# license and licenseURL properties were removed as a result to migrating to new PDE license support. 
+#    Those properties are now added at build time. See http://wiki.eclipse.org/Equinox/p2/License_Mechanism. 
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+# license and licenseURL properties were removed as a result to migrating to new PDE license support. 
+#    Those properties are now added at build time. See http://wiki.eclipse.org/Equinox/p2/License_Mechanism. 
+########### end of license property ##########################################
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/feature.xml b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/feature.xml
new file mode 100644
index 0000000..37f1855
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/feature.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature

+      id="org.eclipse.jst.common.fproj.enablement.jdt"

+      label="%featureName"

+      version="3.8.0.qualifier"

+      provider-name="%providerName"

+      plugin="org.eclipse.jst.common.project.facet.core"

+      license-feature="org.eclipse.license"

+      license-feature-version="1.0.1.qualifier">

+

+   <description>

+      %description

+   </description>

+

+   <copyright>

+      %copyright

+   </copyright>

+

+   <license url="%licenseURL">

+      %license

+   </license>

+

+   <plugin

+         id="org.eclipse.jst.common.project.facet.core"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+   <plugin

+         id="org.eclipse.jst.common.project.facet.ui"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+</feature>

diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/pom.xml b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/pom.xml
new file mode 100644
index 0000000..4ebbabd
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright (c) 2012, 2013 Eclipse Foundation and others.

+  All rights reserved. This program and the accompanying materials

+  are made available under the terms of the Eclipse Distribution License v1.0

+  which accompanies this distribution, and is available at

+  http://www.eclipse.org/org/documents/edl-v10.php

+ 

+  Contributors:

+    Thanh Ha (Eclipse Foundation) - initial implementation

+-->

+

+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"

+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

+  <modelVersion>4.0.0</modelVersion>

+  <parent>

+    <groupId>org.eclipse.webtools.common</groupId>

+    <artifactId>org.eclipse.webtools.common.fproj</artifactId>

+    <version>3.6.0-SNAPSHOT</version>

+    <relativePath>../../</relativePath>

+  </parent>

+

+  <groupId>org.eclipse.webtools.common</groupId>

+  <artifactId>org.eclipse.jst.common.fproj.enablement.jdt</artifactId>

+  <version>3.8.0-SNAPSHOT</version>

+  <packaging>eclipse-feature</packaging>

+</project>
\ No newline at end of file
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/sourceTemplateBundle/about.html b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/sourceTemplateBundle/about.html
new file mode 100644
index 0000000..fe81d46
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/sourceTemplateBundle/about.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<P>June, 2008</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.</p>
+
+<h3>Source Code</h3>
+<p>This plug-in contains source code zip files (&quot;Source Zips&quot;) that correspond to binary content in other plug-ins. These Source Zips may be distributed under different license
+agreements and/or notices. Details about these license agreements and notices are contained in &quot;about.html&quot; files (&quot;Abouts&quot;) located in sub-directories in the
+src/ directory of this plug-in. Such Abouts govern your use of the Source Zips in that directory, not the EPL.</p>
+
+</body>
+</html>
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/sourceTemplateBundle/build.properties b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/sourceTemplateBundle/build.properties
new file mode 100644
index 0000000..90b8764
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.feature/sourceTemplateBundle/build.properties
@@ -0,0 +1 @@
+bin.includes = about.html
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/.project b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/.project
new file mode 100644
index 0000000..14e1dee
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/build.properties b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/build.properties
new file mode 100644
index 0000000..e21a9f8
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/build.properties
@@ -0,0 +1,6 @@
+bin.includes = feature.xml,\
+               eclipse_update_120.jpg,\
+               feature.properties
+
+generate.plugin@org.eclipse.jst.common.project.facet.core.source=org.eclipse.jst.common.project.facet.core
+generate.plugin@org.eclipse.jst.common.project.facet.ui.source=org.eclipse.jst.common.project.facet.ui
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/eclipse_update_120.jpg b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/feature.properties b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/feature.properties
new file mode 100644
index 0000000..7da3fac
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/feature.properties
@@ -0,0 +1,31 @@
+# "featureName" property - name of the feature
+featureName=Eclipse Faceted Project Framework JDT Enablement SDK
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse Web Tools Platform
+
+
+# "description" property - description of the feature
+description=The Faceted Project Framework allows the plugin developer to think of projects \n\
+as composed of units of functionality, otherwise known as facets, that can be added and removed \n\
+by the user.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2009 Oracle 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
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+# license and licenseURL properties were removed as a result to migrating to new PDE license support. 
+#    Those properties are now added at build time. See http://wiki.eclipse.org/Equinox/p2/License_Mechanism. 
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+# license and licenseURL properties were removed as a result to migrating to new PDE license support. 
+#    Those properties are now added at build time. See http://wiki.eclipse.org/Equinox/p2/License_Mechanism. 
+########### end of license property ##########################################
diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/feature.xml b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/feature.xml
new file mode 100644
index 0000000..ac64371
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/feature.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature

+      id="org.eclipse.jst.common.fproj.enablement.jdt.sdk"

+      label="%featureName"

+      version="3.8.0.qualifier"

+      provider-name="%providerName"

+      plugin="org.eclipse.jst.common.fproj.enablement.jdt.sdk"

+      license-feature="org.eclipse.license"

+      license-feature-version="1.0.1.qualifier">

+

+   <description>

+      %description

+   </description>

+

+   <copyright>

+      %copyright

+   </copyright>

+

+   <license url="license.html">

+      %license

+   </license>

+

+   <includes

+         id="org.eclipse.jst.common.fproj.enablement.jdt"

+         version="0.0.0"/>

+

+   <plugin

+         id="org.eclipse.jst.common.project.facet.core.source"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+   <plugin

+         id="org.eclipse.jst.common.project.facet.ui.source"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+   <plugin

+         id="org.eclipse.jst.common.fproj.enablement.jdt.sdk"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+</feature>

diff --git a/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/pom.xml b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/pom.xml
new file mode 100644
index 0000000..6bfddbc
--- /dev/null
+++ b/features/org.eclipse.jst.common.fproj.enablement.jdt.sdk.feature/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright (c) 2012, 2013 Eclipse Foundation and others.

+  All rights reserved. This program and the accompanying materials

+  are made available under the terms of the Eclipse Distribution License v1.0

+  which accompanies this distribution, and is available at

+  http://www.eclipse.org/org/documents/edl-v10.php

+ 

+  Contributors:

+    Thanh Ha (Eclipse Foundation) - initial implementation

+-->

+

+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"

+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

+  <modelVersion>4.0.0</modelVersion>

+  <parent>

+    <groupId>org.eclipse.webtools.common</groupId>

+    <artifactId>org.eclipse.webtools.common.fproj</artifactId>

+    <version>3.6.0-SNAPSHOT</version>

+    <relativePath>../../</relativePath>

+  </parent>

+

+  <groupId>org.eclipse.webtools.common</groupId>

+  <artifactId>org.eclipse.jst.common.fproj.enablement.jdt.sdk</artifactId>

+  <version>3.8.0-SNAPSHOT</version>

+  <packaging>eclipse-feature</packaging>

+</project>
\ No newline at end of file
diff --git a/features/org.eclipse.wst.common.fproj.feature.patch/.project b/features/org.eclipse.wst.common.fproj.feature.patch/.project
new file mode 100644
index 0000000..c95eb3e
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature.patch/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.wst.common.fproj.feature.patch</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.wst.common.fproj.feature.patch/build.properties b/features/org.eclipse.wst.common.fproj.feature.patch/build.properties
new file mode 100644
index 0000000..cb50260
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature.patch/build.properties
@@ -0,0 +1,5 @@
+bin.includes = feature.xml,\
+               license.html,\
+               feature.properties,\
+               epl-v10.html,\
+               eclipse_update_120.jpg
diff --git a/features/org.eclipse.wst.common.fproj.feature.patch/buildnotes_org.eclipse.wst.common.fproj.feature.patch.html b/features/org.eclipse.wst.common.fproj.feature.patch/buildnotes_org.eclipse.wst.common.fproj.feature.patch.html
new file mode 100644
index 0000000..4969102
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature.patch/buildnotes_org.eclipse.wst.common.fproj.feature.patch.html
@@ -0,0 +1,18 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="Build" content="Build">
+<title>WTP 3.3.1 Patches</title>
+</head>
+
+<body>
+
+<h1>WTP 3.3.1 Patches</h1>
+
+<h2>org.eclipse.wst.common.fproj.feature</h2>
+<p>Bug <a href='https://bugs.eclipse.org/364086'>364086</a>. EJB Project wizard doesn't show up and shows an error</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.wst.common.fproj.feature.patch/eclipse_update_120.jpg b/features/org.eclipse.wst.common.fproj.feature.patch/eclipse_update_120.jpg
new file mode 100644
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature.patch/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.wst.common.fproj.feature.patch/epl-v10.html b/features/org.eclipse.wst.common.fproj.feature.patch/epl-v10.html
new file mode 100644
index 0000000..ed4b196
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature.patch/epl-v10.html
@@ -0,0 +1,328 @@
+<html xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 9">
+<meta name=Originator content="Microsoft Word 9">
+<link rel=File-List
+href="./Eclipse%20EPL%202003_11_10%20Final_files/filelist.xml">
+<title>Eclipse Public License - Version 1.0</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+  <o:Revision>2</o:Revision>
+  <o:TotalTime>3</o:TotalTime>
+  <o:Created>2004-03-05T23:03:00Z</o:Created>
+  <o:LastSaved>2004-03-05T23:03:00Z</o:LastSaved>
+  <o:Pages>4</o:Pages>
+  <o:Words>1626</o:Words>
+  <o:Characters>9270</o:Characters>
+   <o:Lines>77</o:Lines>
+  <o:Paragraphs>18</o:Paragraphs>
+  <o:CharactersWithSpaces>11384</o:CharactersWithSpaces>
+  <o:Version>9.4402</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:WordDocument>
+  <w:TrackRevisions/>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+@font-face
+	{font-family:Tahoma;
+	panose-1:2 11 6 4 3 5 4 4 2 4;
+	mso-font-charset:0;
+	mso-generic-font-family:swiss;
+	mso-font-pitch:variable;
+	mso-font-signature:553679495 -2147483648 8 0 66047 0;}
+ /* Style Definitions */
+p.MsoNormal, li.MsoNormal, div.MsoNormal
+	{mso-style-parent:"";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p
+	{margin-right:0in;
+	mso-margin-top-alt:auto;
+	mso-margin-bottom-alt:auto;
+	margin-left:0in;
+	mso-pagination:widow-orphan;
+	font-size:12.0pt;
+	font-family:"Times New Roman";
+	mso-fareast-font-family:"Times New Roman";}
+p.BalloonText, li.BalloonText, div.BalloonText
+	{mso-style-name:"Balloon Text";
+	margin:0in;
+	margin-bottom:.0001pt;
+	mso-pagination:widow-orphan;
+	font-size:8.0pt;
+	font-family:Tahoma;
+	mso-fareast-font-family:"Times New Roman";}
+@page Section1
+	{size:8.5in 11.0in;
+	margin:1.0in 1.25in 1.0in 1.25in;
+	mso-header-margin:.5in;
+	mso-footer-margin:.5in;
+	mso-paper-source:0;}
+div.Section1
+	{page:Section1;}
+-->
+</style>
+</head>
+
+<body lang=EN-US style='tab-interval:.5in'>
+
+<div class=Section1>
+
+<p align=center style='text-align:center'><b>Eclipse Public License - v 1.0</b>
+</p>
+
+<p><span style='font-size:10.0pt'>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
+THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE,
+REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
+OF THIS AGREEMENT.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>1. DEFINITIONS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Contribution&quot; means:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+in the case of the initial Contributor, the initial code and documentation
+distributed under this Agreement, and<br clear=left>
+b) in the case of each subsequent Contributor:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+changes to the Program, and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+additions to the Program;</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>where
+such changes and/or additions to the Program originate from and are distributed
+by that particular Contributor. A Contribution 'originates' from a Contributor
+if it was added to the Program by such Contributor itself or anyone acting on
+such Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in conjunction
+with the Program under their own license agreement, and (ii) are not derivative
+works of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Contributor&quot; means any person or
+entity that distributes the Program.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Licensed Patents &quot; mean patent
+claims licensable by a Contributor which are necessarily infringed by the use
+or sale of its Contribution alone or when combined with the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>&quot;Program&quot; means the Contributions
+distributed in accordance with this Agreement.</span> </p>
+
+<p><span style='font-size:10.0pt'>&quot;Recipient&quot; means anyone who
+receives the Program under this Agreement, including all Contributors.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>2. GRANT OF RIGHTS</span></b> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+Subject to the terms of this Agreement, each Contributor hereby grants Recipient
+a non-exclusive, worldwide, royalty-free copyright license to<span
+style='color:red'> </span>reproduce, prepare derivative works of, publicly
+display, publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and object code
+form.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide,<span style='color:green'> </span>royalty-free
+patent license under Licensed Patents to make, use, sell, offer to sell, import
+and otherwise transfer the Contribution of such Contributor, if any, in source
+code and object code form. This patent license shall apply to the combination
+of the Contribution and the Program if, at the time the Contribution is added
+by the Contributor, such addition of the Contribution causes such combination
+to be covered by the Licensed Patents. The patent license shall not apply to
+any other combinations which include the Contribution. No hardware per se is
+licensed hereunder. </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>c)
+Recipient understands that although each Contributor grants the licenses to its
+Contributions set forth herein, no assurances are provided by any Contributor
+that the Program does not infringe the patent or other intellectual property
+rights of any other entity. Each Contributor disclaims any liability to Recipient
+for claims brought by any other entity based on infringement of intellectual
+property rights or otherwise. As a condition to exercising the rights and
+licenses granted hereunder, each Recipient hereby assumes sole responsibility
+to secure any other intellectual property rights needed, if any. For example,
+if a third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license before
+distributing the Program.</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>d)
+Each Contributor represents that to its knowledge it has sufficient copyright
+rights in its Contribution, if any, to grant the copyright license set forth in
+this Agreement. </span></p>
+
+<p><b><span style='font-size:10.0pt'>3. REQUIREMENTS</span></b> </p>
+
+<p><span style='font-size:10.0pt'>A Contributor may choose to distribute the
+Program in object code form under its own license agreement, provided that:</span>
+</p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it complies with the terms and conditions of this Agreement; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b)
+its license agreement:</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>i)
+effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>ii)
+effectively excludes on behalf of all Contributors all liability for damages,
+including direct, indirect, special, incidental and consequential damages, such
+as lost profits; </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iii)
+states that any provisions which differ from this Agreement are offered by that
+Contributor alone and not by any other party; and</span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>iv)
+states that source code for the Program is available from such Contributor, and
+informs licensees how to obtain it in a reasonable manner on or through a
+medium customarily used for software exchange.<span style='color:blue'> </span></span></p>
+
+<p><span style='font-size:10.0pt'>When the Program is made available in source
+code form:</span> </p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>a)
+it must be made available under this Agreement; and </span></p>
+
+<p class=MsoNormal style='margin-left:.5in'><span style='font-size:10.0pt'>b) a
+copy of this Agreement must be included with each copy of the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Contributors may not remove or alter any
+copyright notices contained within the Program. </span></p>
+
+<p><span style='font-size:10.0pt'>Each Contributor must identify itself as the
+originator of its Contribution, if any, in a manner that reasonably allows
+subsequent Recipients to identify the originator of the Contribution. </span></p>
+
+<p><b><span style='font-size:10.0pt'>4. COMMERCIAL DISTRIBUTION</span></b> </p>
+
+<p><span style='font-size:10.0pt'>Commercial distributors of software may
+accept certain responsibilities with respect to end users, business partners
+and the like. While this license is intended to facilitate the commercial use
+of the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes the
+Program in a commercial product offering, such Contributor (&quot;Commercial
+Contributor&quot;) hereby agrees to defend and indemnify every other
+Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and
+costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may participate
+in any such claim at its own expense.</span> </p>
+
+<p><span style='font-size:10.0pt'>For example, a Contributor might include the
+Program in a commercial product offering, Product X. That Contributor is then a
+Commercial Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance claims and
+warranties are such Commercial Contributor's responsibility alone. Under this
+section, the Commercial Contributor would have to defend claims against the
+other Contributors related to those performance claims and warranties, and if a
+court requires any other Contributor to pay any damages as a result, the
+Commercial Contributor must pay those damages.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>5. NO WARRANTY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; 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. Each Recipient is solely
+responsible for determining the appropriateness of using and distributing the
+Program and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations. </span></p>
+
+<p><b><span style='font-size:10.0pt'>6. DISCLAIMER OF LIABILITY</span></b> </p>
+
+<p><span style='font-size:10.0pt'>EXCEPT AS EXPRESSLY SET FORTH IN THIS
+AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF
+THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGES.</span> </p>
+
+<p><b><span style='font-size:10.0pt'>7. GENERAL</span></b> </p>
+
+<p><span style='font-size:10.0pt'>If any provision of this Agreement is invalid
+or unenforceable under applicable law, it shall not affect the validity or
+enforceability of the remainder of the terms of this Agreement, and without
+further action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.</span> </p>
+
+<p><span style='font-size:10.0pt'>If Recipient institutes patent litigation
+against any entity (including a cross-claim or counterclaim in a lawsuit)
+alleging that the Program itself (excluding combinations of the Program with
+other software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the date
+such litigation is filed. </span></p>
+
+<p><span style='font-size:10.0pt'>All Recipient's rights under this Agreement
+shall terminate if it fails to comply with any of the material terms or
+conditions of this Agreement and does not cure such failure in a reasonable
+period of time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive. </span></p>
+
+<p><span style='font-size:10.0pt'>Everyone is permitted to copy and distribute
+copies of this Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The Agreement
+Steward reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the initial
+Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.</span> </p>
+
+<p><span style='font-size:10.0pt'>This Agreement is governed by the laws of the
+State of New York and the intellectual property laws of the United States of
+America. No party to this Agreement will bring a legal action under this
+Agreement more than one year after the cause of action arose. Each party waives
+its rights to a jury trial in any resulting litigation.</span> </p>
+
+<p class=MsoNormal><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
+
+</div>
+
+</body>
+
+</html>
\ No newline at end of file
diff --git a/features/org.eclipse.wst.common.fproj.feature.patch/feature.properties b/features/org.eclipse.wst.common.fproj.feature.patch/feature.properties
new file mode 100644
index 0000000..7e62a5f
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature.patch/feature.properties
@@ -0,0 +1,147 @@
+###############################################################################
+# Copyright (c) 2007 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
+###############################################################################
+# 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=WTP Patch for org.eclipse.wst.common.fproj.feature
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "updateSiteName" property - label for the update site
+updateSiteName=The Eclipse Web Tools Platform (WTP) Project update site
+
+# "description" property - description of the feature
+description=\
+This patch feature fixes problems as described in following bugs:\n\
+Bug https://bugs.eclipse.org/364086 EJB Project wizard doesn't show up and shows an error\n\
+\n\
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2007 IBM Corporation 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\
+    IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+licenseURL=license.html
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+license=\
+ECLIPSE FOUNDATION SOFTWARE USER AGREEMENT\n\
+September 27, 2007\n\
+\n\
+Usage Of Content\n\
+\n\
+THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR\n\
+OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT").\n\
+USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS\n\
+AGREEMENT AND/OR THE TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR\n\
+NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU\n\
+AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED BY THIS AGREEMENT\n\
+AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS\n\
+OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS\n\
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\
+BELOW, THEN YOU MAY NOT USE THE CONTENT.\n\
+\n\
+Applicable Licenses\n\
+\n\
+Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\
+is provided to you under the terms and conditions of the Eclipse Public\n\
+License Version 1.0 ("EPL"). A copy of the EPL is provided with this\n\
+Content and is also available at http://www.eclipse.org/legal/epl-v10.html.\n\
+For purposes of the EPL, "Program" will mean the Content.\n\
+\n\
+Content includes, but is not limited to, source code, object code,\n\
+documentation and other files maintained in the Eclipse.org CVS\n\
+repository ("Repository") in CVS modules ("Modules") and made available\n\
+as downloadable archives ("Downloads").\n\
+\n\
+   - Content may be structured and packaged into modules to facilitate delivering,\n\
+     extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"),\n\
+     plug-in fragments ("Fragments"), and features ("Features").\n\
+   - Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java? ARchive)\n\
+     in a directory named "plugins".\n\
+   - A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.\n\
+     Each Feature may be packaged as a sub-directory in a directory named "features".\n\
+     Within a Feature, files named "feature.xml" may contain a list of the names and version\n\
+     numbers of the Plug-ins and/or Fragments associated with that Feature.\n\
+   - Features may also include other Features ("Included Features"). Within a Feature, files\n\
+     named "feature.xml" may contain a list of the names and version numbers of Included Features.\n\
+\n\
+Features may also include other Features ("Included Features"). Files named\n\
+"feature.xml" may contain a list of the names and version numbers of\n\
+Included Features.\n\
+\n\
+The terms and conditions governing Plug-ins and Fragments should be\n\
+contained in files named "about.html" ("Abouts"). The terms and\n\
+conditions governing Features and Included Features should be contained\n\
+in files named "license.html" ("Feature Licenses"). Abouts and Feature\n\
+Licenses may be located in any directory of a Download or Module\n\
+including, but not limited to the following locations:\n\
+\n\
+   - The top-level (root) directory\n\
+   - Plug-in and Fragment directories\n\
+   - Inside Plug-ins and Fragments packaged as JARs\n\
+   - Sub-directories of the directory named "src" of certain Plug-ins\n\
+   - Feature directories\n\
+\n\
+Note: if a Feature made available by the Eclipse Foundation is installed using the\n\
+Eclipse Update Manager, you must agree to a license ("Feature Update\n\
+License") during the installation process. If the Feature contains\n\
+Included Features, the Feature Update License should either provide you\n\
+with the terms and conditions governing the Included Features or inform\n\
+you where you can locate them. Feature Update Licenses may be found in\n\
+the "license" property of files named "feature.properties". Such Abouts,\n\
+Feature Licenses and Feature Update Licenses contain the terms and\n\
+conditions (or references to such terms and conditions) that govern your\n\
+use of the associated Content in that directory.\n\
+\n\
+THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER\n\
+TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.\n\
+SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\
+\n\
+    - Common Public License Version 1.0 (available at http://www.eclipse.org/legal/cpl-v10.html)\n\
+    - Apache Software License 1.1 (available at http://www.apache.org/licenses/LICENSE)\n\
+    - Apache Software License 2.0 (available at http://www.apache.org/licenses/LICENSE-2.0)\n\
+    - IBM Public License 1.0 (available at http://oss.software.ibm.com/developerworks/opensource/license10.html)\n\
+    - Metro Link Public License 1.00 (available at http://www.opengroup.org/openmotif/supporters/metrolink/license.html)\n\
+    - Mozilla Public License Version 1.1 (available at http://www.mozilla.org/MPL/MPL-1.1.html)\n\
+\n\
+IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR\n\
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License\n\
+is provided, please contact the Eclipse Foundation to determine what terms and conditions\n\
+govern that particular Content.\n\
+\n\
+Cryptography\n\
+\n\
+Content may contain encryption software. The country in which you are\n\
+currently may have restrictions on the import, possession, and use,\n\
+and/or re-export to another country, of encryption software. BEFORE\n\
+using any encryption software, please check the country's laws,\n\
+regulations and policies concerning the import, possession, or use,\n\
+and re-export of encryption software, to see if this is permitted.\n\
+\n\
+Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.\n
+########### end of license property ##########################################
diff --git a/features/org.eclipse.wst.common.fproj.feature.patch/feature.xml b/features/org.eclipse.wst.common.fproj.feature.patch/feature.xml
new file mode 100644
index 0000000..6297c04
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature.patch/feature.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.wst.common.fproj.feature.patch"
+      label="%featureName"
+      version="3.3.1.qualifier"
+      provider-name="%providerName">
+
+    <description>%description</description>
+
+    <copyright>%copyright</copyright>
+
+    <license url="%licenseURL">%license</license>
+
+   <requires>
+      <import feature="org.eclipse.wst.common.fproj" version="3.3.0.v201102150115-377DF8s7355397B4B9B " patch="true"/>
+   </requires>
+
+   <plugin
+         id="org.eclipse.wst.common.project.facet.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.wst.common.fproj.feature.patch/license.html b/features/org.eclipse.wst.common.fproj.feature.patch/license.html
new file mode 100644
index 0000000..2347060
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature.patch/license.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
+<!-- saved from url=(0044)http://www.eclipse.org/legal/epl/notice.html -->
+<HTML><HEAD><TITLE>Eclipse.org Software User Agreement</TITLE>
+<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<META content="MSHTML 6.00.2800.1479" name=GENERATOR></HEAD>
+<BODY lang=EN-US vLink=purple link=blue>
+<H2>Eclipse Foundation Software User Agreement</H2>
+<P>January 28, 2005</P>
+<H3>Usage Of Content</H3>
+<P>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION 
+AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF 
+THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE 
+TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED 
+BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED 
+BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE 
+AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE 
+TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY 
+APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU 
+MAY NOT USE THE CONTENT.</P>
+<H3>Applicable Licenses</H3>
+<P>Unless otherwise indicated, all Content made available by the Eclipse 
+Foundation is provided to you under the terms and conditions of the Eclipse 
+Public License Version 1.0 ("EPL"). A copy of the EPL is provided with this 
+Content and is also 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, "Program" will mean the Content.</P>
+<P>Content includes, but is not limited to, source code, object code, 
+documentation and other files maintained in the Eclipse.org CVS repository 
+("Repository") in CVS modules ("Modules") and made available as downloadable 
+archives ("Downloads").</P>
+<P>Content may be apportioned into plug-ins ("Plug-ins"), plug-in fragments 
+("Fragments"), and features ("Features"). A Feature is a bundle of one or more 
+Plug-ins and/or Fragments and associated material. Files named "feature.xml" may 
+contain a list of the names and version numbers of the Plug-ins and/or Fragments 
+associated with a Feature. Plug-ins and Fragments are located in directories 
+named "plugins" and Features are located in directories named "features".</P>
+<P>Features may also include other Features ("Included Features"). Files named 
+"feature.xml" may contain a list of the names and version numbers of Included 
+Features.</P>
+<P>The terms and conditions governing Plug-ins and Fragments should be contained 
+in files named "about.html" ("Abouts"). The terms and conditions governing 
+Features and Included Features should be contained in files named "license.html" 
+("Feature Licenses"). Abouts and Feature Licenses may be located in any 
+directory of a Download or Module including, but not limited to the following 
+locations:</P>
+<UL>
+  <LI>The top-level (root) directory 
+  <LI>Plug-in and Fragment directories 
+  <LI>Subdirectories of the directory named "src" of certain Plug-ins 
+  <LI>Feature directories </LI></UL>
+<P>Note: if a Feature made available by the Eclipse Foundation is installed 
+using the Eclipse Update Manager, you must agree to a license ("Feature Update 
+License") during the installation process. If the Feature contains Included 
+Features, the Feature Update License should either provide you with the terms 
+and conditions governing the Included Features or inform you where you can 
+locate them. Feature Update Licenses may be found in the "license" property of 
+files named "feature.properties". Such Abouts, Feature Licenses and Feature 
+Update Licenses contain the terms and conditions (or references to such terms 
+and conditions) that govern your use of the associated Content in that 
+directory.</P>
+<P>THE ABOUTS, FEATURE LICENSES AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL 
+OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE 
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</P>
+<UL>
+  <LI>Common Public License Version 1.0 (available at <A 
+  href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</A>) 
+
+  <LI>Apache Software License 1.1 (available at <A 
+  href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</A>) 
+
+  <LI>Apache Software License 2.0 (available at <A 
+  href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</A>) 
+
+  <LI>IBM Public License 1.0 (available at <A 
+  href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</A>) 
+
+  <LI>Metro Link Public License 1.00 (available at <A 
+  href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</A>) 
+
+  <LI>Mozilla Public License Version 1.1 (available at <A 
+  href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</A>) 
+  </LI></UL>
+<P>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR 
+TO USE OF THE CONTENT. If no About, Feature License or Feature Update License is 
+provided, please contact the Eclipse Foundation to determine what terms and 
+conditions govern that particular Content.</P>
+<H3>Cryptography</H3>
+<P>Content may contain encryption software. The country in which you are 
+currently may have restrictions on the import, possession, and use, and/or 
+re-export to another country, of encryption software. BEFORE using any 
+encryption software, please check the country's laws, regulations and policies 
+concerning the import, possession, or use, and re-export of encryption software, 
+to see if this is permitted.</P></BODY></HTML>
diff --git a/features/org.eclipse.wst.common.fproj.feature.patch/pom.xml b/features/org.eclipse.wst.common.fproj.feature.patch/pom.xml
new file mode 100644
index 0000000..00e218a
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature.patch/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright (c) 2012, 2013 Eclipse Foundation and others.

+  All rights reserved. This program and the accompanying materials

+  are made available under the terms of the Eclipse Distribution License v1.0

+  which accompanies this distribution, and is available at

+  http://www.eclipse.org/org/documents/edl-v10.php

+ 

+  Contributors:

+    Thanh Ha (Eclipse Foundation) - initial implementation

+-->

+

+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"

+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

+  <modelVersion>4.0.0</modelVersion>

+  <parent>

+    <groupId>org.eclipse.webtools.common</groupId>

+    <artifactId>org.eclipse.webtools.common.fproj</artifactId>

+    <version>3.6.0-SNAPSHOT</version>

+    <relativePath>../../</relativePath>

+  </parent>

+

+  <groupId>org.eclipse.webtools.common</groupId>

+  <artifactId>org.eclipse.wst.common.fproj.feature.patch</artifactId>

+  <version>3.3.1-SNAPSHOT</version>

+  <packaging>eclipse-feature</packaging>

+</project>
\ No newline at end of file
diff --git a/features/org.eclipse.wst.common.fproj.feature/.project b/features/org.eclipse.wst.common.fproj.feature/.project
new file mode 100644
index 0000000..a234f5f
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.wst.common.fproj.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.wst.common.fproj.feature/build.properties b/features/org.eclipse.wst.common.fproj.feature/build.properties
new file mode 100644
index 0000000..3e69ba2
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature/build.properties
@@ -0,0 +1,4 @@
+bin.includes = feature.xml,\
+               eclipse_update_120.jpg,\
+               feature.properties
+
diff --git a/features/org.eclipse.wst.common.fproj.feature/eclipse_update_120.jpg b/features/org.eclipse.wst.common.fproj.feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.wst.common.fproj.feature/feature.properties b/features/org.eclipse.wst.common.fproj.feature/feature.properties
new file mode 100644
index 0000000..b8ac3d2
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature/feature.properties
@@ -0,0 +1,31 @@
+# "featureName" property - name of the feature
+featureName=Eclipse Faceted Project Framework
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse Web Tools Platform
+
+
+# "description" property - description of the feature
+description=The Faceted Project Framework allows the plugin developer to think of projects \n\
+as composed of units of functionality, otherwise known as facets, that can be added and removed \n\
+by the user.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2009 Oracle 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
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+# license and licenseURL properties were removed as a result to migrating to new PDE license support. 
+#    Those properties are now added at build time. See http://wiki.eclipse.org/Equinox/p2/License_Mechanism. 
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+# license and licenseURL properties were removed as a result to migrating to new PDE license support. 
+#    Those properties are now added at build time. See http://wiki.eclipse.org/Equinox/p2/License_Mechanism. 
+########### end of license property ##########################################
diff --git a/features/org.eclipse.wst.common.fproj.feature/feature.xml b/features/org.eclipse.wst.common.fproj.feature/feature.xml
new file mode 100644
index 0000000..48fd7e0
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature/feature.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature

+      id="org.eclipse.wst.common.fproj"

+      label="%featureName"

+      version="3.7.0.qualifier"

+      provider-name="%providerName"

+      plugin="org.eclipse.wst.common.project.facet.core"

+      license-feature="org.eclipse.license"

+      license-feature-version="1.0.1.qualifier">

+

+   <description>

+      %description

+   </description>

+

+   <copyright>

+      %copyright

+   </copyright>

+

+   <license url="%licenseURL">

+      %license

+   </license>

+

+   <plugin

+         id="org.eclipse.wst.common.project.facet.core"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+   <plugin

+         id="org.eclipse.wst.common.project.facet.ui"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+</feature>

diff --git a/features/org.eclipse.wst.common.fproj.feature/pom.xml b/features/org.eclipse.wst.common.fproj.feature/pom.xml
new file mode 100644
index 0000000..7a465a1
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright (c) 2012, 2013 Eclipse Foundation and others.

+  All rights reserved. This program and the accompanying materials

+  are made available under the terms of the Eclipse Distribution License v1.0

+  which accompanies this distribution, and is available at

+  http://www.eclipse.org/org/documents/edl-v10.php

+ 

+  Contributors:

+    Thanh Ha (Eclipse Foundation) - initial implementation

+-->

+

+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"

+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

+  <modelVersion>4.0.0</modelVersion>

+  <parent>

+    <groupId>org.eclipse.webtools.common</groupId>

+    <artifactId>org.eclipse.webtools.common.fproj</artifactId>

+    <version>3.6.0-SNAPSHOT</version>

+    <relativePath>../../</relativePath>

+  </parent>

+

+  <groupId>org.eclipse.webtools.common</groupId>

+  <artifactId>org.eclipse.wst.common.fproj</artifactId>

+  <version>3.7.0-SNAPSHOT</version>

+  <packaging>eclipse-feature</packaging>

+</project>
\ No newline at end of file
diff --git a/features/org.eclipse.wst.common.fproj.feature/sourceTemplateBundle/about.html b/features/org.eclipse.wst.common.fproj.feature/sourceTemplateBundle/about.html
new file mode 100644
index 0000000..fe81d46
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature/sourceTemplateBundle/about.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<P>June, 2008</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.</p>
+
+<h3>Source Code</h3>
+<p>This plug-in contains source code zip files (&quot;Source Zips&quot;) that correspond to binary content in other plug-ins. These Source Zips may be distributed under different license
+agreements and/or notices. Details about these license agreements and notices are contained in &quot;about.html&quot; files (&quot;Abouts&quot;) located in sub-directories in the
+src/ directory of this plug-in. Such Abouts govern your use of the Source Zips in that directory, not the EPL.</p>
+
+</body>
+</html>
diff --git a/features/org.eclipse.wst.common.fproj.feature/sourceTemplateBundle/build.properties b/features/org.eclipse.wst.common.fproj.feature/sourceTemplateBundle/build.properties
new file mode 100644
index 0000000..2c2c169
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.feature/sourceTemplateBundle/build.properties
@@ -0,0 +1,2 @@
+bin.includes = about.html
+src.includes = about.html
\ No newline at end of file
diff --git a/features/org.eclipse.wst.common.fproj.sdk.feature/.project b/features/org.eclipse.wst.common.fproj.sdk.feature/.project
new file mode 100644
index 0000000..4a54077
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.sdk.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.wst.common.fproj.sdk.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.wst.common.fproj.sdk.feature/build.properties b/features/org.eclipse.wst.common.fproj.sdk.feature/build.properties
new file mode 100644
index 0000000..ecd6544
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.sdk.feature/build.properties
@@ -0,0 +1,6 @@
+bin.includes = feature.xml,\
+               eclipse_update_120.jpg,\
+               feature.properties
+
+generate.plugin@org.eclipse.wst.common.project.facet.core.source=org.eclipse.wst.common.project.facet.core
+generate.plugin@org.eclipse.wst.common.project.facet.ui.source=org.eclipse.wst.common.project.facet.ui
diff --git a/features/org.eclipse.wst.common.fproj.sdk.feature/eclipse_update_120.jpg b/features/org.eclipse.wst.common.fproj.sdk.feature/eclipse_update_120.jpg
new file mode 100644
index 0000000..bfdf708
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.sdk.feature/eclipse_update_120.jpg
Binary files differ
diff --git a/features/org.eclipse.wst.common.fproj.sdk.feature/feature.properties b/features/org.eclipse.wst.common.fproj.sdk.feature/feature.properties
new file mode 100644
index 0000000..7fab8d0
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.sdk.feature/feature.properties
@@ -0,0 +1,31 @@
+# "featureName" property - name of the feature
+featureName=Eclipse Faceted Project Framework SDK
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse Web Tools Platform
+
+
+# "description" property - description of the feature
+description=The Faceted Project Framework allows the plugin developer to think of projects \n\
+as composed of units of functionality, otherwise known as facets, that can be added and removed \n\
+by the user.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2009 Oracle 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
+################ end of copyright property ####################################
+
+# "licenseURL" property - URL of the "Feature License"
+# do not translate value - just change to point to a locale-specific HTML page
+# license and licenseURL properties were removed as a result to migrating to new PDE license support. 
+#    Those properties are now added at build time. See http://wiki.eclipse.org/Equinox/p2/License_Mechanism. 
+
+# "license" property - text of the "Feature Update License"
+# should be plain text version of license agreement pointed to be "licenseURL"
+# license and licenseURL properties were removed as a result to migrating to new PDE license support. 
+#    Those properties are now added at build time. See http://wiki.eclipse.org/Equinox/p2/License_Mechanism. 
+########### end of license property ##########################################
diff --git a/features/org.eclipse.wst.common.fproj.sdk.feature/feature.xml b/features/org.eclipse.wst.common.fproj.sdk.feature/feature.xml
new file mode 100644
index 0000000..a92e614
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.sdk.feature/feature.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<feature

+      id="org.eclipse.wst.common.fproj.sdk"

+      label="%featureName"

+      version="3.7.0.qualifier"

+      provider-name="%providerName"

+      plugin="org.eclipse.wst.common.fproj.sdk"

+      license-feature="org.eclipse.license"

+      license-feature-version="1.0.1.qualifier">

+

+   <description>

+      %description

+   </description>

+

+   <copyright>

+      %copyright

+   </copyright>

+

+   <license url="license.html">

+      %license

+   </license>

+

+   <includes

+         id="org.eclipse.wst.common.fproj"

+         version="0.0.0"/>

+

+   <plugin

+         id="org.eclipse.wst.common.project.facet.core.source"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+   <plugin

+         id="org.eclipse.wst.common.project.facet.ui.source"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+   <plugin

+         id="org.eclipse.wst.common.project.facet.doc.api"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+   <plugin

+         id="org.eclipse.wst.common.fproj.sdk"

+         download-size="0"

+         install-size="0"

+         version="0.0.0"

+         unpack="false"/>

+

+</feature>

diff --git a/features/org.eclipse.wst.common.fproj.sdk.feature/pom.xml b/features/org.eclipse.wst.common.fproj.sdk.feature/pom.xml
new file mode 100644
index 0000000..9d20e24
--- /dev/null
+++ b/features/org.eclipse.wst.common.fproj.sdk.feature/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright (c) 2012, 2013 Eclipse Foundation and others.

+  All rights reserved. This program and the accompanying materials

+  are made available under the terms of the Eclipse Distribution License v1.0

+  which accompanies this distribution, and is available at

+  http://www.eclipse.org/org/documents/edl-v10.php

+ 

+  Contributors:

+    Thanh Ha (Eclipse Foundation) - initial implementation

+-->

+

+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"

+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

+  <modelVersion>4.0.0</modelVersion>

+  <parent>

+    <groupId>org.eclipse.webtools.common</groupId>

+    <artifactId>org.eclipse.webtools.common.fproj</artifactId>

+    <version>3.6.0-SNAPSHOT</version>

+    <relativePath>../../</relativePath>

+  </parent>

+

+  <groupId>org.eclipse.webtools.common</groupId>

+  <artifactId>org.eclipse.wst.common.fproj.sdk</artifactId>

+  <version>3.7.0-SNAPSHOT</version>

+  <packaging>eclipse-feature</packaging>

+</project>
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/.classpath b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/.classpath
new file mode 100644
index 0000000..304e861
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/.project b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/.project
new file mode 100644
index 0000000..a38058c
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jst.common.fproj.enablement.jdt.sdk</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>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..bcc26d6
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,57 @@
+#Wed Jan 31 15:32:12 PST 2007
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+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.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+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.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.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+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.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+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.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=error
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+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.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/META-INF/MANIFEST.MF b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..91fe524
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/META-INF/MANIFEST.MF
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Vendor: %providerName
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.jst.common.fproj.enablement.jdt.sdk; singleton:=true
+Bundle-Version: 1.4.200.qualifier
+Bundle-ClassPath: .
+Bundle-Localization: plugin
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/about.html b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/about.html
new file mode 100644
index 0000000..2199df3
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/about.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+
+<BODY lang="EN-US">
+
+<H3>About This Content</H3>
+
+<P>June, 2008</P>
+
+<H3>License</H3>
+
+<P>The Eclipse Foundation makes available all content in this plug-in 
+("Content"). Unless otherwise indicated below, the Content is provided to you 
+under the terms and conditions of the Eclipse Public License Version 1.0 
+("EPL"). A copy of the EPL is available at
+<A href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</A>. 
+For purposes of the EPL, "Program" 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 ("Redistributor") 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/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/about.ini b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/about.ini
new file mode 100644
index 0000000..8949d8a
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/about.ini
@@ -0,0 +1,2 @@
+aboutText=%blurb
+featureImage=images/wtp-32.png
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/about.properties b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/about.properties
new file mode 100644
index 0000000..bcc0b6a
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/about.properties
@@ -0,0 +1,9 @@
+blurb=Eclipse Faceted Project Framework JDT Enablement SDK\n\
+\n\
+Version: {featureVersion}\n\
+\n\
+The Faceted Project Framework allows the plugin developer to think of projects \n\
+as composed of units of functionality, otherwise known as facets, that can be \n\
+added and removed by the user.\n\
+\n\
+Copyright (c) 2009 Eclipse contributors and others. All rights reserved.
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/build.properties b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/build.properties
new file mode 100644
index 0000000..5237c90
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/build.properties
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = bin/
+bin.includes = .,\
+               META-INF/,\
+               plugin.properties,\
+               about.html,\
+               images/,\
+               about.ini,\
+               about.properties
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/images/wtp-32.png b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/images/wtp-32.png
new file mode 100644
index 0000000..6f09c2a
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/images/wtp-32.png
Binary files differ
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/plugin.properties b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/plugin.properties
new file mode 100644
index 0000000..632a4c2
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/plugin.properties
@@ -0,0 +1,2 @@
+pluginName = Eclipse Faceted Project Framework JDT Enablement SDK
+providerName = Eclipse Web Tools Platform
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/pom.xml b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/pom.xml
new file mode 100644
index 0000000..6c2d085
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright (c) 2012, 2013 Eclipse Foundation and others.

+  All rights reserved. This program and the accompanying materials

+  are made available under the terms of the Eclipse Distribution License v1.0

+  which accompanies this distribution, and is available at

+  http://www.eclipse.org/org/documents/edl-v10.php

+ 

+  Contributors:

+    Thanh Ha (Eclipse Foundation) - initial implementation

+-->

+

+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"

+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

+  <modelVersion>4.0.0</modelVersion>

+  <parent>

+    <groupId>org.eclipse.webtools.common</groupId>

+    <artifactId>org.eclipse.webtools.common.fproj</artifactId>

+    <version>3.6.0-SNAPSHOT</version>

+    <relativePath>../../</relativePath>

+  </parent>

+

+  <groupId>org.eclipse.webtools.common</groupId>

+  <artifactId>org.eclipse.jst.common.fproj.enablement.jdt.sdk</artifactId>

+  <version>1.4.200-SNAPSHOT</version>

+  <packaging>eclipse-plugin</packaging>

+</project>
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/src/.do-not-delete b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/src/.do-not-delete
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.fproj.enablement.jdt.sdk/src/.do-not-delete
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/.classpath b/plugins/org.eclipse.jst.common.project.facet.core/.classpath
new file mode 100644
index 0000000..304e861
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/.cvsignore b/plugins/org.eclipse.jst.common.project.facet.core/.cvsignore
new file mode 100644
index 0000000..0f57cf1
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/.cvsignore
@@ -0,0 +1,6 @@
+bin
+@dot
+build.xml
+temp.folder
+src.zip
+javaCompiler...args
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/.project b/plugins/org.eclipse.jst.common.project.facet.core/.project
new file mode 100644
index 0000000..29c97ae
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jst.common.project.facet.core</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.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/.settings/.api_filters b/plugins/org.eclipse.jst.common.project.facet.core/.settings/.api_filters
new file mode 100644
index 0000000..e266422
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/.settings/.api_filters
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jst.common.project.facet.core" version="2">
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetValidator.java" type="org.eclipse.jst.common.project.facet.core.internal.JavaFacetValidator">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.JavaFacetValidator"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/FacetCorePlugin.java" type="org.eclipse.jst.common.project.facet.core.internal.FacetCorePlugin">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.FacetCorePlugin"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/FacetedProjectFrameworkJavaPlugin.java" type="org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetInstallDelegate.java" type="org.eclipse.jst.common.project.facet.core.internal.JavaFacetInstallDelegate">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.JavaFacetInstallDelegate"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetRuntimeChangedListener.java" type="org.eclipse.jst.common.project.facet.core.internal.JavaFacetRuntimeChangedListener">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.JavaFacetRuntimeChangedListener"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetVersionChangeDelegate.java" type="org.eclipse.jst.common.project.facet.core.internal.JavaFacetVersionChangeDelegate">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.JavaFacetVersionChangeDelegate"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/JavaRuntimeBridge.java" type="org.eclipse.jst.common.project.facet.core.internal.JavaRuntimeBridge">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.JavaRuntimeBridge"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/StandardJreClasspathProvider.java" type="org.eclipse.jst.common.project.facet.core.internal.StandardJreClasspathProvider">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.StandardJreClasspathProvider"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUtil.java" type="org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/RuntimeClasspathProvider.java" type="org.eclipse.jst.common.project.facet.core.internal.RuntimeClasspathProvider">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.RuntimeClasspathProvider"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetInstallConfigFactory.java" type="org.eclipse.jst.common.project.facet.core.internal.JavaFacetInstallConfigFactory">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.JavaFacetInstallConfigFactory"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDefaultVersionProvider.java" type="org.eclipse.jst.common.project.facet.core.internal.JavaFacetDefaultVersionProvider">
+        <filter id="305365105">
+            <message_arguments>
+                <message_argument value="org.eclipse.jst.common.project.facet.core.internal.JavaFacetDefaultVersionProvider"/>
+                <message_argument value="org.eclipse.jst.common.project.facet.core_1.4.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+</component>
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.jst.common.project.facet.core/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..bd20e56
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Sun Apr 16 17:56:05 EDT 2006
+eclipse.preferences.version=1
+encoding/<project>=ISO-8859-1
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.jst.common.project.facet.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..eb5358d
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,78 @@
+#Mon Jan 24 08:45:15 PST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+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=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+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.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=ignore
+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.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+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.nullReference=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=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=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.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=error
+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=ignore
+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.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/.settings/org.eclipse.pde.prefs b/plugins/org.eclipse.jst.common.project.facet.core/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..4a66d5a
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,13 @@
+#Sun Apr 16 17:55:02 EDT 2006
+compilers.p.build=0
+compilers.p.deprecated=0
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=0
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.jst.common.project.facet.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2811f14
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Vendor: %providerName
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.jst.common.project.facet.core; singleton:=true
+Bundle-Version: 1.4.500.qualifier
+Bundle-ClassPath: .
+Bundle-Localization: plugin
+Export-Package: org.eclipse.jst.common.project.facet.core,
+ org.eclipse.jst.common.project.facet.core.internal;x-internal:=true,
+ org.eclipse.jst.common.project.facet.core.libprov,
+ org.eclipse.jst.common.project.facet.core.libprov.internal;x-friends:="org.eclipse.jst.common.project.facet.ui",
+ org.eclipse.jst.common.project.facet.core.libprov.osgi,
+ org.eclipse.jst.common.project.facet.core.libprov.user,
+ org.eclipse.jst.common.project.facet.core.libprov.user.internal;x-friends:="org.eclipse.jst.common.project.facet.ui"
+Require-Bundle: org.eclipse.core.resources;bundle-version="[3.2.0,4.0)",
+ org.eclipse.core.runtime;bundle-version="[3.2.0,4.0)",
+ org.eclipse.jdt.core;bundle-version="[3.2.0,4.0)",
+ org.eclipse.wst.common.project.facet.core;bundle-version="[1.3.0,2.0.0)",
+ org.eclipse.jdt.launching;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)",
+ org.eclipse.core.net;bundle-version="[1.2.0,2.0.0)",
+ org.eclipse.core.filesystem;bundle-version="[1.3.0,2.0.0)"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-Activator: org.eclipse.jst.common.project.facet.core.internal.FacetCorePlugin
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/about.html b/plugins/org.eclipse.jst.common.project.facet.core/about.html
new file mode 100644
index 0000000..2199df3
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/about.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<HTML>
+
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+
+<BODY lang="EN-US">
+
+<H3>About This Content</H3>
+
+<P>June, 2008</P>
+
+<H3>License</H3>
+
+<P>The Eclipse Foundation makes available all content in this plug-in 
+("Content"). Unless otherwise indicated below, the Content is provided to you 
+under the terms and conditions of the Eclipse Public License Version 1.0 
+("EPL"). A copy of the EPL is available at
+<A href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</A>. 
+For purposes of the EPL, "Program" 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 ("Redistributor") 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/plugins/org.eclipse.jst.common.project.facet.core/about.ini b/plugins/org.eclipse.jst.common.project.facet.core/about.ini
new file mode 100644
index 0000000..8949d8a
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/about.ini
@@ -0,0 +1,2 @@
+aboutText=%blurb
+featureImage=images/wtp-32.png
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/about.properties b/plugins/org.eclipse.jst.common.project.facet.core/about.properties
new file mode 100644
index 0000000..8e6dd91
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/about.properties
@@ -0,0 +1,9 @@
+blurb=Eclipse Faceted Project Framework JDT Enablement\n\
+\n\
+Version: {featureVersion}\n\
+\n\
+The Faceted Project Framework allows the plugin developer to think of projects \n\
+as composed of units of functionality, otherwise known as facets, that can be \n\
+added and removed by the user.\n\
+\n\
+Copyright (c) 2010 Eclipse contributors and others. All rights reserved.
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/build.properties b/plugins/org.eclipse.jst.common.project.facet.core/build.properties
new file mode 100644
index 0000000..18151cb
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/build.properties
@@ -0,0 +1,12 @@
+source.. = src/
+output.. = bin/
+bin.includes = .,\
+               plugin.xml,\
+               META-INF/,\
+               plugin.properties,\
+               about.html,\
+               about.ini,\
+               about.properties,\
+               images/,\
+               schemas/
+src.includes = about.html
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/images/wtp-32.png b/plugins/org.eclipse.jst.common.project.facet.core/images/wtp-32.png
new file mode 100644
index 0000000..6f09c2a
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/images/wtp-32.png
Binary files differ
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/plugin.properties b/plugins/org.eclipse.jst.common.project.facet.core/plugin.properties
new file mode 100644
index 0000000..6911393
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/plugin.properties
@@ -0,0 +1,16 @@
+pluginName = Eclipse Faceted Project Framework JDT Enablement
+providerName = Eclipse Web Tools Platform
+javaFacetLabel = Java
+javaFacetDescription = Adds support for writing applications using Java programming language.
+javaVersionMismatchMarkerName = Faceted Project Problem (Java Version Mismatch)
+libraryProvidersExtensionPointName = Library Providers Extension Point
+legacyLibraryProviderDetectorsExtensionPointName = Legacy Library Provider Detectors Extension Point
+downloadableLibrariesExtensionPointName = Downloadable Libraries Extension Point
+userLibraryProviderLabel = User Library
+runtimeLibraryProviderLabel = Library Provided by Target Runtime
+runtimeLibraryProviderMessage = The targeted runtime is able to provide the library required by this facet. Selecting this option will configure the project to use that library.
+unknownLibraryProviderLabel = Unknown Library Configuration
+unknownLibraryProviderMessage = Could not determine the library that this project facet is configured to use. This could be due to plugins that are missing or could not be activated. Changing facet library in this state can leave metadata and other files in the project that will need to be cleaned up manually.
+legacyLibraryProviderLabel = Legacy Library Configuration
+legacyLibraryProviderMessage = This project is currently configured to use a legacy method for configuring libraries. Switch to one of the other available library types when it is no longer necessary to open this project in previous versions of Eclipse.
+noOpLibraryProviderLabel = Disable Library Configuration
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/plugin.xml b/plugins/org.eclipse.jst.common.project.facet.core/plugin.xml
new file mode 100644
index 0000000..559a733
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/plugin.xml
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<plugin>
+
+  <extension point="org.eclipse.core.runtime.adapters">
+    <factory 
+      class="org.eclipse.jst.common.project.facet.core.internal.RuntimeClasspathProvider$Factory" 
+      adaptableType="org.eclipse.wst.common.project.facet.core.runtime.IRuntime">
+      <adapter type="org.eclipse.jst.common.project.facet.core.IClasspathProvider"/>
+    </factory>
+  </extension>
+
+  <extension point="org.eclipse.wst.common.project.facet.core.runtimeBridges">
+    <bridge
+      id="org.eclipse.jst.common.project.facet.core.JavaRuntimeBridge"
+      class="org.eclipse.jst.common.project.facet.core.internal.JavaRuntimeBridge"/>
+  </extension>
+  
+  <extension point="org.eclipse.wst.common.project.facet.core.runtimes">
+  
+    <runtime-component-type id="standard.jre"/>
+    <runtime-component-version type="standard.jre" version="1.3"/>
+    <runtime-component-version type="standard.jre" version="1.4"/>
+    <runtime-component-version type="standard.jre" version="1.5"/>
+    <runtime-component-version type="standard.jre" version="1.6"/>
+    <runtime-component-version type="standard.jre" version="1.7"/>
+    <runtime-component-version type="standard.jre" version="1.8"/>
+
+    <supported>
+      <facet id="java" version="1.3"/>
+      <runtime-component id="standard.jre" version="[1.3"/>
+    </supported>
+
+    <supported>
+      <facet id="java" version="1.4"/>
+      <runtime-component id="standard.jre" version="[1.4"/>
+    </supported>
+
+    <supported>
+      <facet id="java" version="1.5"/>
+      <runtime-component id="standard.jre" version="[1.5"/>
+    </supported>
+
+    <supported>
+      <facet id="java" version="1.6"/>
+      <runtime-component id="standard.jre" version="[1.6"/>
+    </supported>
+    
+    <supported>
+      <facet id="java" version="1.7"/>
+      <runtime-component id="standard.jre" version="[1.7"/>
+    </supported>
+
+    <supported>
+      <facet id="java" version="1.8"/>
+      <runtime-component id="standard.jre" version="[1.8"/>
+    </supported>
+
+    <adapter>
+      <runtime-component id="standard.jre"/>
+      <factory class="org.eclipse.jst.common.project.facet.core.internal.StandardJreClasspathProvider$Factory"/>
+      <type class="org.eclipse.jst.common.project.facet.core.IClasspathProvider"/>
+    </adapter>
+
+  </extension>
+
+  <extension point="org.eclipse.wst.common.project.facet.core.facets">
+  
+    <project-facet id="java">
+      <label>%javaFacetLabel</label>
+      <description>%javaFacetDescription</description>
+      <default-version provider="org.eclipse.jst.common.project.facet.core.internal.JavaFacetDefaultVersionProvider"/>
+    </project-facet>
+
+    <project-facet-version facet="java" version="1.3"/>
+
+    <project-facet-version facet="java" version="1.4"/>
+
+    <project-facet-version facet="java" version="1.5"/>
+
+    <project-facet-version facet="java" version="1.6"/>
+
+    <project-facet-version facet="java" version="1.7"/>
+
+    <project-facet-version facet="java" version="1.8"/>
+
+    <action facet="java" type="install" id="java.install">
+      <delegate class="org.eclipse.jst.common.project.facet.core.internal.JavaFacetInstallDelegate"/>
+      <config-factory class="org.eclipse.jst.common.project.facet.core.internal.JavaFacetInstallConfigFactory"/>
+    </action>
+
+    <action facet="java" type="uninstall">
+      <delegate class="org.eclipse.jst.common.project.facet.core.internal.JavaFacetUninstallDelegate"/>
+      <config-factory class="org.eclipse.jst.common.project.facet.core.internal.JavaFacetUninstallConfigFactory"/>
+    </action>
+
+    <action facet="java" type="version-change">
+      <delegate class="org.eclipse.jst.common.project.facet.core.internal.JavaFacetVersionChangeDelegate"/>
+      <config-factory class="org.eclipse.jst.common.project.facet.core.internal.JavaFacetVersionChangeConfigFactory"/>
+    </action>
+
+  </extension>
+  
+  <extension point="org.eclipse.wst.common.project.facet.core.listeners">
+     <listener
+       class="org.eclipse.jst.common.project.facet.core.internal.JavaFacetRuntimeChangedListener"
+       eventTypes="PRIMARY_RUNTIME_CHANGED"/>
+  </extension>
+  
+  <extension point="org.eclipse.wst.common.project.facet.core.validators">
+    <validator class="org.eclipse.jst.common.project.facet.core.internal.JavaFacetValidator">
+      <facet id="java"/>
+    </validator>
+  </extension>    
+  
+  <extension point="org.eclipse.wst.common.project.facet.core.detectors">
+    <detector class="org.eclipse.jst.common.project.facet.core.internal.JavaFacetDetector"/>
+  </extension>
+
+  <extension point="org.eclipse.wst.common.project.facet.core.aliases">
+    <facet-alias facet="java" alias="jst.java"/>
+    <facet-version-alias facet="java" version="1.5" alias="5.0"/>
+    <facet-version-alias facet="java" version="1.6" alias="6.0"/>
+  </extension>
+
+  <extension 
+    point="org.eclipse.core.resources.markers"
+    id="javaVersionMismatch"
+    name="%javaVersionMismatchMarkerName">
+    <super type="org.eclipse.wst.common.project.facet.core.validation.marker"/>
+    <attribute name="facetVersion"/>
+    <attribute name="compilerLevel"/>
+    <persistent value="true"/>
+  </extension>
+
+  <!--
+    ******************************
+    * Library Provider Framework *
+    ******************************
+  -->
+
+  <extension-point 
+   	id="libraryProviders" 
+   	name="%libraryProvidersExtensionPointName" 
+   	schema="schemas/libraryProviders.exsd"/>
+
+  <extension-point 
+    id="legacyLibraryProviderDetectors" 
+    name="%legacyLibraryProviderDetectorsExtensionPointName" 
+    schema="schemas/legacyLibraryProviderDetectors.exsd"/>
+   	
+  <extension-point 
+    id="downloadableLibraries" 
+    name="%downloadableLibrariesExtensionPointName" 
+    schema="schemas/downloadableLibraries.exsd"/>
+   	
+  <extension point="org.eclipse.jst.common.project.facet.core.libraryProviders">
+    <provider id="user-library-provider" abstract="true">
+      <label>%userLibraryProviderLabel</label>
+      <priority>500</priority>
+      <action type="INSTALL">
+        <config class="org.eclipse.jst.common.project.facet.core.libprov.user.UserLibraryProviderInstallOperationConfig"/>
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.user.UserLibraryProviderInstallOperation"/>
+      </action>
+      <action type="UNINSTALL">
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.user.UserLibraryProviderUninstallOperation"/>
+      </action>
+    </provider>
+  </extension>
+  
+  <extension point="org.eclipse.jst.common.project.facet.core.libraryProviders">
+    <provider id="runtime-library-provider">
+      <label>%runtimeLibraryProviderLabel</label>
+      <priority>600</priority>
+      <param name="message" value="%runtimeLibraryProviderMessage"/>
+      <enablement>
+        <with variable="context">
+          <test property="org.eclipse.jst.common.project.facet.core.canTargetRuntimeProvideLibrary" forcePluginActivation="true"/>
+        </with>
+      </enablement>
+      <action type="INSTALL">
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.internal.RuntimeLibraryProviderInstallOperation"/>
+      </action>
+      <action type="UNINSTALL">
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.internal.RuntimeLibraryProviderUninstallOperation"/>
+      </action>
+    </provider>
+  </extension>
+  
+  <extension point="org.eclipse.core.expressions.propertyTesters">
+    <propertyTester
+      id="org.eclipse.jst.common.project.facet.core.canTargetRuntimeProvideLibrary"
+      type="org.eclipse.jst.common.project.facet.core.libprov.EnablementExpressionContext"
+      namespace="org.eclipse.jst.common.project.facet.core"
+      properties="canTargetRuntimeProvideLibrary"
+      class="org.eclipse.jst.common.project.facet.core.libprov.internal.RuntimeLibraryProviderPropertyTester">
+    </propertyTester>
+  </extension>
+
+  <extension point="org.eclipse.jst.common.project.facet.core.libraryProviders">
+    <provider id="unknown-library-provider" hidden="true">
+      <label>%unknownLibraryProviderLabel</label>
+      <param name="message" value="%unknownLibraryProviderMessage"/>
+      <action type="INSTALL">
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.internal.UnknownLibraryProviderInstallOperation"/>
+      </action>
+      <action type="UNINSTALL">
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.NoOpLibraryProviderOperation"/>
+      </action>
+    </provider>
+  </extension>
+  
+  <extension point="org.eclipse.jst.common.project.facet.core.libraryProviders">
+    <provider id="legacy-library-provider" hidden="true">
+      <label>%legacyLibraryProviderLabel</label>
+      <param name="message" value="%legacyLibraryProviderMessage"/>
+      <action type="INSTALL">
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.internal.LegacyLibraryProviderInstallOperation"/>
+      </action>
+    </provider>
+  </extension>
+  
+  <extension point="org.eclipse.jst.common.project.facet.core.libraryProviders">
+    <provider id="legacy-runtime-library-provider" extends="legacy-library-provider" hidden="true">
+      <action type="UNINSTALL">
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.internal.LegacyRuntimeLibraryProviderUninstallOperation"/>
+      </action>
+    </provider>
+  </extension>
+
+  <extension point="org.eclipse.jst.common.project.facet.core.legacyLibraryProviderDetectors">
+    <detector class="org.eclipse.jst.common.project.facet.core.libprov.internal.LegacyRuntimeLibraryProviderDetector"/>
+  </extension>
+
+  <extension point="org.eclipse.jst.common.project.facet.core.libraryProviders">
+    <provider id="no-op-library-provider" abstract="true">
+      <label>%noOpLibraryProviderLabel</label>
+      <priority>-1000</priority>
+      <action type="INSTALL">
+        <config class="org.eclipse.jst.common.project.facet.core.libprov.NoOpLibraryProviderInstallOperationConfig"/>
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.NoOpLibraryProviderOperation"/>
+      </action>
+      <action type="UNINSTALL">
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.NoOpLibraryProviderOperation"/>
+      </action>
+    </provider>
+  </extension>
+  
+  <extension point="org.eclipse.jst.common.project.facet.core.libraryProviders">
+    <provider id="osgi-bundles-library-provider" abstract="true">
+      <priority>600</priority>
+      <action type="INSTALL">
+        <config class="org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesLibraryProviderInstallOperationConfig"/>
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesLibraryProviderInstallOperation"/>
+      </action>
+      <action type="UNINSTALL">
+        <operation class="org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesLibraryProviderUninstallOperation"/>
+      </action>
+      <enablement>
+        <with variable="provider">
+          <test property="eclipse.fproj.jdt.libprov.osgi.bundleReferencesResolvable" value="true" forcePluginActivation="true"/>
+        </with>
+      </enablement>
+    </provider>
+  </extension>
+  
+  <extension point="org.eclipse.jdt.core.classpathContainerInitializer">
+    <classpathContainerInitializer
+      class="org.eclipse.jst.common.project.facet.core.libprov.osgi.internal.OsgiBundlesContainerImpl$Initializer"
+      id="eclipse.fproj.jdt.libprov.osgi"/>
+  </extension>
+  
+  <extension point="org.eclipse.core.expressions.propertyTesters">
+    <propertyTester
+      id="eclipse.fproj.jdt.libprov.osgi.bundleReferencesResolvable"
+      type="org.eclipse.jst.common.project.facet.core.libprov.EnablementExpressionContext"
+      namespace="eclipse.fproj.jdt.libprov.osgi"
+      properties="bundleReferencesResolvable"
+      class="org.eclipse.jst.common.project.facet.core.libprov.osgi.internal.OsgiBundlesLibraryProviderResolvablePropertyTester">
+    </propertyTester>
+    <propertyTester
+      id="eclipse.fproj.jdt.libprov.osgi.bundleReferencesResolvable"
+      type="org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider"
+      namespace="eclipse.fproj.jdt.libprov.osgi"
+      properties="bundleReferencesResolvable"
+      class="org.eclipse.jst.common.project.facet.core.libprov.osgi.internal.OsgiBundlesLibraryProviderResolvablePropertyTester">
+    </propertyTester>
+  </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/pom.xml b/plugins/org.eclipse.jst.common.project.facet.core/pom.xml
new file mode 100644
index 0000000..225947e
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  Copyright (c) 2012, 2013 Eclipse Foundation and others.

+  All rights reserved. This program and the accompanying materials

+  are made available under the terms of the Eclipse Distribution License v1.0

+  which accompanies this distribution, and is available at

+  http://www.eclipse.org/org/documents/edl-v10.php

+ 

+  Contributors:

+    Thanh Ha (Eclipse Foundation) - initial implementation

+-->

+

+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"

+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

+  <modelVersion>4.0.0</modelVersion>

+  <parent>

+    <groupId>org.eclipse.webtools.common</groupId>

+    <artifactId>org.eclipse.webtools.common.fproj</artifactId>

+    <version>3.6.0-SNAPSHOT</version>

+    <relativePath>../../</relativePath>

+  </parent>

+

+  <groupId>org.eclipse.webtools.common</groupId>

+  <artifactId>org.eclipse.jst.common.project.facet.core</artifactId>

+  <version>1.4.500-SNAPSHOT</version>

+  <packaging>eclipse-plugin</packaging>

+</project>
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/schemas/downloadableLibraries.exsd b/plugins/org.eclipse.jst.common.project.facet.core/schemas/downloadableLibraries.exsd
new file mode 100644
index 0000000..3481b7e
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/schemas/downloadableLibraries.exsd
@@ -0,0 +1,148 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.common.project.facet.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.jst.common.project.facet.core" id="downloadableLibraries" name="Downloadable Libraries Extension Point"/>
+      </appinfo>
+      <documentation>
+         Provides a way to register libraries that can be downloaded from remote servers. This is a feature of the user library provider.
+      </documentation>
+   </annotation>
+
+   <include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+         <documentation>
+            Allows importing one or more files that contain definitions of downloadable libraries.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="import-definitions" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  A fully qualified identifier of the target extension point.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  An optional identifier of the extension instance.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  An optional name of the extension instance.
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="import-definitions">
+      <annotation>
+         <documentation>
+            Imports a single file that contains definitions of downloadable libraries.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="enablement" minOccurs="0" maxOccurs="1"/>
+         </sequence>
+         <attribute name="path" type="string">
+            <annotation>
+               <documentation>
+                  The local path (within the plugin) to the definitions file. The path attribute is mutually exclusive with the url attribute.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="url" type="string">
+            <annotation>
+               <documentation>
+                  The URL of the definitions file on a remote server. The url attribute is mutually exclusive with the path attribute.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         WTP 3.1
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         &lt;p&gt;The following example adds downloadable libraries catalog entries from a file that is located within the plugin:&lt;/p&gt;
+
+&lt;pre&gt;
+&lt;extension point=&quot;org.eclipse.jst.common.project.facet.core.downloadableLibraries&quot;&gt;
+  &lt;import-definitions path=&quot;libs/catalog.xml&quot;/&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+
+&lt;p&gt;The following example adds catalog entries from a file that is located on a server:&lt;/p&gt;
+
+&lt;pre&gt;
+&lt;extension point=&quot;org.eclipse.jst.common.project.facet.core.downloadableLibraries&quot;&gt;
+  &lt;import-definitions url=&quot;http://www.mycorp.com/libs/catalog.xml&quot;/&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+
+&lt;p&gt;Here is an example definition file. Such file can be placed inside a plugin or hosted on a server.
+Multiple libraries can be defined in a single definition file.&lt;/p&gt;
+
+&lt;pre&gt;
+&lt;libraries&gt;
+  &lt;library&gt;
+    &lt;name&gt;EclipseLink 1.0.0&lt;/name&gt;
+    &lt;download-provider&gt;Eclipse Foundation&lt;/download-provider&gt;
+    &lt;download-url&gt;&lt;![CDATA[http://www.eclipse.org/downloads/...]]&gt;&lt;/download-url&gt;
+    &lt;license-url&gt;&lt;![CDATA[http://www.eclipse.org/legal/epl-v10.html]]&gt;&lt;/license-url&gt;&gt;
+    &lt;attributes&gt;
+      &lt;component&gt;eclipselink/jlib/eclipselink.jar&lt;/component&gt;
+      &lt;source&gt;eclipselink/jlib/eclipselink-src.zip&lt;/source&gt;
+      &lt;javadoc&gt;eclipselink/jlib/eclipselink-javadocs.zip&lt;/javadoc&gt;
+    &lt;/attributes&gt;
+  &lt;/library&gt;
+&lt;/libraries&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2010 Oracle and others.&lt;br&gt;
+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 &lt;a
+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/schemas/legacyLibraryProviderDetectors.exsd b/plugins/org.eclipse.jst.common.project.facet.core/schemas/legacyLibraryProviderDetectors.exsd
new file mode 100644
index 0000000..7619cd6
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/schemas/legacyLibraryProviderDetectors.exsd
@@ -0,0 +1,114 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.common.project.facet.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.jst.common.project.facet.core" id="legacyLibraryProviderDetectors" name="Legacy Library Provider Detectors Extension Point"/>
+      </appinfo>
+      <documentation>
+         Provides a migration path for existing code to Library Provider Framework by allowing registration of detectors that can identify legacy metadata in a project and return a library provider. The registered detectors are called when a call to LibraryProviderFramework.getCurrentProvider() is made and the project metadata maintained by the framework does not show a provider for the facet in question. The detectors should not alter project state, but only return a library provider representing the legacy configuration. The legacy library providers are typically configured as hidden (not available for installation) and only implement the uninstall action.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+         <documentation>
+            Allows registering one or more legacy library provider detectors.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="detector" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  A fully qualified identifier of the target extension point.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  An optional identifier of the extension instance.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  An optional name of the extension instance.
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="detector">
+      <annotation>
+         <documentation>
+            Registers a single legacy library provider detector.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="class" type="string">
+            <annotation>
+               <documentation>
+                  Specifies the class name of the detector.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jst.common.project.facet.core.libprov.LegacyLibraryProviderDetector:"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         WTP 3.1
+
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         &lt;p&gt;The following example registers two detectors:&lt;/p&gt;
+
+&lt;pre&gt;
+&lt;extension point=&quot;org.eclipse.jst.common.project.facet.core.legacyLibraryProviderDetectors&quot;&gt;
+  &lt;detector class=&quot;com.mycompany.Detector1&quot;/&gt;
+  &lt;detector class=&quot;com.mycompany.Detector2&quot;/&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2010 Oracle and others.&lt;br&gt;
+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 &lt;a
+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/schemas/libraryProviders.exsd b/plugins/org.eclipse.jst.common.project.facet.core/schemas/libraryProviders.exsd
new file mode 100644
index 0000000..0e4e347
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/schemas/libraryProviders.exsd
@@ -0,0 +1,245 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.common.project.facet.core.libprov" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.jst.common.project.facet.core.libprov" id="libraryProviders" name="Library Providers Extension Point"/>
+      </appinfo>
+      <documentation>
+         [Enter description of this extension point.]
+      </documentation>
+   </annotation>
+
+   <include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+         <documentation>
+            (no description available)
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="provider" 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="provider">
+      <annotation>
+         <documentation>
+            (no description available)
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="label" minOccurs="0" maxOccurs="1"/>
+            <element ref="priority" minOccurs="0" maxOccurs="1"/>
+            <element ref="enablement" minOccurs="0" maxOccurs="1"/>
+            <element ref="param" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="action" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  (no description available)
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="extends" type="string">
+            <annotation>
+               <documentation>
+                  (no description available)
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="identifier" basedOn="org.eclipse.jst.common.project.facet.core.libraryProviders/provider/@id"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="abstract" type="boolean">
+            <annotation>
+               <documentation>
+                  (no description available)
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="hidden" type="boolean">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="param">
+      <annotation>
+         <documentation>
+            (no description available)
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="name" type="string" use="required">
+            <annotation>
+               <documentation>
+                  (no description available)
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="value" type="string">
+            <annotation>
+               <documentation>
+                  (no description available)
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="action">
+      <annotation>
+         <documentation>
+            (no description available)
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="config" minOccurs="0" maxOccurs="1"/>
+            <element ref="operation"/>
+         </sequence>
+         <attribute name="type" use="required">
+            <annotation>
+               <documentation>
+                  (no description available)
+               </documentation>
+            </annotation>
+            <simpleType>
+               <restriction base="string">
+                  <enumeration value="INSTALL">
+                  </enumeration>
+                  <enumeration value="UNINSTALL">
+                  </enumeration>
+               </restriction>
+            </simpleType>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="config">
+      <annotation>
+         <documentation>
+            (no description available)
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  (no description available)
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig:"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="operation">
+      <annotation>
+         <documentation>
+            (no description available)
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="class" type="string">
+            <annotation>
+               <documentation>
+                  (no description available)
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation:"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="label" type="string">
+      <annotation>
+         <documentation>
+            (no description available)
+         </documentation>
+      </annotation>
+   </element>
+
+   <element name="priority" type="string">
+      <annotation>
+         <documentation>
+            (no description available)
+         </documentation>
+      </annotation>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         WTP 3.1
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2010 Oracle and others.&lt;br&gt;
+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 &lt;a
+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/ClasspathHelper.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/ClasspathHelper.java
new file mode 100644
index 0000000..cde5c14
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/ClasspathHelper.java
@@ -0,0 +1,183 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jst.common.project.facet.core.internal.ClasspathUtil;
+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.eclipse.wst.common.project.facet.core.runtime.IRuntime;
+
+/**
+ * <p>A utility used in conjunction with IClasspathProvider in order to manage
+ * the bookkeeping when project facets are installed and uninstalled, and when
+ * the bound runtime changes. This utility tracks which classpath entries were
+ * added to the project by which facet and stores this information in a project
+ * metadata file. This enables the classpath entries to be removed without
+ * knowing what they are. It is only necessary to know which facet added them.
+ * This utility supports the case where the same classpath entry is added by
+ * multiple project facets. In this situation, a classpath entry is only
+ * removed when the removal has been requested for all of the facets that added
+ * it.</p>
+ * 
+ * <p>Typically the project facet author will write something like this in the
+ * install delegate:</p>
+ * 
+ * <pre>
+ * if( ! ClasspathHelper.addClasspathEntries( project, fv )
+ * {
+ *     // Handle the case when there is no bound runtime or when the bound
+ *     // runtime cannot provide classpath entries for this facet.
+ *     
+ *     final List alternate = ...;
+ *     ClasspathHelper.addClasspathEntries( project, fv, alternate );
+ * }
+ * </pre>
+ * 
+ * <p>And something like this in the uninstall delegate:</p>
+ * 
+ * <pre>
+ * ClasspathHelper.removeClasspathEntries( project, fv );
+ * </pre>
+ * 
+ * <p>And something like this in the runtime changed delegate:</p>
+ * 
+ * <pre>
+ * ClasspathHelper.removeClasspathEntries( project, fv );
+ * 
+ * if( ! ClasspathHelper.addClasspathEntries( project, fv )
+ * {
+ *     // Handle the case when there is no bound runtime or when the bound
+ *     // runtime cannot provide classpath entries for this facet.
+ *     
+ *     final List alternate = ...;
+ *     ClasspathHelper.addClasspathEntries( project, fv, alternate );
+ * }
+ * </pre>
+ * 
+ * <p>And something like this in the version change delegate:</p>
+ * 
+ * <pre>
+ * final IProjectFacetVersion oldver
+ *   = fproj.getInstalledVersion( fv.getProjectFacet() );
+ * 
+ * ClasspathHelper.removeClasspathEntries( project, oldver );
+ * 
+ * if( ! ClasspathHelper.addClasspathEntries( project, fv )
+ * {
+ *     // Handle the case when there is no bound runtime or when the bound
+ *     // runtime cannot provide classpath entries for this facet.
+ *     
+ *     final List alternate = ...;
+ *     ClasspathHelper.addClasspathEntries( project, fv, alternate );
+ * }
+ * </pre>
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class ClasspathHelper
+{
+    /**
+     * @since 1.4
+     */
+    
+    public static final String LEGACY_METADATA_FILE_NAME = ClasspathUtil.LEGACY_METADATA_FILE_NAME;
+    
+    private ClasspathHelper() {}
+    
+    /**
+     * Convenience method for adding to the project the classpath entries
+     * provided for the specified project facet by the runtime bound to the
+     * project. The entries are marked as belonging to the specified project
+     * facet.
+     *   
+     * @param project the project
+     * @param fv the project facet version that will own these entries
+     * @return <code>true</code> if classpath entries were added, or
+     *   <code>false</code> if there is no runtime bound to the project or if
+     *   it cannot provide classpath entries for the specified facet
+     * @throws CoreException if failed while adding the classpath entries
+     */
+    
+    public static boolean addClasspathEntries( final IProject project,
+                                               final IProjectFacetVersion fv )
+    
+        throws CoreException
+        
+    {
+        final IFacetedProject fproj = ProjectFacetsManager.create( project );
+        final IRuntime runtime = fproj.getPrimaryRuntime();
+        
+        if( runtime != null )
+        {
+            final IClasspathProvider cpprov 
+                = (IClasspathProvider) runtime.getAdapter( IClasspathProvider.class );
+            
+            final List<IClasspathEntry> cpentries = cpprov.getClasspathEntries( fv );
+            
+            if( cpentries != null )
+            {
+                addClasspathEntries( project, fv, cpentries );
+                return true;
+            }
+        }
+        
+        return false;
+    }
+    
+    /**
+     * Add the provided classpath entries to project and marks them as belonging
+     * to the specified project facet.
+     * 
+     * @param project the project
+     * @param fv the project facet version that will own these entries
+     * @param cpentries the classpath entries (element type: 
+     *   {@see IClasspathEntry})
+     * @throws CoreException if failed while adding the classpath entries
+     */
+    
+    public static void addClasspathEntries( final IProject project,
+                                            final IProjectFacetVersion fv,
+                                            final List<IClasspathEntry> cpentries )
+    
+        throws CoreException
+        
+    {
+        ClasspathUtil.addClasspathEntries( project, fv.getProjectFacet(), cpentries );
+    }
+    
+    /**
+     * Removes the classpath entries belonging to the specified project facet.
+     * Any entries that also belong to another facet are left in place.
+     * 
+     * @param project the project
+     * @param fv the project facet that owns the entries that should be removed
+     * @throws CoreException if failed while removing classpath entries
+     */
+    
+    public static void removeClasspathEntries( final IProject project,
+                                               final IProjectFacetVersion fv )
+    
+        throws CoreException
+        
+    {
+        ClasspathUtil.removeClasspathEntries( project, fv.getProjectFacet() );
+    }
+    
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/IClasspathProvider.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/IClasspathProvider.java
new file mode 100644
index 0000000..2237d56
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/IClasspathProvider.java
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * The interface implemented by a runtime component adapter in order to provide
+ * classpath entries for project facets. For convenience, the runtime can also
+ * be adapted to this interface. That adapter will delegate to the runtime 
+ * components in the order that they are listed in the runtime. The first one 
+ * that can provide classpath entries for the specified project facet wins. 
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public interface IClasspathProvider
+{
+    /**
+     * Returns the classpath entries for the specified project facet.
+     * 
+     * @param fv the project facet version
+     * @return returns the classpath entries for the specified project facet, or
+     *   <code>null</code> if this provider does not provide classpath entries
+     *   for the given project facet
+     */
+    
+    List<IClasspathEntry> getClasspathEntries( IProjectFacetVersion fv );
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacet.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacet.java
new file mode 100644
index 0000000..552a1e0
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacet.java
@@ -0,0 +1,83 @@
+/******************************************************************************
+ * Copyright (c) 2010, 2014 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin;
+import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
+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 <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacet 
+{
+    public static final String ID = "java"; //$NON-NLS-1$
+    public static final IProjectFacet FACET = ProjectFacetsManager.getProjectFacet( ID );
+    public static final IProjectFacetVersion VERSION_1_3 = FACET.getVersion( "1.3" ); //$NON-NLS-1$
+    public static final IProjectFacetVersion VERSION_1_4 = FACET.getVersion( "1.4" ); //$NON-NLS-1$
+    public static final IProjectFacetVersion VERSION_1_5 = FACET.getVersion( "1.5" ); //$NON-NLS-1$
+    public static final IProjectFacetVersion VERSION_1_6 = FACET.getVersion( "1.6" ); //$NON-NLS-1$
+    public static final IProjectFacetVersion VERSION_1_7 = FACET.getVersion( "1.7" ); //$NON-NLS-1$
+    public static final IProjectFacetVersion VERSION_1_8 = FACET.getVersion( "1.8" ); //$NON-NLS-1$
+
+    @Deprecated
+    public static final IProjectFacetVersion JAVA_13 = VERSION_1_3;
+    
+    @Deprecated
+    public static final IProjectFacetVersion JAVA_14 = VERSION_1_4;
+    
+    @Deprecated
+    public static final IProjectFacetVersion JAVA_50 = VERSION_1_5;
+    
+    @Deprecated
+    public static final IProjectFacetVersion JAVA_60 = VERSION_1_6;
+
+    public static boolean isInstalled( final IProject project )
+    {
+        try
+        {
+            return FacetedProjectFramework.hasProjectFacet( project, ID );
+        }
+        catch( CoreException e )
+        {
+            FacetedProjectFrameworkJavaPlugin.log( e );
+            return false;
+        }
+    }
+    
+    /**
+     * Checks whether the specified project is a Java project.
+     * 
+     * @param pj the project to check.
+     * @return <code>true</code> if the project is a Java project
+     * @since 1.4
+     */
+    
+    public static boolean isJavaProject( final IProject project )
+    {
+        try
+        {
+            return project.getNature( JavaCore.NATURE_ID ) != null;
+        }
+        catch( CoreException e )
+        {
+            return false;
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetInstallConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetInstallConfig.java
new file mode 100644
index 0000000..a8f4a1f
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetInstallConfig.java
@@ -0,0 +1,460 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ *    Scott Huff (shuff@us.ibm.com) - improvements to validation
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.PLUGIN_ID;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jst.common.project.facet.core.internal.FacetCorePlugin;
+import org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.ActionConfig;
+import org.eclipse.wst.common.project.facet.core.util.EventListenerRegistry;
+import org.eclipse.wst.common.project.facet.core.util.IEventListener;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public class JavaFacetInstallConfig
+
+    extends ActionConfig
+    
+{
+    private static final String PROD_PROP_OUTPUT_FOLDER = "defaultJavaOutputFolder"; //$NON-NLS-1$
+    private static final String PROD_PROP_OUTPUT_FOLDER_LEGACY = "outputFolder"; //$NON-NLS-1$
+    private static final String DEFAULT_OUTPUT_FOLDER = "build/classes"; //$NON-NLS-1$
+    
+    public static class ChangeEvent
+    {
+        public enum Type
+        {
+            SOURCE_FOLDERS_CHANGED,
+            DEFAULT_OUTPUT_FOLDER_CHANGED
+        }
+        
+        private final Type type;
+        private final JavaFacetInstallConfig installConfig;
+        
+        ChangeEvent( final Type type,
+                     final JavaFacetInstallConfig installConfig )
+        {
+            this.type = type;
+            this.installConfig = installConfig;
+        }
+        
+        public final Type getType()
+        {
+            return this.type;
+        }
+
+        public final JavaFacetInstallConfig getJavaFacetInstallConfig()
+        {
+            return this.installConfig;
+        }
+    }
+
+    /**
+     * Specifies if the local file system is case sensitive. Used by validation. This is a non-final
+     * instance field to allow unit tests to override the default behavior. Unit tests will access
+     * this field via reflection. Do not rename or otherwise modify without changing unit tests too.
+     */
+    
+    private boolean caseSensitiveFs = EFS.getLocalFileSystem().isCaseSensitive();
+
+    private EventListenerRegistry<ChangeEvent.Type,ChangeEvent> listeners;
+    private List<IPath> sourceFolders;
+    private List<IPath> sourceFoldersReadOnly;
+    private IPath defaultOutputFolder;
+        
+    public JavaFacetInstallConfig()
+    {
+        this.listeners = new EventListenerRegistry<ChangeEvent.Type,ChangeEvent>( ChangeEvent.Type.class );
+        
+        this.sourceFolders = new CopyOnWriteArrayList<IPath>();
+        this.sourceFoldersReadOnly = Collections.unmodifiableList( this.sourceFolders );
+        this.defaultOutputFolder = null;
+        
+        String sourceFolder = FacetCorePlugin.getJavaSrcFolder();
+        
+        this.sourceFolders.add( new Path( sourceFolder ) );
+        
+        String outputFolder = getProductProperty( PROD_PROP_OUTPUT_FOLDER );
+        
+        if( outputFolder == null )
+        {
+            outputFolder = getProductProperty( PROD_PROP_OUTPUT_FOLDER_LEGACY );
+        }
+        
+        if( outputFolder == null )
+        {
+            outputFolder = DEFAULT_OUTPUT_FOLDER;
+        }
+        
+        this.defaultOutputFolder = new Path( outputFolder );
+    }
+    
+    @Override
+    public Set<IFile> getValidateEditFiles()
+    {
+        final Set<IFile> files = super.getValidateEditFiles();
+        final IProject project = getFacetedProjectWorkingCopy().getProject();
+        
+        if( project != null )
+        {
+            files.add( project.getFile( IProjectDescription.DESCRIPTION_FILE_NAME ) );
+            files.add( project.getFile( JavaFacetUtil.FILE_CLASSPATH ) );
+            files.add( project.getFile( JavaFacetUtil.FILE_JDT_CORE_PREFS ) );
+            files.add( project.getFile( ClasspathHelper.LEGACY_METADATA_FILE_NAME ) );
+        }
+        
+        return files;
+    }
+    
+    @Override
+    public IStatus validate()
+    {
+        IStatus status = Status.OK_STATUS;
+        
+        final List<Folder> folders = new ArrayList<Folder>();
+        
+        for( IPath sourceFolder : this.sourceFolders )
+        {
+            folders.add( new SourceFolder( sourceFolder ) );
+        }
+        
+        folders.add( new OutputFolder( this.defaultOutputFolder ) );
+        
+        while( ! folders.isEmpty() )
+        {
+            final Folder folder = folders.remove( 0 );
+            status = validateFolder( folders, folder );
+            
+            if( ! status.isOK() )
+            {
+                break;
+            }
+        }
+        
+        return status;
+    }
+
+    /**
+     * Validates the provided source folder against the existing configuration. Can be used to check
+     * if adding a given source folder to this configuration will introduce validation problems.
+     *  
+     * @param candidateSourceFolder the source folder to validate
+     * @return status detailing the validity of the candidate source folder
+     * @throw {@link IllegalArgumentException} if candidateSourceFolder is null
+     */
+    
+    public IStatus validateSourceFolder( final String candidateSourceFolder )
+    {
+        if( candidateSourceFolder == null )
+        {
+            throw new IllegalArgumentException();
+        }
+        
+        final List<Folder> folders = new ArrayList<Folder>();
+        
+        for( IPath sourceFolder : this.sourceFolders )
+        {
+            folders.add( new SourceFolder( sourceFolder ) );
+        }
+        
+        folders.add( new OutputFolder( this.defaultOutputFolder ) );
+        
+        return validateFolder( folders, new SourceFolder( new Path( candidateSourceFolder.trim() ) ) );
+    }
+    
+    private IStatus validateFolder( final List<Folder> existingFolders,
+                                    final Folder folder )
+    {
+        IStatus status = Status.OK_STATUS;
+        
+        if( folder.path.segmentCount() == 0 )
+        {
+            if( folder instanceof SourceFolder )
+            {
+                status = new Status( IStatus.ERROR, PLUGIN_ID, Resources.mustSpecifySourceFolderMessage );
+            }
+            else
+            {
+                status = new Status( IStatus.ERROR, PLUGIN_ID, Resources.mustSpecifyDefaultOutputFolderMessage );
+            }
+        }
+        else
+        {
+            final String pjname = getFacetedProjectWorkingCopy().getProjectName();
+            final String fullPath = "/" + pjname + "/" + folder.path; //$NON-NLS-1$ //$NON-NLS-2$
+            
+            status = ResourcesPlugin.getWorkspace().validatePath( fullPath, IResource.FOLDER );
+            
+            if( status.isOK() )
+            {
+                for( Folder existingFolder : existingFolders )
+                {
+                    status = validateFolder( existingFolder, folder );
+                    
+                    if( ! status.isOK() )
+                    {
+                        break;
+                    }
+                }
+            }
+        }
+        
+        return status;
+    }
+
+    private IStatus validateFolder( final Folder existingPath,
+                                    final Folder newPath )
+    {
+        final int existingPathLen = existingPath.path.segmentCount();
+        final int newPathLen = newPath.path.segmentCount();
+        final int minPathLen = Math.min( existingPathLen, newPathLen );
+        
+        if( minPathLen == 0 )
+        {
+            // The check that handles this case better is done elsewhere.
+            
+            return Status.OK_STATUS;
+        }
+        
+        for( int i = 0; i < minPathLen; i++ )
+        {
+            if( comparePathSegments( existingPath.path.segment( i ), newPath.path.segment( i ) ) == false )
+            {
+                return Status.OK_STATUS;
+            }
+        }
+        
+        String message = null;
+        
+        if( existingPathLen == newPathLen )
+        {
+            // It is legal to use the same folder as both source and output. 
+            
+            if( existingPath instanceof SourceFolder && newPath instanceof SourceFolder )
+            {
+                message = NLS.bind( Resources.nonUniqueSourceFolderMessage, newPath.path );
+            }
+        }
+        else
+        {
+            final Folder x, y;
+            
+            if( existingPathLen > newPathLen )
+            {
+                x = newPath;
+                y = existingPath;
+            }
+            else
+            {
+                x = existingPath;
+                y = newPath;
+            }
+            
+            message = NLS.bind( Resources.cannotNestFoldersMessage, new Object[] { x.path, x.getTypeLabel(), y.path, y.getTypeLabel() } );
+        }
+        
+        if( message == null )
+        {
+            return Status.OK_STATUS;
+        }
+        
+        return new Status( IStatus.ERROR, PLUGIN_ID, message );
+    }
+
+    private boolean comparePathSegments( final String a,
+                                         final String b )
+    {
+        return ( this.caseSensitiveFs && a.equals( b ) ) || ( ! this.caseSensitiveFs && a.equalsIgnoreCase( b ) );
+    }
+
+    public List<IPath> getSourceFolders()
+    {
+        return this.sourceFoldersReadOnly;
+    }
+    
+    public void setSourceFolders( final List<IPath> paths )
+    {
+        if( ! this.sourceFolders.equals( paths ) )
+        {
+            this.sourceFolders.clear();
+            this.sourceFolders.addAll( paths );
+
+            final ChangeEvent event = new ChangeEvent( ChangeEvent.Type.SOURCE_FOLDERS_CHANGED, this );
+            this.listeners.notifyListeners( ChangeEvent.Type.SOURCE_FOLDERS_CHANGED, event );
+        }
+    }
+    
+    public void setSourceFolder( final IPath path )
+    {
+        final List<IPath> newSourceFolders;
+        
+        if( path == null )
+        {
+            newSourceFolders = Collections.emptyList();
+        }
+        else
+        {
+            newSourceFolders = Collections.singletonList( path );
+        }
+        
+        setSourceFolders( newSourceFolders );
+    }
+    
+    public void addSourceFolder( final IPath path )
+    {
+        if( path == null )
+        {
+            throw new IllegalArgumentException();
+        }
+        
+        final List<IPath> newSourceFolders = new ArrayList<IPath>( getSourceFolders() );
+        newSourceFolders.add( path );
+        setSourceFolders( newSourceFolders );
+    }
+    
+    public void removeSourceFolder( final IPath path )
+    {
+        final List<IPath> newSourceFolders = new ArrayList<IPath>( getSourceFolders() );
+        newSourceFolders.remove( path );
+        setSourceFolders( newSourceFolders );
+    }
+    
+    public IPath getDefaultOutputFolder()
+    {
+        return this.defaultOutputFolder;
+    }
+    
+    public void setDefaultOutputFolder( final IPath defaultOutputFolder )
+    {
+        if( ! equal( this.defaultOutputFolder, defaultOutputFolder ) )
+        {
+            this.defaultOutputFolder = defaultOutputFolder;
+            
+            final ChangeEvent event = new ChangeEvent( ChangeEvent.Type.DEFAULT_OUTPUT_FOLDER_CHANGED, this );
+            this.listeners.notifyListeners( ChangeEvent.Type.DEFAULT_OUTPUT_FOLDER_CHANGED, event );
+        }
+    }
+    
+    public void addListener( final IEventListener<ChangeEvent> listener,
+                             final ChangeEvent.Type... types )
+    {
+        this.listeners.addListener( listener, types );
+    }
+    
+    public void removeListener( final IEventListener<ChangeEvent> listener )
+    {
+        this.listeners.removeListener( listener );
+    }
+
+    private static boolean equal( final Object obj1,
+                                  final Object obj2 )
+    {
+        if( obj1 == null || obj2 == null )
+        {
+            return false;
+        }
+        else
+        {
+            return obj1.equals( obj2 );
+        }
+    }
+    
+    private static String getProductProperty( final String propName )
+    {
+        String value = null;
+        
+        if( Platform.getProduct() != null )
+        {
+            value = Platform.getProduct().getProperty( propName );
+        }
+        
+        return value;
+    }
+    
+    private static abstract class Folder
+    {
+        public final IPath path;
+        
+        public Folder( final IPath path )
+        {
+            this.path = path;
+        }
+        
+        public abstract String getTypeLabel();
+    }
+    
+    private static final class SourceFolder extends Folder
+    {
+        public SourceFolder( final IPath path )
+        {
+            super( path );
+        }
+        
+        @Override
+        public String getTypeLabel()
+        {
+            return Resources.sourceFolderType;
+        }
+    }
+
+    private static final class OutputFolder extends Folder
+    {
+        public OutputFolder( final IPath path )
+        {
+            super( path );
+        }
+        
+        @Override
+        public String getTypeLabel()
+        {
+            return Resources.outputFolderType;
+        }
+    }
+
+    private static final class Resources extends NLS 
+    {
+        public static String mustSpecifySourceFolderMessage;
+        public static String mustSpecifyDefaultOutputFolderMessage;
+        public static String nonUniqueSourceFolderMessage;
+        public static String cannotNestFoldersMessage;
+        public static String sourceFolderType;
+        public static String outputFolderType;
+
+        static 
+        {
+            initializeMessages( JavaFacetInstallConfig.class.getName(), Resources.class );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetInstallConfig.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetInstallConfig.properties
new file mode 100644
index 0000000..d96dab5
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetInstallConfig.properties
@@ -0,0 +1,6 @@
+mustSpecifySourceFolderMessage = Source folder must be specified.
+mustSpecifyDefaultOutputFolderMessage = Default output folder must be specified.
+nonUniqueSourceFolderMessage = Source folder "{0}" is already specified.
+cannotNestFoldersMessage = Cannot nest {3} folder "{2}" inside {1} folder "{0}".
+sourceFolderType = source
+outputFolderType = output
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetUninstallConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetUninstallConfig.java
new file mode 100644
index 0000000..eb29b44
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetUninstallConfig.java
@@ -0,0 +1,46 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core;
+
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil;
+import org.eclipse.wst.common.project.facet.core.ActionConfig;
+
+/**
+ * @since 1.4
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public class JavaFacetUninstallConfig
+
+    extends ActionConfig
+    
+{
+    @Override
+    public Set<IFile> getValidateEditFiles()
+    {
+        final Set<IFile> files = super.getValidateEditFiles();
+        final IProject project = getFacetedProjectWorkingCopy().getProject();
+        
+        files.add( project.getFile( IProjectDescription.DESCRIPTION_FILE_NAME ) );
+        files.add( project.getFile( JavaFacetUtil.FILE_CLASSPATH ) );
+        files.add( project.getFile( JavaFacetUtil.FILE_JDT_CORE_PREFS ) );
+        files.add( project.getFile( ClasspathHelper.LEGACY_METADATA_FILE_NAME ) );
+        
+        return files;
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetVersionChangeConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetVersionChangeConfig.java
new file mode 100644
index 0000000..02e9deb
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/JavaFacetVersionChangeConfig.java
@@ -0,0 +1,44 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core;
+
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.common.project.facet.core.internal.JavaFacetUtil;
+import org.eclipse.wst.common.project.facet.core.ActionConfig;
+
+/**
+ * @since 1.4
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public class JavaFacetVersionChangeConfig
+
+    extends ActionConfig
+    
+{
+    @Override
+    public Set<IFile> getValidateEditFiles()
+    {
+        final Set<IFile> files = super.getValidateEditFiles();
+        final IProject project = getFacetedProjectWorkingCopy().getProject();
+        
+        files.add( project.getFile( JavaFacetUtil.FILE_CLASSPATH ) );
+        files.add( project.getFile( JavaFacetUtil.FILE_JDT_CORE_PREFS ) );
+        files.add( project.getFile( ClasspathHelper.LEGACY_METADATA_FILE_NAME ) );
+        
+        return files;
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/StandardJreRuntimeComponent.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/StandardJreRuntimeComponent.java
new file mode 100644
index 0000000..3f70bf2
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/StandardJreRuntimeComponent.java
@@ -0,0 +1,107 @@
+/******************************************************************************
+ * Copyright (c) 2010, 2014 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMInstall2;
+import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponent;
+import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentType;
+import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponentVersion;
+import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class StandardJreRuntimeComponent 
+{
+    public static final String TYPE_ID = "standard.jre"; //$NON-NLS-1$
+    public static final IRuntimeComponentType TYPE = RuntimeManager.getRuntimeComponentType( TYPE_ID );
+    public static final IRuntimeComponentVersion VERSION_1_3 = TYPE.getVersion( "1.3" ); //$NON-NLS-1$
+    public static final IRuntimeComponentVersion VERSION_1_4 = TYPE.getVersion( "1.4" ); //$NON-NLS-1$
+    public static final IRuntimeComponentVersion VERSION_1_5 = TYPE.getVersion( "1.5" ); //$NON-NLS-1$
+    public static final IRuntimeComponentVersion VERSION_1_6 = TYPE.getVersion( "1.6" ); //$NON-NLS-1$
+    public static final IRuntimeComponentVersion VERSION_1_7 = TYPE.getVersion( "1.7" ); //$NON-NLS-1$
+    public static final IRuntimeComponentVersion VERSION_1_8 = TYPE.getVersion( "1.8" ); //$NON-NLS-1$
+
+    @Deprecated
+    public static final IRuntimeComponentVersion VERSION_5_0 = VERSION_1_5;
+    
+    @Deprecated( )
+    public static final IRuntimeComponentVersion VERSION_6_0 = VERSION_1_6;
+
+    public static final String PROP_VM_INSTALL_TYPE = "vm-install-type"; //$NON-NLS-1$
+    public static final String PROP_VM_INSTALL_ID = "vm-install-id"; //$NON-NLS-1$
+    
+    public static IRuntimeComponent create( final IVMInstall vmInstall )
+    {
+        String jvmver = null;
+        
+        if( vmInstall instanceof IVMInstall2 )
+        {
+            final IVMInstall2 vmInstall2 = (IVMInstall2) vmInstall;
+            jvmver = vmInstall2.getJavaVersion();
+        }
+        
+        final IRuntimeComponentVersion rcv;
+        
+        if( jvmver == null ) 
+        {
+            rcv = StandardJreRuntimeComponent.VERSION_1_7;
+        } 
+        else if( jvmver.startsWith( "1.3" ) ) //$NON-NLS-1$
+        {
+            rcv = StandardJreRuntimeComponent.VERSION_1_3;
+        }
+        else if( jvmver.startsWith( "1.4" ) ) //$NON-NLS-1$
+        {
+            rcv = StandardJreRuntimeComponent.VERSION_1_4;
+        }
+        else if( jvmver.startsWith( "1.5" ) ) //$NON-NLS-1$
+        {
+            rcv = StandardJreRuntimeComponent.VERSION_1_5;
+        }
+        else if( jvmver.startsWith( "1.6" ) ) //$NON-NLS-1$
+        {
+            rcv = StandardJreRuntimeComponent.VERSION_1_6;
+        }
+        else if( jvmver.startsWith( "1.7" ) ) //$NON-NLS-1$
+        {
+            rcv = StandardJreRuntimeComponent.VERSION_1_7;
+        }
+        else if( jvmver.startsWith( "1.8" ) ) //$NON-NLS-1$
+        {
+            rcv = StandardJreRuntimeComponent.VERSION_1_8;
+        }
+        else 
+        {
+            rcv = StandardJreRuntimeComponent.VERSION_1_8;
+        }
+        
+        final Map<String,String> properties = new HashMap<String,String>();
+        
+        if( vmInstall != null )
+        {
+            properties.put( StandardJreRuntimeComponent.PROP_VM_INSTALL_TYPE, 
+                            vmInstall.getVMInstallType().getId() );
+            
+            properties.put( StandardJreRuntimeComponent.PROP_VM_INSTALL_ID, 
+                            vmInstall.getId() );
+        }
+        
+        return RuntimeManager.createRuntimeComponent( rcv, properties );
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/ClasspathUtil.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/ClasspathUtil.java
new file mode 100644
index 0000000..5b72161
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/ClasspathUtil.java
@@ -0,0 +1,546 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+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.internal.core.ClasspathEntry;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+@SuppressWarnings( "restriction" )
+public final class ClasspathUtil
+{
+    public static final String LEGACY_METADATA_FILE_NAME 
+        = ".settings/org.eclipse.jst.common.project.facet.core.prefs"; //$NON-NLS-1$
+
+    public static final Object SYSTEM_OWNER = new Object();
+    private static final String OWNER_PROJECT_FACETS_ATTR = "owner.project.facets"; //$NON-NLS-1$
+    
+    private ClasspathUtil() {}
+
+    public static List<IClasspathEntry> getProjectClasspath( final IJavaProject project )
+    
+        throws CoreException
+        
+    {
+        final List<IClasspathEntry> result = new ArrayList<IClasspathEntry>();
+        
+        for( IClasspathEntry cpe : project.getRawClasspath() )
+        {
+            result.add( cpe );
+        }
+        
+        return result;
+    }
+    
+    public static void setProjectClasspath( final IJavaProject project,
+                                            final List<IClasspathEntry> cp )
+    
+        throws CoreException
+        
+    {
+        validateClasspathEdit( project );
+        project.setRawClasspath( cp.toArray( new IClasspathEntry[ cp.size() ] ), null );
+    }
+    
+    public static void addClasspathEntry( final IProject project,
+                                          final IClasspathEntry cpe )
+    
+        throws CoreException
+        
+    {
+        addClasspathEntry( JavaCore.create( project ), cpe );
+    }
+
+    public static void addClasspathEntry( final IJavaProject project,
+                                          final IClasspathEntry cpe )
+    
+        throws CoreException
+        
+    {
+        validateClasspathEdit( project );
+        
+        final IClasspathEntry[] cpOld = project.getRawClasspath();
+        final IClasspathEntry[] cpNew = new IClasspathEntry[ cpOld.length + 1 ];
+        System.arraycopy( cpOld, 0, cpNew, 0, cpOld.length );
+        cpNew[ cpOld.length ] = cpe;
+        project.setRawClasspath( cpNew, null );
+    }
+
+    public static List<IClasspathEntry> getClasspathEntries( final IProject project,
+                                                             final IProjectFacet facet )
+                                                             
+        throws CoreException
+        
+    {
+        final IJavaProject jproj = JavaCore.create( project );
+        return getClasspathEntries( jproj, facet );
+    }
+    
+    public static List<IClasspathEntry> getClasspathEntries( final IJavaProject project,
+                                                             final IProjectFacet facet )
+    
+        throws CoreException
+        
+    {
+        final List<IClasspathEntry> result = new ArrayList<IClasspathEntry>();
+        
+        for( IClasspathEntry cpe : project.getRawClasspath() )
+        {
+            final Set<Object> owners = getOwners( project, cpe );
+            
+            if( owners.contains( facet ) )
+            {
+                result.add( cpe );
+            }
+        }
+        
+        return result;
+    }
+    
+    
+    public static void addClasspathEntries( final IProject project,
+                                            final IProjectFacet facet,
+                                            final List<IClasspathEntry> cpentries )
+    
+        throws CoreException
+        
+    {
+        final IJavaProject jproj = JavaCore.create( project );
+        addClasspathEntries( jproj, facet, cpentries );
+    }
+    
+    public static void addClasspathEntries( final IJavaProject project,
+                                            final IProjectFacet facet,
+                                            final List<IClasspathEntry> cpentries )
+    
+        throws CoreException
+        
+    {
+        validateClasspathEdit( project );
+        convertLegacyMetadata( project );
+        
+        final List<IClasspathEntry> cp = getProjectClasspath( project );
+        
+        for( IClasspathEntry cpe : cpentries )
+        {
+            IClasspathEntry existingClasspathEntry = null;
+            
+            for( IClasspathEntry x : cp )
+            {
+                if( x.getPath().equals( cpe.getPath() ) )
+                {
+                    existingClasspathEntry = x;
+                    break;
+                }
+            }
+
+            final Set<Object> owners = getOwners( project, existingClasspathEntry );
+            
+            owners.add( facet );
+            
+            if( existingClasspathEntry != null )
+            {
+                final IClasspathEntry annotatedEntry = setOwners( existingClasspathEntry, owners );
+                final int existingIndex = cp.indexOf( existingClasspathEntry );
+                cp.set( existingIndex, annotatedEntry );
+            }
+            else
+            {
+                final IClasspathEntry annotatedEntry = setOwners( cpe, owners );
+                cp.add( annotatedEntry );
+            }
+        }
+
+        setProjectClasspath( project, cp );
+    }
+    
+    public static void removeClasspathEntries( final IProject project,
+                                               final IProjectFacet facet )
+    
+        throws CoreException
+        
+    {
+        final IJavaProject jproj = JavaCore.create( project );
+        removeClasspathEntries( jproj, facet );
+    }
+        
+    public static void removeClasspathEntries( final IJavaProject project,
+                                               final IProjectFacet facet )
+    
+        throws CoreException
+        
+    {
+        validateClasspathEdit( project );
+        convertLegacyMetadata( project );
+        
+        final List<IClasspathEntry> cp = getProjectClasspath( project );
+        boolean cpchanged = false;
+        
+        for( ListIterator<IClasspathEntry> itr = cp.listIterator(); itr.hasNext(); )
+        {
+            final IClasspathEntry cpe = itr.next();
+            final Set<Object> owners = getOwners( project, cpe );
+            
+            if( owners.remove( facet ) )
+            {
+                if( owners.size() == 0 )
+                {
+                    itr.remove();
+                }
+                else
+                {
+                    itr.set( setOwners( cpe, owners ) );
+                }
+                
+                cpchanged = true;
+            }
+        }
+
+        if( cpchanged )
+        {
+            setProjectClasspath( project, cp );
+        }
+    }
+
+    public static void removeClasspathEntries( final IProject project,
+                                               final IProjectFacet facet,
+                                               final List<IClasspathEntry> cpentries )
+    
+        throws CoreException
+        
+    {
+        final IJavaProject jproj = JavaCore.create( project );
+        removeClasspathEntries( jproj, facet, cpentries );
+    }
+        
+    public static void removeClasspathEntries( final IJavaProject project,
+                                               final IProjectFacet facet,
+                                               final List<IClasspathEntry> cpentries )
+    
+        throws CoreException
+        
+    {
+        validateClasspathEdit( project );
+        convertLegacyMetadata( project );
+        
+        final List<IClasspathEntry> cp = getProjectClasspath( project );
+        boolean cpchanged = false;
+        
+        for( ListIterator<IClasspathEntry> itr = cp.listIterator(); itr.hasNext(); )
+        {
+            final IClasspathEntry cpe = itr.next();
+            
+            if( cpentries.contains( cpe ) )
+            {
+                final Set<Object> owners = getOwners( project, cpe );
+                
+                if( owners.remove( facet ) )
+                {
+                    if( owners.size() == 0 )
+                    {
+                        itr.remove();
+                    }
+                    else
+                    {
+                        itr.set( setOwners( cpe, owners ) );
+                    }
+                    
+                    cpchanged = true;
+                }
+            }
+        }
+
+        if( cpchanged )
+        {
+            setProjectClasspath( project, cp );
+        }
+    }
+    
+    private static Set<Object> getOwners( final IJavaProject project,
+                                          final IClasspathEntry cpe )
+                                          
+        throws CoreException
+        
+    {
+        final Set<Object> owners = new HashSet<Object>();
+        
+        if( cpe != null )
+        {
+            for( IClasspathAttribute attr : cpe.getExtraAttributes() )
+            {
+                if( attr.getName().equals( OWNER_PROJECT_FACETS_ATTR ) )
+                {
+                    owners.addAll( decodeOwnersString( attr.getValue() ) );
+                    break;
+                }
+            }
+            
+            owners.addAll( getOwnersFromLegacyMetadata( project, cpe ) );
+            
+            if( owners.isEmpty() )
+            {
+                owners.add( SYSTEM_OWNER );
+            }
+        }
+        
+        return owners;
+    }
+
+    private static Set<Object> getOwnersFromLegacyMetadata( final IJavaProject project,
+                                                            final IClasspathEntry cpe )
+    
+        throws CoreException
+        
+    {
+        final IProject pj = project.getProject();
+        final IFile legacyMetadataFile = pj.getFile( LEGACY_METADATA_FILE_NAME );
+        
+        if( legacyMetadataFile.exists() )
+        {
+            final ProjectScope scope = new ProjectScope( pj );
+            final IEclipsePreferences pluginRoot = scope.getNode( FacetCorePlugin.PLUGIN_ID );
+            final Preferences root = pluginRoot.node( "classpath.helper" ); //$NON-NLS-1$
+            
+            final String[] keys;
+            
+            try
+            {
+                keys = root.childrenNames();
+            }
+            catch( BackingStoreException e )
+            {
+                throw new CoreException( FacetCorePlugin.createErrorStatus( e.getMessage(), e ) );
+            }
+            
+            for( String key : keys )
+            {
+                final Preferences node = root.node( key );
+                final String owners = node.get( "owners", null ); //$NON-NLS-1$
+                
+                if( owners != null )
+                {
+                    final IPath path = new Path( key.replaceAll( "::", "/" ) ); //$NON-NLS-1$ //$NON-NLS-2$
+                    
+                    if( cpe.getPath().equals( path ) )
+                    {
+                        return decodeOwnersString( owners );
+                    }
+                }
+            }
+        }
+        
+        return Collections.emptySet();
+    }
+
+    private static IClasspathEntry setOwners( final IClasspathEntry cpe,
+                                              final Set<Object> owners )
+    {
+        if( owners.size() == 1 && owners.iterator().next() == SYSTEM_OWNER )
+        {
+            owners.clear();
+        }
+        
+        final String ownersString = ( owners.size() == 0 ? null : encodeOwnersString( owners ) );
+        return setOwners( cpe, ownersString );
+    }
+
+    private static IClasspathEntry setOwners( final IClasspathEntry cpe,
+                                              final String owners )
+    {
+        final List<IClasspathAttribute> attrs = new ArrayList<IClasspathAttribute>();
+        
+        for( IClasspathAttribute attr : cpe.getExtraAttributes() )
+        {
+            if( ! attr.getName().equals( OWNER_PROJECT_FACETS_ATTR ) )
+            {
+                attrs.add( attr );
+            }
+        }
+        
+        if( owners != null )
+        {
+            attrs.add( JavaCore.newClasspathAttribute( OWNER_PROJECT_FACETS_ATTR, owners ) );
+        }
+        
+        return new ClasspathEntry( cpe.getContentKind(), cpe.getEntryKind(), cpe.getPath(),
+                                   cpe.getInclusionPatterns(), cpe.getExclusionPatterns(),
+                                   cpe.getSourceAttachmentPath(), cpe.getSourceAttachmentRootPath(),
+                                   cpe.getOutputLocation(), cpe.isExported(), cpe.getAccessRules(),
+                                   cpe.combineAccessRules(), 
+                                   attrs.toArray( new IClasspathAttribute[ attrs.size() ] ) );
+    }
+
+    private static String encodeOwnersString( final Set<Object> owners )
+    {
+        final StringBuilder buf = new StringBuilder();
+        
+        for( Object owner : owners )
+        {
+            if( buf.length() > 0 ) 
+            {
+                buf.append( ';' );
+            }
+            
+            if( owner == SYSTEM_OWNER )
+            {
+                buf.append( "#system#" ); //$NON-NLS-1$
+            }
+            else
+            {
+                final IProjectFacet facet = (IProjectFacet) owner;
+                buf.append( facet.getId() );
+            }
+        }
+        
+        return buf.toString();
+    }
+    
+    private static Set<Object> decodeOwnersString( final String str )
+    {
+        final Set<Object> owners = new HashSet<Object>();
+        final String[] split = str.split( ";" ); //$NON-NLS-1$
+        
+        for( int j = 0; j < split.length; j++ )
+        {
+            final String segment = split[ j ];
+            
+            if( segment.equals( "#system#" ) ) //$NON-NLS-1$
+            {
+                owners.add( SYSTEM_OWNER );
+            }
+            else
+            {
+                String facetId = segment;
+                final int colon = facetId.indexOf( ':' );
+                
+                if( colon != -1 )
+                {
+                    facetId = facetId.substring( 0, colon );
+                }
+                
+                owners.add( ProjectFacetsManager.getProjectFacet( facetId ) );
+            }
+        }
+        
+        return owners;
+    }
+    
+    private static void convertLegacyMetadata( final IJavaProject project )
+    
+        throws CoreException
+        
+    {
+        final IProject pj = project.getProject();
+        final IFile legacyMetadataFile = pj.getFile( LEGACY_METADATA_FILE_NAME );
+        
+        if( legacyMetadataFile.exists() )
+        {
+            final ProjectScope scope = new ProjectScope( pj );
+            final IEclipsePreferences pluginRoot = scope.getNode( FacetCorePlugin.PLUGIN_ID );
+            final Preferences root = pluginRoot.node( "classpath.helper" ); //$NON-NLS-1$
+            final Map<IPath,String> metadata = new HashMap<IPath,String>();
+            
+            final String[] keys;
+            
+            try
+            {
+                keys = root.childrenNames();
+            }
+            catch( BackingStoreException e )
+            {
+                throw new CoreException( FacetCorePlugin.createErrorStatus( e.getMessage(), e ) );
+            }
+            
+            for( String key : keys )
+            {
+                final Preferences node = root.node( key );
+                final String owners = node.get( "owners", null ); //$NON-NLS-1$
+                
+                if( owners != null )
+                {
+                    metadata.put( new Path( key.replaceAll( "::", "/" ) ), owners ); //$NON-NLS-1$ //$NON-NLS-2$
+                }
+            }
+            
+            if( ! metadata.isEmpty() )
+            {
+                final List<IClasspathEntry> cp = getProjectClasspath( project );
+                boolean cpchanged = false;
+                
+                for( ListIterator<IClasspathEntry> itr = cp.listIterator(); itr.hasNext(); )
+                {
+                    final IClasspathEntry cpe = itr.next();
+                    final String ownersString = metadata.get( cpe.getPath() );
+                    
+                    if( ownersString != null )
+                    {
+                        final Set<Object> owners = decodeOwnersString( ownersString );
+                        itr.set( setOwners( cpe, encodeOwnersString( owners ) ) );
+                        cpchanged = true;
+                    }
+                }
+                
+                if( cpchanged )
+                {
+                    setProjectClasspath( project, cp );
+                }
+            }
+            
+            legacyMetadataFile.delete( true, null );
+        }
+    }
+    
+    private static void validateClasspathEdit( final IJavaProject jproject )
+    
+        throws CoreException
+        
+    {
+        final IWorkspace ws = ResourcesPlugin.getWorkspace();
+        final IProject project = jproject.getProject();
+        final IStatus st = ws.validateEdit( new IFile[] { project.getFile( ".classpath" ) }, IWorkspace.VALIDATE_PROMPT ); //$NON-NLS-1$
+        
+        if( st.getSeverity() == IStatus.ERROR )
+        {
+            throw new CoreException( st );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/FacetCorePlugin.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/FacetCorePlugin.java
new file mode 100644
index 0000000..6d985c5
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/FacetCorePlugin.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 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
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+
+public final class FacetCorePlugin 
+
+    extends Plugin
+
+{
+    public static final String PLUGIN_ID = "org.eclipse.jst.common.project.facet.core"; //$NON-NLS-1$
+    public static final String OUTPUT_FOLDER = "outputFolder"; //$NON-NLS-1$
+    public static final String PROD_PROP_SOURCE_FOLDER_LEGACY = "defaultSource"; //$NON-NLS-1$    
+    private static final String PROD_PROP_SOURCE_FOLDER = "defaultJavaSourceFolder"; //$NON-NLS-1$
+    public static final String DEFAULT_SOURCE_FOLDER = "src"; //$NON-NLS-1$
+    public static final String DEFUALT_OUTPUT_FOLDER ="build/classes"; //$NON-NLS-1$
+    
+    private static FacetCorePlugin inst;
+
+    /**
+     * Get the plugin singleton.
+     */
+    
+    public static FacetCorePlugin getDefault() 
+    {
+        return inst;
+    }
+    
+    public FacetCorePlugin() {
+    	super();
+		if (inst == null)
+			inst = this;
+	}
+    public String getPluginID() 
+    {
+        return PLUGIN_ID;
+    }
+    
+    public static void log( final Exception e )
+    {
+        final ILog log = FacetCorePlugin.getDefault().getLog();
+        final String msg = "Encountered an unexpected exception."; //$NON-NLS-1$
+        
+        log.log( new Status( IStatus.ERROR, PLUGIN_ID, IStatus.OK, msg, e ) );
+    }
+    
+    public static IStatus createErrorStatus( final String msg )
+    {
+        return createErrorStatus( msg, null );
+    }
+
+    public static IStatus createErrorStatus( final String msg,
+                                             final Exception e )
+    {
+        return new Status( IStatus.ERROR, FacetCorePlugin.PLUGIN_ID, 0, msg, e );
+    }
+    
+    
+    
+    public static String getJavaSrcFolder(){
+    	String srcFolder = FacetCorePlugin.getDefault().getPluginPreferences().getString(PROD_PROP_SOURCE_FOLDER_LEGACY);
+    	if( srcFolder == null || srcFolder.equals("") ){ //$NON-NLS-1$
+    		if( Platform.getProduct() != null ){
+    			srcFolder = Platform.getProduct().getProperty( PROD_PROP_SOURCE_FOLDER );
+    		    if( srcFolder == null || srcFolder.equals("")){ //$NON-NLS-1$
+    		    	srcFolder = Platform.getProduct().getProperty( PROD_PROP_SOURCE_FOLDER_LEGACY );
+    		    }      			
+    		}
+	    	if( srcFolder == null || srcFolder.equals("") ){ //$NON-NLS-1$
+	    		srcFolder = DEFAULT_SOURCE_FOLDER;
+	    	}
+
+    	}
+	    return srcFolder;
+    }
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/FacetedProjectFrameworkJavaPlugin.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/FacetedProjectFrameworkJavaPlugin.java
new file mode 100644
index 0000000..e438ee3
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/FacetedProjectFrameworkJavaPlugin.java
@@ -0,0 +1,70 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class FacetedProjectFrameworkJavaPlugin 
+{
+    public static final String PLUGIN_ID = "org.eclipse.jst.common.project.facet.core"; //$NON-NLS-1$
+    
+    private static final ILog platformLog
+        = Platform.getLog( Platform.getBundle( PLUGIN_ID ) );
+    
+    public static IEclipsePreferences getWorkspacePreferences()
+    {
+        final InstanceScope prefs = new InstanceScope();
+        return prefs.getNode( PLUGIN_ID );
+    }
+    
+    public static void log( final Exception e )
+    {
+        final String message = e.getMessage() + ""; //$NON-NLS-1$
+        log( createErrorStatus( message, e ) );
+    }
+
+    public static void log( final IStatus status )
+    {
+        platformLog.log( status );
+    }
+    
+    public static void logError( final String message )
+    {
+        log( createErrorStatus( message ) );
+    }
+    
+    public static IStatus createErrorStatus( final String message )
+    {
+        return createErrorStatus( message, null );
+    }
+
+    public static IStatus createErrorStatus( final Exception e )
+    {
+        return createErrorStatus( e.getMessage(), e );
+    }
+    
+    public static IStatus createErrorStatus( final String message,
+                                             final Exception e )
+    {
+        return new Status( IStatus.ERROR, PLUGIN_ID, -1, message, e )  ;      
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDefaultVersionProvider.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDefaultVersionProvider.java
new file mode 100644
index 0000000..80dded5
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDefaultVersionProvider.java
@@ -0,0 +1,53 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jst.common.project.facet.core.JavaFacet;
+import org.eclipse.wst.common.project.facet.core.IDefaultVersionProvider;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * Defaults the java facet version to align with workspace java compiler
+ * level settings.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetDefaultVersionProvider
+
+    implements IDefaultVersionProvider
+    
+{
+    public IProjectFacetVersion getDefaultVersion()
+    {
+        final String compilerLevel = JavaFacetUtil.getCompilerLevel();
+        
+        if( JavaFacet.FACET.hasVersion( compilerLevel ) )
+        {
+            return JavaFacet.FACET.getVersion( compilerLevel );
+        }
+        else
+        {
+            try
+            {
+                return JavaFacet.FACET.getLatestVersion();
+            }
+            catch( CoreException e )
+            {
+                // Not expected for this facet.
+                
+                throw new RuntimeException( e );
+            }
+        }
+    }
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDelegate.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDelegate.java
new file mode 100644
index 0000000..d661fc0
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDelegate.java
@@ -0,0 +1,101 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jst.common.project.facet.core.ClasspathHelper;
+import org.eclipse.wst.common.project.facet.core.FacetedProjectFrameworkException;
+import org.eclipse.wst.common.project.facet.core.IDelegate;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public abstract class JavaFacetDelegate 
+
+    implements IDelegate 
+    
+{
+    protected static final class RelevantFiles
+    {
+        public final IFile dotProjectFile;
+        public final IFile dotClasspathFile;
+        public final IFile jdtCorePrefsFile;
+        public final IFile jstFacetCorePrefsFile;
+        
+        public RelevantFiles( final IProject project )
+        {
+            this.dotProjectFile = project.getFile( IProjectDescription.DESCRIPTION_FILE_NAME );
+            this.dotClasspathFile = project.getFile( JavaFacetUtil.FILE_CLASSPATH );
+            this.jdtCorePrefsFile = project.getFile( JavaFacetUtil.FILE_JDT_CORE_PREFS );
+            this.jstFacetCorePrefsFile = project.getFile( ClasspathHelper.LEGACY_METADATA_FILE_NAME );
+        }
+    }
+    
+    protected static void validateEdit( final IProject project )
+    
+        throws CoreException
+        
+    {
+        validateEdit( new RelevantFiles( project ) );
+    }
+    
+    protected static void validateEdit( final RelevantFiles files )
+    
+        throws CoreException
+        
+    {
+        final List<IFile> list = new ArrayList<IFile>();
+        
+        list.add( files.dotProjectFile );
+        
+        if( files.dotClasspathFile.exists() )
+        {
+            list.add( files.dotClasspathFile );
+        }
+        
+        if( files.jdtCorePrefsFile.exists() )
+        {
+            list.add( files.jdtCorePrefsFile );
+        }
+        
+        if( files.jstFacetCorePrefsFile.exists() )
+        {
+            list.add( files.jstFacetCorePrefsFile );
+        }
+        
+        final IWorkspace ws = ResourcesPlugin.getWorkspace();
+        
+        final IStatus validateEditStatus 
+            = ws.validateEdit( list.toArray( new IFile[ list.size() ] ), IWorkspace.VALIDATE_PROMPT );
+        
+        if( validateEditStatus.getSeverity() == IStatus.ERROR )
+        {
+            final FacetedProjectFrameworkException e 
+                = new FacetedProjectFrameworkException( validateEditStatus );
+            
+            e.setExpected( true );
+            
+            throw e;
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDetector.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDetector.java
new file mode 100644
index 0000000..cb5fb83
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetDetector.java
@@ -0,0 +1,202 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+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.jdt.core.JavaCore;
+import org.eclipse.jst.common.project.facet.core.JavaFacet;
+import org.eclipse.jst.common.project.facet.core.JavaFacetInstallConfig;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetDetector;
+
+public final class JavaFacetDetector
+
+    extends ProjectFacetDetector
+    
+{
+    private static final Pattern IMPORT_STATEMENT_PATTERN = Pattern.compile( ".*package[ ]*(.*);.*" ); //$NON-NLS-1$
+    
+    public static void main( final String[] args )
+    {
+        final Matcher matcher = IMPORT_STATEMENT_PATTERN.matcher( "package a.b.c;" ); //$NON-NLS-1$
+        
+        if( matcher.matches() )
+        {
+            System.err.println( matcher.group( 1 ) );
+        }
+        else
+        {
+            System.err.println( "no match" ); //$NON-NLS-1$
+        }
+    }
+    
+    @Override
+    public void detect( final IFacetedProjectWorkingCopy fpjwc,
+                        final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        monitor.beginTask( "", 1 ); //$NON-NLS-1$
+        
+        try
+        {
+            if( fpjwc.hasProjectFacet( JavaFacet.FACET ) )
+            {
+                return;
+            }
+            
+            if( fpjwc.getProject().hasNature( JavaCore.NATURE_ID ) )
+            {
+                fpjwc.addProjectFacet( JavaFacet.FACET.getDefaultVersion() );
+            }
+            else
+            {
+                final IProject pj = fpjwc.getProject();
+                final List<IPath> sourceFolders = detectSourceFolders( pj );
+                
+                if( ! sourceFolders.isEmpty() )
+                {
+                    fpjwc.addProjectFacet( JavaFacet.FACET.getDefaultVersion() );
+                    
+                    final JavaFacetInstallConfig javaFacetInstallConfig
+                        = (JavaFacetInstallConfig) fpjwc.getProjectFacetAction( JavaFacet.FACET ).getConfig();
+                    
+                    javaFacetInstallConfig.setSourceFolders( sourceFolders );
+                    javaFacetInstallConfig.setDefaultOutputFolder( null );
+                }
+            }
+        }
+        finally
+        {
+            monitor.done();
+        }
+    }
+    
+    private List<IPath> detectSourceFolders( final IResource resource )
+    
+        throws CoreException
+        
+    {
+        if( resource instanceof IFile )
+        {
+            final String extension = resource.getFileExtension();
+            
+            if( extension != null && extension.equals( "java" ) ) //$NON-NLS-1$
+            {
+                final InputStream in = ( (IFile) resource ).getContents( true );
+                
+                try
+                {
+                    final BufferedReader reader = new BufferedReader( new InputStreamReader( in ) );
+                    
+                    for( String line = reader.readLine(); line != null; line = reader.readLine() )
+                    {
+                        final Matcher matcher = IMPORT_STATEMENT_PATTERN.matcher( line );
+                        
+                        if( matcher.matches() )
+                        {
+                            final String packageName = matcher.group( 1 );
+                            final IPath packagePath = new Path( packageName.replace( '.', '/' ) );
+                            final int packagePathLength = packagePath.segmentCount();
+                            
+                            IPath path = resource.getProjectRelativePath().removeLastSegments( 1 );
+                            
+                            if( path.segmentCount() > packagePathLength )
+                            {
+                                for( int i = packagePathLength - 1; i >= 0; i-- )
+                                {
+                                    if( path.lastSegment().equals( packagePath.segment( i ) ) )
+                                    {
+                                        path = path.removeLastSegments( 1 );
+                                    }
+                                    else
+                                    {
+                                        return Collections.emptyList();
+                                    }
+                                }
+                                
+                                return Collections.singletonList( path );
+                            }
+                            else
+                            {
+                                return Collections.emptyList();
+                            }
+                        }
+                    }
+                }
+                catch( IOException e )
+                {
+                    FacetCorePlugin.log( e );
+                }
+                finally
+                {
+                    try
+                    {
+                        in.close();
+                    }
+                    catch( IOException e ) {}
+                }
+            }
+            
+            return Collections.emptyList();
+        }
+        else
+        {
+            List<IPath> result = null;
+            
+            for( IResource child : ( (IContainer) resource ).members() )
+            {
+                final List<IPath> subResult = detectSourceFolders( child );
+                final IPath childPath = child.getProjectRelativePath();
+
+                if( ! subResult.isEmpty() )
+                {
+                    final IPath subResultPath = subResult.get( 0 );
+                    
+                    if( subResult.size() == 1 && subResultPath.isPrefixOf( childPath ) && 
+                        childPath.segmentCount() > subResultPath.segmentCount() )
+                    {
+                        return subResult;
+                    }
+                    
+                    if( result == null )
+                    {
+                        result = new ArrayList<IPath>();
+                    }
+                    
+                    result.addAll( subResult );
+                }
+            }
+            
+            return ( result == null ? Collections.<IPath>emptyList() : result );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetInstallConfigFactory.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetInstallConfigFactory.java
new file mode 100644
index 0000000..23817b8
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetInstallConfigFactory.java
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import org.eclipse.jst.common.project.facet.core.JavaFacetInstallConfig;
+import org.eclipse.wst.common.project.facet.core.IActionConfigFactory;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetInstallConfigFactory
+
+    implements IActionConfigFactory
+    
+{
+    public Object create() 
+    {
+        return new JavaFacetInstallConfig();
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetInstallDelegate.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetInstallDelegate.java
new file mode 100644
index 0000000..52c39e6
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetInstallDelegate.java
@@ -0,0 +1,195 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+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.IResourceStatus;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdapterManager;
+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.Platform;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jst.common.project.facet.core.JavaFacetInstallConfig;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetInstallDelegate 
+
+    extends JavaFacetDelegate 
+    
+{
+    public void execute( final IProject project, 
+                         final IProjectFacetVersion fv, 
+                         final Object cfg, 
+                         final IProgressMonitor monitor ) 
+    
+        throws CoreException 
+        
+    {
+        validateEdit( project );
+        
+        final JavaFacetInstallConfig config = castToConfig( cfg );
+
+        // Create the source and the output directories.
+
+        IJavaProject jproject = null;
+        
+        if( project.exists() )
+        {
+            jproject = JavaCore.create( project );
+        }
+        
+        if( ! jproject.exists() )
+        {
+            final List<IClasspathEntry> cp = new ArrayList<IClasspathEntry>();
+            
+            for( IPath srcFolderPath : config.getSourceFolders() )
+            {
+                final IFolder folder = createFolder( project, srcFolderPath, false );
+                cp.add( JavaCore.newSourceEntry( folder.getFullPath() ) );
+            }
+            
+            final IPath defOutputPath = config.getDefaultOutputFolder();
+            IFolder defOutputFolder = null;
+            
+            if( defOutputPath != null )
+            {
+                defOutputFolder = createFolder( project, config.getDefaultOutputFolder(), true );
+            }
+
+            // Add the java nature. This will automatically add the builder.
+
+            final IProjectDescription desc = project.getDescription();
+            final String[] current = desc.getNatureIds();
+            final String[] replacement = new String[ current.length + 1 ];
+            System.arraycopy( current, 0, replacement, 0, current.length );
+            replacement[ current.length ] = JavaCore.NATURE_ID;
+            desc.setNatureIds( replacement );
+            project.setDescription( desc, null );
+
+            // Setup the classpath.
+            
+            if( defOutputFolder == null )
+            {
+                jproject.setRawClasspath( cp.toArray( new IClasspathEntry[ cp.size() ] ), null ); 
+            }
+            else
+            {
+                jproject.setRawClasspath( cp.toArray( new IClasspathEntry[ cp.size() ] ), 
+                                          defOutputFolder.getFullPath(), null );
+            }
+
+            JavaFacetUtil.resetClasspath( project, null, fv );
+            JavaFacetUtil.setCompilerLevel( project, fv );
+        }
+        else
+        {
+            // Set the compiler compliance level for the project. Ignore whether
+            // this might already be set so at the workspace level in case
+            // workspace settings change later or the project is included in a
+            // different workspace.
+            
+            String oldCompilerLevel = JavaFacetUtil.getCompilerLevel( project );
+            JavaFacetUtil.setCompilerLevel( project, fv );
+            
+            String newCompilerLevel = JavaFacetUtil.getCompilerLevel( project );
+            
+            // Schedule a full build of the project if the compiler level changed
+            // because we want classes in the project to be recompiled.
+            
+            if( newCompilerLevel != null && ! newCompilerLevel.equals( oldCompilerLevel ) )
+            {
+                JavaFacetUtil.scheduleFullBuild( project );
+            }
+        }
+    }
+    
+    private static JavaFacetInstallConfig castToConfig( final Object cfg )
+    {
+        if( cfg instanceof JavaFacetInstallConfig )
+        {
+            return (JavaFacetInstallConfig) cfg;
+        }
+        else
+        {
+            final IAdapterManager manager = Platform.getAdapterManager();
+            return (JavaFacetInstallConfig) manager.getAdapter( cfg, JavaFacetInstallConfig.class );
+        }
+    }
+    
+    private static IFolder createFolder( final IProject project,
+                                         final IPath path,
+                                         final boolean isDerived )
+    
+        throws CoreException
+        
+    {
+        IContainer current = project;
+        
+        for( int i = 0, n = path.segmentCount(); i < n; i++ )
+        {
+            final String name = path.segment( i );
+            IFolder folder = current.getFolder( new Path( name ) );
+            
+            if( ! folder.exists() )
+            {
+                try
+                {
+                    folder.create( true, true, null );
+                    folder.setDerived( isDerived, null );
+                }
+                catch( CoreException e )
+                {
+                    // Eclipse Resources API is always case sensitive regardless of the underlying
+                    // file system. In particular, IResource.exists() call will return false on
+                    // case collision, but the create() call will fail.
+                    
+                    final IStatus st = e.getStatus();
+                    
+                    if( st.getCode() != IResourceStatus.CASE_VARIANT_EXISTS )
+                    {
+                        throw e;
+                    }
+                    
+                    for( IResource resource : current.members() )
+                    {
+                        if( resource instanceof IFolder && resource.getName().equalsIgnoreCase( name ) )
+                        {
+                            folder = (IFolder) resource;
+                            break;
+                        }
+                    }
+                }
+            }
+            
+            current = folder;
+        }
+        
+        return (IFolder) current;
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetRuntimeChangedListener.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetRuntimeChangedListener.java
new file mode 100644
index 0000000..13ab0a6
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetRuntimeChangedListener.java
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jst.common.project.facet.core.JavaFacet;
+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.events.IFacetedProjectEvent;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetRuntimeChangedListener 
+
+    implements IFacetedProjectListener
+    
+{
+    public void handleEvent( final IFacetedProjectEvent event )
+    {
+        final IFacetedProject fproj = event.getProject();
+        
+        if( fproj.hasProjectFacet( JavaFacet.FACET ) )
+        {
+            final IProjectFacetVersion fv = fproj.getInstalledVersion( JavaFacet.FACET );
+            
+            try
+            {
+                JavaFacetUtil.resetClasspath( fproj.getProject(), fv, fv );
+            }
+            catch( CoreException e )
+            {
+                FacetedProjectFrameworkJavaPlugin.log( e );
+            }
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUninstallConfigFactory.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUninstallConfigFactory.java
new file mode 100644
index 0000000..9e2dbe5
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUninstallConfigFactory.java
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import org.eclipse.jst.common.project.facet.core.JavaFacetUninstallConfig;
+import org.eclipse.wst.common.project.facet.core.IActionConfigFactory;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetUninstallConfigFactory
+
+    implements IActionConfigFactory
+    
+{
+    public Object create() 
+    {
+        return new JavaFacetUninstallConfig();
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUninstallDelegate.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUninstallDelegate.java
new file mode 100644
index 0000000..12c63b4
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUninstallDelegate.java
@@ -0,0 +1,130 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+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.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetUninstallDelegate 
+
+    extends JavaFacetDelegate 
+    
+{
+    public void execute( final IProject project, 
+                         final IProjectFacetVersion fv, 
+                         final Object cfg, 
+                         final IProgressMonitor monitor ) 
+    
+        throws CoreException 
+        
+    {
+        final RelevantFiles files = new RelevantFiles( project );
+
+        validateEdit( files );
+        
+        // Find output directories. They will be removed later.
+        
+        final List<IPath> outputFolders = new ArrayList<IPath>();
+        
+        try
+        {
+            final IJavaProject jproj = JavaCore.create( project );
+            
+            outputFolders.add( jproj.getOutputLocation() );
+            
+            for( IClasspathEntry cpe : jproj.getRawClasspath() )
+            {
+                outputFolders.add( cpe.getOutputLocation() );
+            }
+        }
+        catch( Exception e )
+        {
+            // Ignore the exception since we tearing down and the user might be doing this
+            // because the project is corrupted.
+        }
+        
+        // Remove java nature. This will automatically remove the builder.
+
+        final IProjectDescription desc = project.getDescription();
+        final List<String> natures = new ArrayList<String>();
+        
+        for( String nature : desc.getNatureIds() )
+        {
+            if( ! nature.equals( JavaCore.NATURE_ID ) )
+            {
+                natures.add( nature );
+            }
+        }
+        
+        desc.setNatureIds( natures.toArray( new String[ natures.size() ] ) );
+        project.setDescription( desc, null );
+
+        // Delete various metadata files.
+        
+        files.dotClasspathFile.delete( true, null );
+        files.jdtCorePrefsFile.delete( true, null );
+        files.jstFacetCorePrefsFile.delete( true, null );
+        
+        // Delete all the output folders and their contents.
+        
+        final IWorkspace ws = ResourcesPlugin.getWorkspace();
+        
+        for( IPath path : outputFolders )
+        {
+            if( path != null )
+            {
+                delete( ws.getRoot().getFolder( path ) );
+            }
+        }
+    }
+    
+    private static final void delete( final IFolder folder )
+    
+        throws CoreException
+        
+    {
+        final IContainer parent = folder.getParent();
+        
+        if( parent instanceof IFolder &&
+            parent.members( IContainer.INCLUDE_HIDDEN | IContainer.INCLUDE_PHANTOMS | 
+                            IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS ).length == 1 )
+        {
+            delete( (IFolder) parent );
+        }
+        else
+        {
+            if( folder.exists() )
+            {
+                folder.delete( true, null );
+            }
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUtil.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUtil.java
new file mode 100644
index 0000000..e2a5723
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUtil.java
@@ -0,0 +1,255 @@
+/******************************************************************************
+ * Copyright (c) 2010, 2014 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+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.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jst.common.project.facet.core.ClasspathHelper;
+import org.eclipse.jst.common.project.facet.core.JavaFacet;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetUtil
+{
+    public static final String FILE_CLASSPATH = ".classpath";  //$NON-NLS-1$
+    public static final String FILE_JDT_CORE_PREFS = ".settings/org.eclipse.jdt.core.prefs"; //$NON-NLS-1$
+    
+    private static final IPath CPE_PREFIX_FOR_EXEC_ENV 
+        = new Path( "org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType" ); //$NON-NLS-1$
+    
+    private static final Map<IProjectFacetVersion,String> FACET_VER_TO_EXEC_ENV = new HashMap<IProjectFacetVersion,String>();
+    
+    static
+    {
+        FACET_VER_TO_EXEC_ENV.put( JavaFacet.VERSION_1_3, "J2SE-1.3" ); //$NON-NLS-1$
+        FACET_VER_TO_EXEC_ENV.put( JavaFacet.VERSION_1_4, "J2SE-1.4" ); //$NON-NLS-1$
+        FACET_VER_TO_EXEC_ENV.put( JavaFacet.VERSION_1_5, "J2SE-1.5" ); //$NON-NLS-1$
+        FACET_VER_TO_EXEC_ENV.put( JavaFacet.VERSION_1_6, "JavaSE-1.6" ); //$NON-NLS-1$
+        FACET_VER_TO_EXEC_ENV.put( JavaFacet.VERSION_1_7, "JavaSE-1.7" ); //$NON-NLS-1$
+        FACET_VER_TO_EXEC_ENV.put( JavaFacet.VERSION_1_8, "JavaSE-1.8" ); //$NON-NLS-1$
+    }
+    
+    public static String getCompilerLevel()
+    {
+        String level = JavaCore.getOption( JavaCore.COMPILER_COMPLIANCE );
+        
+        if( level == null )
+        {
+            final Hashtable<?,?> defaults = JavaCore.getDefaultOptions();
+            level = (String) defaults.get( JavaCore.COMPILER_COMPLIANCE );
+        }
+        
+        return level;
+    }
+
+    public static String getCompilerLevel( final IProject project )
+    {
+        final IJavaProject jproj = JavaCore.create( project );
+        String level = jproj.getOption( JavaCore.COMPILER_COMPLIANCE, false );
+        
+        if( level == null )
+        {
+            level = getCompilerLevel();
+        }
+        
+        return level;
+    }
+    
+    public static void setCompilerLevel( final IProject project,
+                                         final IProjectFacetVersion fv )
+    
+        throws CoreException
+        
+    {
+        setCompilerLevel( project, fv.getVersionString() );
+    }
+
+    public static void setCompilerLevel( final IProject project,
+                                         final String level )
+    
+        throws CoreException
+        
+    {
+        final IJavaProject jproj = JavaCore.create( project );
+        final Map<String, String> options = jproj.getOptions( false );
+        JavaCore.setComplianceOptions( level, options );
+        jproj.setOptions( options );
+    }
+    
+    public static void scheduleFullBuild( final IProject project )
+    {
+        // This code is modeled after the code in 
+        // org.eclipse.jdt.internal.ui.util.CoreUtility.getBuildJob() method.
+        
+        final IWorkspace ws = ResourcesPlugin.getWorkspace();
+        
+        final String msg 
+            = NLS.bind( Resources.buildingMsg, project.getName() );
+        
+        final Job buildJob = new Job( msg ) 
+        {
+            public IStatus run( final IProgressMonitor monitor ) 
+            {
+                monitor.beginTask( msg, 2 );
+                
+                try
+                {
+                    project.build( IncrementalProjectBuilder.FULL_BUILD,
+                                   new SubProgressMonitor( monitor, 1 ) );
+                    
+                    ws.build( IncrementalProjectBuilder.INCREMENTAL_BUILD, 
+                              new SubProgressMonitor( monitor, 1 ) );
+                    
+                }
+                catch( CoreException e )
+                {
+                    return e.getStatus();
+                }
+                finally
+                {
+                    monitor.done();
+                }
+                
+                return Status.OK_STATUS;
+            }
+            
+            public boolean belongsTo( final Object family ) 
+            {
+                return family == ResourcesPlugin.FAMILY_MANUAL_BUILD;
+            }
+        };
+         
+        buildJob.setRule( ws.getRuleFactory().buildRule() );
+        buildJob.schedule();
+    }
+    
+    public static void resetClasspath( final IProject project,
+                                       final IProjectFacetVersion oldver,
+                                       final IProjectFacetVersion newver )
+    
+        throws CoreException
+        
+    {
+        if( oldver != null )
+        {
+            ClasspathHelper.removeClasspathEntries( project, oldver );
+        }
+        
+        // If this was a java project before it became a faceted project or
+        // the JRE container has been added manually, the above method will not
+        // delete the old JRE container. Do it manually.
+        
+        removeJreContainer( project );
+        
+        if( ! ClasspathHelper.addClasspathEntries( project, newver ) ) 
+        {
+            final IVMInstall vm = JavaRuntime.getDefaultVMInstall();
+            
+            if( vm != null )
+            {
+                final IPath path = CPE_PREFIX_FOR_EXEC_ENV.append( getCorrespondingExecutionEnvironment( newver ) );
+                final IClasspathEntry cpe = JavaCore.newContainerEntry( path );
+                final List<IClasspathEntry> entries = Collections.singletonList( cpe );
+                
+                ClasspathHelper.addClasspathEntries( project, newver, entries );
+            }
+        }
+    }
+    
+    private static void removeJreContainer( final IProject proj ) 
+    
+        throws CoreException
+        
+    {
+        final IJavaProject jproj = JavaCore.create( proj );
+        final IClasspathEntry[] cp = jproj.getRawClasspath();
+        
+        int pos = -1;
+        
+        for( int i = 0; i < cp.length; i++ )
+        {
+            final IClasspathEntry cpe = cp[ i ];
+            
+            if( cpe.getEntryKind() == IClasspathEntry.CPE_CONTAINER &&
+                cpe.getPath().segment( 0 ).equals( JavaRuntime.JRE_CONTAINER ) )
+            {
+                pos = i;
+                break;
+            }
+        }
+            
+        if( pos == -1 )
+        {
+            return;
+        }
+        
+        final IClasspathEntry[] newcp 
+            = new IClasspathEntry[ cp.length - 1 ];
+        
+        System.arraycopy( cp, 0, newcp, 0, pos );
+        System.arraycopy( cp, pos + 1, newcp, pos, newcp.length - pos );
+        
+        jproj.setRawClasspath( newcp, null );
+    }
+    
+    public static String getCorrespondingExecutionEnvironment( final IProjectFacetVersion fv )
+    {
+        final String res = FACET_VER_TO_EXEC_ENV.get( fv );
+        
+        if( res == null )
+        {
+            throw new IllegalArgumentException( fv.toString() );
+        }
+        
+        return res;
+    }
+    
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String buildingMsg;
+        
+        static
+        {
+            initializeMessages( JavaFacetUtil.class.getName(), 
+                                Resources.class );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUtil.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUtil.properties
new file mode 100644
index 0000000..b8e00de
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetUtil.properties
@@ -0,0 +1 @@
+buildingMsg = Building Project {0}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetValidator.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetValidator.java
new file mode 100644
index 0000000..5b7e991
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetValidator.java
@@ -0,0 +1,71 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jst.common.project.facet.core.JavaFacet;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectValidator;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetValidator
+
+    implements IFacetedProjectValidator
+    
+{
+    public static final String MARKER_ID
+        = "org.eclipse.jst.common.project.facet.core.javaVersionMismatch"; //$NON-NLS-1$
+    
+    public static final String ATTR_FACET_VERSION = "facetVersion"; //$NON-NLS-1$
+    public static final String ATTR_COMPILER_LEVEL = "compilerLevel"; //$NON-NLS-1$
+
+    public void validate( final IFacetedProject fproj ) 
+    
+        throws CoreException
+        
+    {
+        final String level 
+            = JavaFacetUtil.getCompilerLevel( fproj.getProject() );
+        
+        final IProjectFacetVersion fv = fproj.getInstalledVersion( JavaFacet.FACET );
+        
+        if( ! JavaFacet.FACET.hasVersion( level ) || JavaFacet.FACET.getVersion( level ) != fv )
+        {
+            final IMarker marker
+                = fproj.createErrorMarker( MARKER_ID, Resources.versionsDontMatch );
+            
+            marker.setAttribute( ATTR_FACET_VERSION, fv.getVersionString() );
+            marker.setAttribute( ATTR_COMPILER_LEVEL, level );
+        }
+    }
+    
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String versionsDontMatch;
+        
+        static
+        {
+            initializeMessages( JavaFacetValidator.class.getName(), 
+                                Resources.class );
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetValidator.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetValidator.properties
new file mode 100644
index 0000000..7c1e870
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetValidator.properties
@@ -0,0 +1 @@
+versionsDontMatch = Java compiler level does not match the version of the installed Java project facet.
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetVersionChangeConfigFactory.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetVersionChangeConfigFactory.java
new file mode 100644
index 0000000..fb2b6db
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetVersionChangeConfigFactory.java
@@ -0,0 +1,31 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import org.eclipse.jst.common.project.facet.core.JavaFacetVersionChangeConfig;
+import org.eclipse.wst.common.project.facet.core.IActionConfigFactory;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetVersionChangeConfigFactory
+
+    implements IActionConfigFactory
+    
+{
+    public Object create() 
+    {
+        return new JavaFacetVersionChangeConfig();
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetVersionChangeDelegate.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetVersionChangeDelegate.java
new file mode 100644
index 0000000..6bcabd1
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaFacetVersionChangeDelegate.java
@@ -0,0 +1,80 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+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.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaFacetVersionChangeDelegate 
+
+    implements IDelegate
+    
+{
+    public void execute( final IProject project, 
+                         final IProjectFacetVersion fv,
+                         final Object cfg,
+                         final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        if( monitor != null )
+        {
+            monitor.beginTask( "", 1 ); //$NON-NLS-1$
+        }
+        
+        try
+        {
+            // Find the version that's currently installed.
+            
+            final IFacetedProject fproj
+                = ProjectFacetsManager.create( project );
+
+            final IProjectFacetVersion oldver
+                = fproj.getInstalledVersion( fv.getProjectFacet() );
+            
+            // Reset the classpath. 
+            
+            JavaFacetUtil.resetClasspath( project, oldver, fv );
+            
+            // Reset the compiler level.
+            
+            JavaFacetUtil.setCompilerLevel( project, fv );
+            
+            // Schedule a full build of the project.
+            
+            JavaFacetUtil.scheduleFullBuild( project );
+            
+            if( monitor != null )
+            {
+                monitor.worked( 1 );
+            }
+        }
+        finally
+        {
+            if( monitor != null )
+            {
+                monitor.done();
+            }
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaRuntimeBridge.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaRuntimeBridge.java
new file mode 100644
index 0000000..35b57fa
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/JavaRuntimeBridge.java
@@ -0,0 +1,94 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMInstallType;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jst.common.project.facet.core.StandardJreRuntimeComponent;
+import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeBridge;
+import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponent;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class JavaRuntimeBridge
+
+    implements IRuntimeBridge
+    
+{
+    public Set<String> getExportedRuntimeNames() throws CoreException
+    {
+        final Set<String> result = new HashSet<String>();
+        
+        for( IVMInstallType vmInstallType : JavaRuntime.getVMInstallTypes() )
+        {
+            for( IVMInstall vmInstall : vmInstallType.getVMInstalls() )
+            {
+                result.add( vmInstall.getName() );
+            }
+        }
+
+        return result;
+    }
+
+    
+    public IStub bridge( final String name ) throws CoreException
+    {
+        IVMInstall vmInstall = null;
+        
+        for( IVMInstallType vmInstallType : JavaRuntime.getVMInstallTypes() )
+        {
+            vmInstall = vmInstallType.findVMInstallByName( name );
+            
+            if( vmInstall != null )
+            {
+                break;
+            }
+        }
+        
+        return new Stub( vmInstall );
+    }
+
+    private static class Stub
+    
+        extends IRuntimeBridge.Stub
+        
+    {
+        private final IVMInstall vmInstall;
+
+        public Stub( final IVMInstall vmInstall )
+        {
+            this.vmInstall = vmInstall;
+        }
+
+        public List<IRuntimeComponent> getRuntimeComponents()
+        {
+            final IRuntimeComponent rc = StandardJreRuntimeComponent.create( this.vmInstall );
+            return Collections.singletonList( rc );
+        }
+
+        public Map<String,String> getProperties()
+        {
+            return Collections.emptyMap();
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/RuntimeClasspathProvider.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/RuntimeClasspathProvider.java
new file mode 100644
index 0000000..5e7289d
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/RuntimeClasspathProvider.java
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.jst.common.project.facet.core.IClasspathProvider;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
+import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponent;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class RuntimeClasspathProvider
+
+    implements IClasspathProvider
+    
+{
+    private final IRuntime r;
+    
+    public RuntimeClasspathProvider( final IRuntime r )
+    {
+        this.r = r;
+    }
+
+    public List getClasspathEntries( final IProjectFacetVersion fv )
+    {
+        for( Iterator itr = this.r.getRuntimeComponents().iterator(); 
+             itr.hasNext(); )
+        {
+            final IRuntimeComponent rc = (IRuntimeComponent) itr.next();
+            
+            final IClasspathProvider cpprov 
+                = (IClasspathProvider) rc.getAdapter( IClasspathProvider.class );
+            
+            if( cpprov != null )
+            {
+                final List cp = cpprov.getClasspathEntries( fv );
+                
+                if( cp != null )
+                {
+                    return cp;
+                }
+            }
+        }
+        
+        return null;
+    }
+    
+    public static final class Factory
+    
+        implements IAdapterFactory
+        
+    {
+        private static final Class[] ADAPTER_TYPES = { IClasspathProvider.class };
+        
+        public Object getAdapter( final Object adaptable, 
+                                  final Class adapterType )
+        {
+            if( adapterType == IClasspathProvider.class )
+            {
+                return new RuntimeClasspathProvider( (IRuntime) adaptable );
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+        public Class[] getAdapterList()
+        {
+            return ADAPTER_TYPES;
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/StandardJreClasspathProvider.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/StandardJreClasspathProvider.java
new file mode 100644
index 0000000..63b8a1f
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/internal/StandardJreClasspathProvider.java
@@ -0,0 +1,107 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.internal;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMInstallType;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jst.common.project.facet.core.IClasspathProvider;
+import org.eclipse.jst.common.project.facet.core.JavaFacet;
+import org.eclipse.jst.common.project.facet.core.StandardJreRuntimeComponent;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponent;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class StandardJreClasspathProvider 
+
+    implements IClasspathProvider 
+    
+{
+	private IRuntimeComponent rc;
+
+	public StandardJreClasspathProvider( final IRuntimeComponent rc ) 
+	{
+		this.rc = rc;
+	}
+
+	public List<IClasspathEntry> getClasspathEntries( final IProjectFacetVersion fv ) 
+	{
+		if( fv.getProjectFacet() == JavaFacet.FACET ) 
+		{
+		    final IVMInstall vmInstall = getVMInstall();
+		    
+		    if( vmInstall != null )
+		    {
+		        final IPath cpEntryPath = JavaRuntime.newJREContainerPath( vmInstall );
+		        final IClasspathEntry cpEntry = JavaCore.newContainerEntry( cpEntryPath );
+		        
+		        return Collections.singletonList( cpEntry );
+		    }
+		}
+		
+		return null;
+	}
+	
+	private IVMInstall getVMInstall()
+	{
+	    final String vmInstallTypeId 
+	        = this.rc.getProperty( StandardJreRuntimeComponent.PROP_VM_INSTALL_TYPE );
+	    
+	    final String vmInstallId
+	        = this.rc.getProperty( StandardJreRuntimeComponent.PROP_VM_INSTALL_ID );
+	    
+	    if( vmInstallTypeId == null || vmInstallId == null )
+	    {
+	        return null;
+	    }
+	    
+	    final IVMInstallType vmInstallType = JavaRuntime.getVMInstallType( vmInstallTypeId );
+	    
+	    if( vmInstallType == null )
+	    {
+	        return null;
+	    }
+	    
+	    return vmInstallType.findVMInstall( vmInstallId );
+	}
+
+	public static final class Factory
+	
+	    implements IAdapterFactory 
+	
+	{
+		private static final Class[] ADAPTER_TYPES = { IClasspathProvider.class };
+
+		public Class[] getAdapterList() 
+		{
+            return ADAPTER_TYPES;
+        }
+
+		public Object getAdapter( final Object adaptable, 
+		                          final Class adapterType ) 
+		{
+			IRuntimeComponent rc = (IRuntimeComponent) adaptable;
+			return new StandardJreClasspathProvider(rc);
+		}
+	}
+	
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/EnablementExpressionContext.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/EnablementExpressionContext.java
new file mode 100644
index 0000000..a3eae6f
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/EnablementExpressionContext.java
@@ -0,0 +1,61 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * Contains all of the information available in the context of library provider enablement
+ * expression. Useful for writing custom property testers.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public final class EnablementExpressionContext
+{
+    private final IFacetedProjectBase fproj;
+    private final IProjectFacetVersion fv;
+    private final ILibraryProvider provider;
+    
+    public EnablementExpressionContext( final IFacetedProjectBase fproj,
+                                        final IProjectFacetVersion fv,
+                                        final ILibraryProvider provider )
+    {
+        this.fproj = fproj;
+        this.fv = fv;
+        this.provider = provider;
+    }
+    
+    public IFacetedProjectBase getFacetedProject()
+    {
+        return this.fproj;
+    }
+    
+    public IProjectFacet getRequestingProjectFacet()
+    {
+        return this.fv.getProjectFacet();
+    }
+    
+    public IProjectFacetVersion getRequestingProjectFacetVersion()
+    {
+        return this.fv;
+    }
+    
+    public ILibraryProvider getLibraryProvider()
+    {
+        return this.provider;
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/ILibraryProvider.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/ILibraryProvider.java
new file mode 100644
index 0000000..b2657fc
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/ILibraryProvider.java
@@ -0,0 +1,150 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import java.util.Map;
+
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * Represents a single library provider as declared to the framework.
+ * 
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public interface ILibraryProvider
+
+    extends Comparable<ILibraryProvider>
+    
+{
+    /**
+     * Returns the id of the library provider. Each library provider must have a unique id.
+     * 
+     * @return the id of the library provider
+     */
+    
+    String getId();
+    
+    /**
+     * Returns the id of the plugin that declares this library provider.
+     * 
+     * @return the id of the plugin that declares this library provider
+     */
+    
+    String getPluginId();
+    
+    /**
+     * Returns the library provider label. This is the text that will be presented to the user
+     * when referencing this library provider. The user never sees the library provider id. The
+     * label can be translated.
+     * 
+     * @return the library provider label
+     */
+    
+    String getLabel();
+    
+    /**
+     * Returns the library provider that this provider extends or <code>null</code> if this
+     * library provider doesn't extend anything.
+     * 
+     * @return the library provider that this provider extends or <code>null</code>
+     */
+    
+    ILibraryProvider getBaseProvider();
+    
+    /**
+     * Returns the root library provider in the extension chain. If this library provider does
+     * not extend another, this method call will return this provider.
+     * 
+     * @return the root library provider in the extension chain
+     */
+    
+    ILibraryProvider getRootProvider();
+    
+    /**
+     * Indicates whether this library provider is only meant to be used as a base for other
+     * providers and not to be used directly.
+     * 
+     * @return <code>true</code> if this library provider is only meant to be used as a base
+     *   for other providers
+     */
+    
+    boolean isAbstract();
+    
+    /**
+     * Indicates whether this library provider is meant to be hidden from the user. This
+     * typically means that it cannot be installed.
+     * 
+     * @return <code>true</code> if this library provider is meant to be hidden from the user
+     */
+    
+    boolean isHidden();
+    
+    /**
+     * Returns the priority number of this library provider. Each library provider can be assigned
+     * a priority number that is used when sorting applicable providers in order to present
+     * providers to the user. Higher priority numbers are sorted first. The provider with the
+     * highest priority in the set of applicable providers is one that is selected by default.
+     * 
+     * @return the priority number of this library provider
+     */
+    
+    int getPriority();
+    
+    /**
+     * Checks whether this provider is enabled for the given context.
+     * 
+     * @param fpjwc the faceted project (or working copy)
+     * @param fv the project facet that is making the request for libraries
+     * @return <code>true</code> if this provider is enabled for the given context
+     */
+    
+    boolean isEnabledFor( IFacetedProjectBase fproj, 
+                          IProjectFacetVersion fv );
+    
+    /**
+     * Checks whether this provider is enabled for the given context.
+     * 
+     * @param fpjwc the faceted project (or working copy)
+     * @param fv the project facet that is making the request for libraries
+     * @param customVariables custom variables to add to the enablement expressions
+     *   evaluation context
+     * @return <code>true</code> if this provider is enabled for the given context
+     */
+    
+    boolean isEnabledFor( IFacetedProjectBase fproj, 
+                          IProjectFacetVersion fv,
+                          Map<String,Object> customVariables );
+    
+    /**
+     * Determines whether this provider supports the specified action type.
+     * 
+     * @param type the action type to check
+     * @return <code>true</code> if this provider supports the specified action type
+     */
+    
+    boolean isActionSupported( LibraryProviderActionType type );
+    
+    /**
+     * Returns the parameters associated with this library provider at declaration time. The
+     * list of parameters and their meaning is specific to the implementation of this library
+     * provider.
+     * 
+     * @return the parameters associated with this library provider at declaration time.
+     */
+    
+    Map<String,String> getParams();
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/IPropertyChangeListener.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/IPropertyChangeListener.java
new file mode 100644
index 0000000..2c3f394
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/IPropertyChangeListener.java
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+/**
+ * The common interface that's used throughout the Library Provider Framework to implement
+ * listeners.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public interface IPropertyChangeListener
+{
+    /**
+     * Called when property is changed.
+     * 
+     * @param property the name of the property
+     * @param oldValue the old value
+     * @param newValue the new value
+     */
+    
+    void propertyChanged( String property,
+                          Object oldValue,
+                          Object newValue );
+}
+
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LegacyLibraryProviderDetector.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LegacyLibraryProviderDetector.java
new file mode 100644
index 0000000..097436d
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LegacyLibraryProviderDetector.java
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+
+/**
+ * This class should be subclassed to provide detection of legacy library providers in the project.
+ * It is used together with the org.eclipse.jst.common.project.facet.core.legacyLibraryProviderDetectors
+ * extension point when migrating an existing facet to use the Library Provider Framework.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public abstract class LegacyLibraryProviderDetector
+{
+    /**
+     * Attempts to detect the presence of the legacy library provider in the project.
+     * 
+     * @param project the project in question
+     * @param facet the facet that is making the request for libraries
+     * @return the legacy library provider or <code>null</code> if not detected
+     */
+    
+    public abstract ILibraryProvider detect( final IProject project,
+                                             final IProjectFacet facet );
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryFacetInstallConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryFacetInstallConfig.java
new file mode 100644
index 0000000..8907da4
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryFacetInstallConfig.java
@@ -0,0 +1,105 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.common.project.facet.core.ActionConfig;
+import org.eclipse.wst.common.project.facet.core.IActionConfigFactory;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @author <a href="konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public class LibraryFacetInstallConfig
+
+    extends ActionConfig
+    
+{
+    private LibraryInstallDelegate libraryInstallDelegate = null;
+
+    public final LibraryInstallDelegate getLibraryInstallDelegate()
+    {
+        return this.libraryInstallDelegate;
+    }
+    
+    @Override
+    public void setFacetedProjectWorkingCopy( final IFacetedProjectWorkingCopy fpjwc )
+    {
+        super.setFacetedProjectWorkingCopy( fpjwc );
+        init();
+    }
+
+    @Override
+    public void setProjectFacetVersion( final IProjectFacetVersion fv )
+    {
+        super.setProjectFacetVersion( fv );
+        
+        final boolean initialized = init();
+        
+        if( this.libraryInstallDelegate != null && ! initialized )
+        {
+            this.libraryInstallDelegate.setProjectFacetVersion( fv );
+        }
+    }
+    
+    @Override
+    public IStatus validate() 
+    {
+        if( this.libraryInstallDelegate != null )
+        {
+            return this.libraryInstallDelegate.validate();
+        }
+        else
+        {
+            return Status.OK_STATUS;
+        }
+    }
+
+    private boolean init()
+    {
+        final IFacetedProjectWorkingCopy fpjwc = getFacetedProjectWorkingCopy();
+        final IProjectFacetVersion fv = getProjectFacetVersion();
+        
+        if( this.libraryInstallDelegate == null && fpjwc != null && fv != null )
+        {
+            this.libraryInstallDelegate = new LibraryInstallDelegate( fpjwc, fv );
+            return true;
+        }
+        
+        return false;
+    }
+    
+    @Override
+	public void dispose() 
+    {
+    	if( this.libraryInstallDelegate != null )
+    	{
+    		this.libraryInstallDelegate.dispose();
+    	}
+	}
+
+	public static final class Factory
+        
+        implements IActionConfigFactory
+        
+    {
+        public Object create()
+        {
+            return new LibraryFacetInstallConfig();
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryFacetUninstallConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryFacetUninstallConfig.java
new file mode 100644
index 0000000..c5fd698
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryFacetUninstallConfig.java
@@ -0,0 +1,96 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.common.project.facet.core.ActionConfig;
+import org.eclipse.wst.common.project.facet.core.IActionConfigFactory;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @author <a href="konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public class LibraryFacetUninstallConfig
+
+    extends ActionConfig
+    
+{
+    private LibraryUninstallDelegate libraryUninstallDelegate = null;
+
+    public final LibraryUninstallDelegate getLibraryUninstallDelegate()
+    {
+        return this.libraryUninstallDelegate;
+    }
+    
+    @Override
+    public void setFacetedProjectWorkingCopy( final IFacetedProjectWorkingCopy fpjwc )
+    {
+        super.setFacetedProjectWorkingCopy( fpjwc );
+        init();
+    }
+
+    @Override
+    public void setProjectFacetVersion( final IProjectFacetVersion fv )
+    {
+        super.setProjectFacetVersion( fv );
+        init();
+    }
+    
+    @Override
+    public IStatus validate() 
+    {
+        if( this.libraryUninstallDelegate != null )
+        {
+            return this.libraryUninstallDelegate.validate();
+        }
+        else
+        {
+            return Status.OK_STATUS;
+        }
+    }
+
+    private void init()
+    {
+        final IFacetedProjectWorkingCopy fpjwc = getFacetedProjectWorkingCopy();
+        final IProjectFacetVersion fv = getProjectFacetVersion();
+        
+        if( fpjwc != null && fv != null )
+        {
+            this.libraryUninstallDelegate = new LibraryUninstallDelegate( fpjwc, fv );
+        }
+    }
+    
+    @Override
+    public void dispose()
+    {
+    	if( this.libraryUninstallDelegate != null )
+    	{
+    		this.libraryUninstallDelegate.dispose();
+    	}
+    }
+    
+    public static final class Factory
+    
+        implements IActionConfigFactory
+        
+    {
+        public Object create()
+        {
+            return new LibraryFacetUninstallConfig();
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryInstallDelegate.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryInstallDelegate.java
new file mode 100644
index 0000000..3302869
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryInstallDelegate.java
@@ -0,0 +1,648 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.createErrorStatus;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.beginTask;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.done;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.submon;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.worked;
+import static org.eclipse.wst.common.project.facet.core.util.internal.MiscUtil.equal;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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.jst.common.project.facet.core.libprov.internal.LibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.internal.LibraryProviderFrameworkImpl;
+import org.eclipse.jst.common.project.facet.core.libprov.internal.PropertiesHost;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
+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.events.IFacetedProjectEvent;
+import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
+import org.eclipse.wst.common.project.facet.core.util.internal.CollectionsUtil;
+
+/**
+ * Used for configuring and then installing a library via the Library Provider Framework.
+ * Instance of this class would typically be embedded in facet action config objects and then
+ * executed during the execution of those actions. Can also be used stand-alone when it is
+ * necessary to change libraries outside facet lifecycle actions.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public final class LibraryInstallDelegate
+
+    extends PropertiesHost
+    
+{
+    private static final String CLASS_NAME = LibraryInstallDelegate.class.getName();
+    
+    /**
+     * The property corresponding to the list of available providers.
+     */
+    
+    public static final String PROP_AVAILABLE_PROVIDERS 
+        = CLASS_NAME + ".AVAILABLE_PROVIDERS"; //$NON-NLS-1$
+    
+    /**
+     * The property corresponding to the currently-selected provider.
+     */
+    
+    public static final String PROP_SELECTED_PROVIDER 
+        = CLASS_NAME + ".SELECTED_PROVIDER"; //$NON-NLS-1$
+    
+    private final IFacetedProjectBase fproj;
+    private IProjectFacetVersion fv;
+    private List<ILibraryProvider> providers;
+    private List<ILibraryProvider> providersReadOnly;
+    private ILibraryProvider selectedProvider;
+    private boolean isDefaultSelection;
+    private final Map<ILibraryProvider,LibraryProviderOperationConfig> configs;
+    private final IPropertyChangeListener providerConfigListener;
+    private LibraryUninstallDelegate uninstallDelegate = null;
+    private Map<String,Object> customEnablementContextVariables;
+    private final IFacetedProjectListener facetedProjectListener;
+    
+    /**
+     * Constructs a new library install delegate. 
+     * 
+     * @param fproj the faceted project (or a working copy)
+     * @param fv the project facet that is requesting libraries
+     * @param customEnablementContextVariables custom variables to add to the expression
+     *   evaluation context for enablement expressions or <code>null</code> for none
+     * @see #setEnablementContextVariable(String, Object)  
+     */
+    
+    public LibraryInstallDelegate( final IFacetedProjectBase fproj,
+                                   final IProjectFacetVersion fv,
+                                   final Map<String,Object> customEnablementContextVariables )
+    {
+        this.fproj = fproj;
+        this.fv = fv;
+        this.providers = Collections.emptyList();
+        this.providersReadOnly = Collections.emptyList();
+        this.selectedProvider = null;
+        this.isDefaultSelection = true;
+        this.configs = new HashMap<ILibraryProvider,LibraryProviderOperationConfig>();
+        this.customEnablementContextVariables = new HashMap<String,Object>();
+        
+        if( customEnablementContextVariables != null )
+        {
+            this.customEnablementContextVariables.putAll( customEnablementContextVariables );
+        }
+        
+        this.providerConfigListener = new IPropertyChangeListener()
+        {
+            public void propertyChanged( final String property,
+                                         final Object oldValue,
+                                         final Object newValue )
+            {
+                notifyListeners( property, oldValue, newValue );
+            }
+        };
+
+        this.facetedProjectListener = new IFacetedProjectListener()
+        {
+            public void handleEvent( final IFacetedProjectEvent event )
+            {
+                refresh();
+            }
+        };
+
+        getFacetedProject().addListener( this.facetedProjectListener, IFacetedProjectEvent.Type.PROJECT_MODIFIED );
+        
+        reset();
+    }
+    
+    /**
+     * Constructs a new library install delegate. 
+     * 
+     * @param fproj the faceted project (or a working copy)
+     * @param fv the project facet that is requesting libraries
+     */
+    
+    public LibraryInstallDelegate( final IFacetedProjectBase fproj,
+                                   final IProjectFacetVersion fv )
+    {
+        this( fproj, fv, null );
+    }
+    
+    /**
+     * Returns the faceted project that this install delegate was configured to use. Can be a working
+     * copy.
+     * 
+     * @return the faceted project that this install delegate was configured to use
+     */
+    
+    public IFacetedProjectBase getFacetedProject()
+    {
+        return this.fproj;
+    }
+    
+    /**
+     * Returns the project facet that made the request for libraries.
+     * 
+     * @return the project facet that made the request for libraries
+     */
+    
+    public synchronized IProjectFacet getProjectFacet()
+    {
+        return this.fv.getProjectFacet();
+    }
+    
+    /**
+     * Returns the project facet version that made the request for libraries.
+     * 
+     * @return the project facet version that made the request for libraries
+     */
+    
+    public synchronized IProjectFacetVersion getProjectFacetVersion()
+    {
+        return this.fv;
+    }
+    
+    /**
+     * Changes the project facet version of the requesting facet after the library install
+     * delegate has been created.
+     * 
+     * @param fv the project facet version
+     */
+    
+    public synchronized void setProjectFacetVersion( final IProjectFacetVersion fv )
+    {
+        this.fv = fv;
+        refresh();
+    }
+    
+    /**
+     * Returns the list of library providers that are currently available. The list is sorted
+     * by library provider priority (highest priority first). To listen for changes to this
+     * list use PROP_AVAILABLE_PROVIDERS.
+     * 
+     * @return the list of library providers that are currently available
+     */
+    
+    public synchronized List<ILibraryProvider> getLibraryProviders()
+    {
+        return this.providersReadOnly;
+    }
+    
+    /**
+     * Returns the library provider that is currently selected. To list for changes to this
+     * property use PROP_SELECTED_PROVIDER.
+     * 
+     * @return the library provider that is currently selected
+     */
+    
+    public synchronized ILibraryProvider getLibraryProvider()
+    {
+        return this.selectedProvider;
+    }
+    
+    /**
+     * Sets the current library provider. 
+     * 
+     * @param provider the provider that should be selected
+     */
+    
+    public synchronized void setLibraryProvider( final ILibraryProvider provider )
+    {
+        setLibraryProvider( provider, false, true );
+    }
+
+    private synchronized void setLibraryProvider( final ILibraryProvider provider,
+                                                  final boolean isDefaultSelection,
+                                                  final boolean notifyListeners )
+    {
+        if( ! this.providers.contains( provider ) &&
+            ! ( this.providers.size() == 0 && provider == null ) )
+        {
+            throw new IllegalArgumentException();
+        }
+        
+        if( ! equal( this.selectedProvider, provider ) )
+        {
+            final ILibraryProvider oldSelectedProvider = this.selectedProvider;
+            
+            this.selectedProvider = provider;
+            this.isDefaultSelection = isDefaultSelection;
+            
+            final LibraryProviderOperationConfig config = this.configs.get( this.selectedProvider );
+            
+            if( config != null )
+            {
+                config.reset();
+            }
+            
+            if( notifyListeners )
+            {
+                notifyListeners( PROP_SELECTED_PROVIDER, oldSelectedProvider, this.selectedProvider );
+            }
+        }
+    }
+    
+    /**
+     * Returns the install operation config of the currently-selected provider. This property's
+     * lifecycle is bound to the current provider changes, so listen for changes using 
+     * PROP_SELECTED_PROVIDER.
+     * 
+     * @return the install operation config of the currently-selected provider
+     */
+    
+    public synchronized LibraryProviderOperationConfig getLibraryProviderOperationConfig()
+    {
+        if( this.selectedProvider == null )
+        {
+            return null;
+        }
+        else
+        {
+            return this.configs.get( this.selectedProvider );
+        }
+    }
+    
+    /**
+     * Returns the install operation config for any of the available library providers.
+     * 
+     * @param provider the library provider to look up install operation config
+     * @return the install operation config for any of the available library providers
+     */
+    
+    public synchronized LibraryProviderOperationConfig getLibraryProviderOperationConfig( final ILibraryProvider provider )
+    {
+        if( ! this.providers.contains( provider ) )
+        {
+            throw new IllegalArgumentException();
+        }
+        
+        return this.configs.get( provider );
+    }
+    
+    /**
+     * Adds a custom variable to the expression evaluation context for enablement expressions
+     * controlling activation of library providers. Setting the variable to <code>null</code>
+     * has the effect of removing it. Calling this method will trigger a refresh of available 
+     * library providers.
+     *  
+     * @param name the name of the variable
+     * @param value the value of the variable
+     */
+    
+    public synchronized void setEnablementContextVariable( final String name,
+                                                           final Object value )
+    {
+        final Object currentValue = this.customEnablementContextVariables.get( name );
+        
+        if( ! equal( currentValue, value ) )
+        {
+            if( value == null )
+            {
+                this.customEnablementContextVariables.remove( name );
+            }
+            else
+            {
+                this.customEnablementContextVariables.put( name, value );
+            }
+            
+            refresh();
+        }
+    }
+    
+    /**
+     * Refreshes the list of available library providers and resets the current library provider
+     * if the one currently selected is not in the available list any longer.
+     */
+    
+    public synchronized void refresh()
+    {
+        final IProjectFacet f = getProjectFacet();
+        final IProjectFacetVersion fv = getProjectFacetVersion();
+        final IFacetedProjectBase fproj = getFacetedProject();
+        
+        final List<ILibraryProvider> oldProviders = this.providers;
+        
+        for( ILibraryProvider provider : oldProviders )
+        {
+            final LibraryProviderOperationConfig config = this.configs.remove( provider );
+            
+            if( config != null )
+            {
+                config.removeListener( this.providerConfigListener );
+                config.dispose();
+            }
+        }
+        
+        final List<ILibraryProvider> newProviders = new ArrayList<ILibraryProvider>();
+    
+        for( ILibraryProvider provider : LibraryProviderFramework.getProviders() )
+        {
+            if( ! provider.isAbstract() && ! provider.isHidden() 
+                && provider.isEnabledFor( fproj, fv, this.customEnablementContextVariables ) )
+            {
+                newProviders.add( provider );
+            }
+        }
+        
+        final Comparator<ILibraryProvider> comp = CollectionsUtil.getInvertingComparator();
+        Collections.sort( newProviders, comp );
+        
+        final IFacetedProject base;
+        
+        if( fproj instanceof IFacetedProject )
+        {
+            base = (IFacetedProject) fproj;
+        }
+        else
+        {
+            base = ( (IFacetedProjectWorkingCopy) fproj ).getFacetedProject();
+        }
+        
+        if( base != null && base.hasProjectFacet( f ) )
+        {
+            // This code is here to take care of cases where framework injects a provider
+            // that is not typically available for unknown and legacy usecases.
+            
+            final ILibraryProvider provider 
+                = LibraryProviderFramework.getCurrentProvider( base.getProject(), f );
+            
+            if( provider == null )
+            {
+                throw new RuntimeException();
+            }
+            
+            if( ! newProviders.contains( provider ) )
+            {
+                newProviders.add( provider );
+            }
+        }
+        
+        this.providers = newProviders;
+        this.providersReadOnly = Collections.unmodifiableList( this.providers );
+        
+        for( ILibraryProvider provider : this.providers )
+        {
+            final LibraryProvider prov = (LibraryProvider) provider;
+            final LibraryProviderOperationConfig config = prov.createInstallOperationConfig( this );
+            config.addListener( this.providerConfigListener );
+            this.configs.put( provider, config );
+        }
+        
+        final ILibraryProvider oldSelectedProvider = this.selectedProvider;
+        
+        if( this.providers.size() > 0 )
+        {
+            if( this.selectedProvider == null || this.isDefaultSelection || 
+                ! this.providers.contains( this.selectedProvider ) )
+            {
+                ILibraryProvider provider = LibraryProviderFrameworkImpl.get().getLastProviderUsed( fv );
+                
+                if( provider == null || ! this.providers.contains( provider ) )
+                {
+                    provider = this.providers.iterator().next();
+                }
+                    
+                setLibraryProvider( provider, true, false );
+            }
+        }
+        else
+        {
+            setLibraryProvider( null, true, false );
+        }
+        
+        notifyListeners( PROP_AVAILABLE_PROVIDERS, oldProviders, this.providersReadOnly );
+
+        if( ! equal( oldSelectedProvider, this.selectedProvider ) )
+        {
+            notifyListeners( PROP_SELECTED_PROVIDER, oldSelectedProvider, this.selectedProvider );
+        }
+    }
+
+    /**
+     * Resets this install delegate to its initial state (prior to any user changes).
+     */
+
+    public synchronized void reset()
+    {
+        refresh();
+        
+        final IProjectFacet facet = this.fv.getProjectFacet();
+        final IFacetedProject fpj;
+        
+        if( this.fproj instanceof IFacetedProject )
+        {
+            fpj = (IFacetedProject) this.fproj;
+        }
+        else
+        {
+            fpj = ( (IFacetedProjectWorkingCopy) this.fproj ).getFacetedProject();
+        }
+        
+        ILibraryProvider provider = null;
+        
+        if( this.uninstallDelegate != null )
+        {
+        	this.uninstallDelegate.dispose();
+        	this.uninstallDelegate = null;
+        }
+        
+        if( fpj != null && fpj.hasProjectFacet( facet ) )
+        {
+            this.uninstallDelegate = new LibraryUninstallDelegate( fpj, this.fv );
+            
+            provider = LibraryProviderFramework.getCurrentProvider( fpj.getProject(), facet );
+            
+            if( provider == null )
+            {
+                throw new RuntimeException();
+            }
+        }
+        else
+        {
+            provider = LibraryProviderFrameworkImpl.get().getLastProviderUsed( this.fv );
+        
+            if( provider == null || ! this.providers.contains( provider ) )
+            {
+                if( ! this.providers.isEmpty() )
+                {
+                    provider = this.providers.iterator().next();
+                }
+                else
+                {
+                    provider = null;
+                }
+            }
+        }
+        
+        setLibraryProvider( provider );
+        
+        for( LibraryProviderOperationConfig config : this.configs.values() )
+        {
+            config.reset();
+        }
+    }
+
+    /**
+     * Checks the validity of the library install configuration. 
+     * 
+     * @return a status object describing configuration problems, if any
+     */
+    
+    public synchronized IStatus validate()
+    {
+        IStatus st = Status.OK_STATUS;
+        
+        if( this.providers.size() == 0 )
+        {
+            st = createErrorStatus( Resources.noProvidersAvailable );
+        }
+        else
+        {
+            final Object providerInstallOpConfig = this.configs.get( this.selectedProvider );
+            
+            if( providerInstallOpConfig instanceof LibraryProviderOperationConfig )
+            {
+                st = ( (LibraryProviderOperationConfig) providerInstallOpConfig ).validate();
+            }
+        }
+        
+        return st;
+    }
+    
+    /**
+     * Executes the library install operation.
+     * 
+     * @param monitor the progress monitor for reporting status and handling cancellation requests
+     * @throws CoreException if failed for some reason while executing the install operation
+     */
+    
+    public synchronized void execute( final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        beginTask( monitor, "", 10 ); //$NON-NLS-1$
+        
+        try
+        {
+            final IFacetedProjectBase fproj = getFacetedProject();
+            final IProjectFacetVersion fv = getProjectFacetVersion();
+            final LibraryProvider provider = (LibraryProvider) getLibraryProvider();
+            
+            // Turn this into a no-op if the selected library provider is either the legacy
+            // library provider or the unknown library provider. Those represent special corner
+            // cases and the standard uninstall/install does not work. This comes up in the property
+            // page case where the user hits ok without picking a different provider. Would be nice 
+            // if we could somehow turn this check into a more general "did user change" anything 
+            // check.
+            
+            final String rootLibraryProviderId = this.selectedProvider.getRootProvider().getId();
+            
+            if( rootLibraryProviderId.equals( "unknown-library-provider" ) || //$NON-NLS-1$
+                rootLibraryProviderId.equals( "legacy-library-provider" ) ) //$NON-NLS-1$
+            {
+                return;
+            }
+            
+            // Uninstall the previous library, if applicable.
+            
+            if( this.uninstallDelegate != null )
+            {
+                this.uninstallDelegate.execute( new NullProgressMonitor() );
+            }
+            
+            // Install the library.
+            
+            final LibraryProviderOperation libraryInstallOp 
+                = provider.createOperation( LibraryProviderActionType.INSTALL );
+            
+            final LibraryProviderOperationConfig libraryInstallOpConfig 
+                = getLibraryProviderOperationConfig();
+            
+            libraryInstallOp.execute( libraryInstallOpConfig, submon( monitor, 8 ) );
+            
+            // Record which library provider was used for this facet in workspace prefs. This 
+            // will be used to default the provider selection the next time this facet is installed.
+            
+            LibraryProviderFrameworkImpl.get().setLastProviderUsed( fv, provider );
+            worked( monitor, 1 );
+            
+            // Record which library provider was used for this facet in project metadata. This
+            // will be used to know which provider to use when the facet is being uninstalled or
+            // the version is being changed.
+            
+            LibraryProviderFrameworkImpl.get().setCurrentProvider( fproj.getProject(), fv.getProjectFacet(), provider );
+            
+            worked( monitor, 1 );
+        }
+        finally
+        {
+            done( monitor );
+        }
+    }
+    
+    /**
+     * Cleans up allocated resources. Client code that instantiates this class is responsible that the
+     * instance is properly disposed by calling the dispose method.
+     */
+    
+    public synchronized void dispose()
+    {
+    	if( this.uninstallDelegate != null )
+    	{
+    		this.uninstallDelegate.dispose();
+    	}
+    	
+        getFacetedProject().removeListener( this.facetedProjectListener );
+        
+        for( LibraryProviderOperationConfig cfg : this.configs.values() )
+        {
+            try
+            {
+                cfg.dispose();
+            }
+            catch( Exception e )
+            {
+                log( e );
+            }
+        }
+    }
+    
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String noProvidersAvailable;
+        
+        static
+        {
+            initializeMessages( LibraryInstallDelegate.class.getName(), 
+                                Resources.class );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryInstallDelegate.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryInstallDelegate.properties
new file mode 100644
index 0000000..107a283
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryInstallDelegate.properties
@@ -0,0 +1 @@
+noProvidersAvailable = No library providers are available for this facet. The facet cannot be installed.
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderActionType.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderActionType.java
new file mode 100644
index 0000000..9a2a68f
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderActionType.java
@@ -0,0 +1,34 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+/**
+ * Enumeration of library provider action types.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public enum LibraryProviderActionType
+{
+    /**
+     * Represents the action of configuring the library in a project.
+     */
+    
+    INSTALL,
+    
+    /**
+     * Represents removing the library from a project.
+     */
+    
+    UNINSTALL
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderFramework.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderFramework.java
new file mode 100644
index 0000000..48f7ce2
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderFramework.java
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jst.common.project.facet.core.libprov.internal.LibraryProviderFrameworkImpl;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+
+/**
+ * The root entry point for working with the Library Provider Framework.
+ * 
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public final class LibraryProviderFramework
+{
+    private LibraryProviderFramework() {}
+    
+    /**
+     * Returns all of the library providers declared in the system.
+     * 
+     * @return all of the library providers declared in the system
+     */
+    
+    public static Set<ILibraryProvider> getProviders()
+    {
+        return get().getProviders();
+    }
+    
+    /**
+     * Determines if a library provider with the specified id exists.
+     * 
+     * @param id the id of the library provider to use in lookup
+     * @return <code>true</code> if and only if a library provider with the specified
+     *   id exists
+     */
+    
+    public static boolean isProviderDefined( final String id )
+    {
+        return get().isProviderDefined( id );
+    }
+    
+    /**
+     * Returns the library provider corresponding to the specified id.
+     * 
+     * @param id the id of the library provider to use in lookup
+     * @return the library provider corresponding to the specified id
+     * @throws IllegalArgumentException if the specified provider id is not recognized
+     */
+    
+    public static ILibraryProvider getProvider( final String id )
+    {
+        return get().getProvider( id );
+    }
+    
+    /**
+     * Returns the library provider that is currently configured with the specified facet. Will
+     * return <code>null</code> if the facet is not installed in the specified project.
+     * 
+     * @param project the project in question
+     * @param facet the facet in question
+     * @return the library provider currently used by the facet in the specified project
+     */
+    
+    public static ILibraryProvider getCurrentProvider( final IProject project,
+                                                       final IProjectFacet facet )
+    {
+        return get().getCurrentProvider( project, facet );
+    }
+    
+    private static LibraryProviderFrameworkImpl get()
+    {
+        return LibraryProviderFrameworkImpl.get();
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderInstallOperationConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderInstallOperationConfig.java
new file mode 100644
index 0000000..7957838
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderInstallOperationConfig.java
@@ -0,0 +1,63 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+
+/**
+ * This class should be subclassed in order to implement parameterization of the library
+ * provider install operations. If no additional parameters are necessary, this class can also be 
+ * used directly.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public class LibraryProviderInstallOperationConfig
+
+    extends LibraryProviderOperationConfig
+    
+{
+    private LibraryInstallDelegate libraryInstallDelegate;
+    
+    /**
+     * Initializes the operation config. This method is called soon after the provider
+     * is instantiated. Extenders can override in order to add to the initialization, but
+     * have make sure to forward the init call up the inheritance chain.
+     * 
+     * @param libraryInstallDelegate the library install delegate that created this config object
+     * @param provider the library provider (useful if the same operation config class
+     *   is re-used between multiple providers)
+     */
+    
+    public void init( final LibraryInstallDelegate libraryInstallDelegate,
+                      final ILibraryProvider provider )
+    {
+        this.libraryInstallDelegate = libraryInstallDelegate;
+        
+        init( this.libraryInstallDelegate.getFacetedProject(),
+              this.libraryInstallDelegate.getProjectFacetVersion(),
+              provider );
+    }
+
+    /**
+     * Returns the library install delegate that created this install operation config and is
+     * controlling it's lifecycle.
+     * 
+     * @return the library install delegate that is controlling this operation config object
+     */
+    
+    public final LibraryInstallDelegate getLibraryInstallDelegate()
+    {
+        return this.libraryInstallDelegate;
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderOperation.java
new file mode 100644
index 0000000..ccce47b
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderOperation.java
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * This class should be subclassed in order to provider the logic that should execute
+ * when a library provider action (such as install and uninstall) is triggered.
+ *
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public abstract class LibraryProviderOperation
+{
+    /**
+     * Runs the library provider operation.
+     * 
+     * @param config the library provider operation config; will never be null
+     * @param monitor the progress monitor for status reporting and cancellation
+     * @throws CoreException if failed while executing the operation
+     */
+    
+    public abstract void execute( final LibraryProviderOperationConfig config,
+                                  final IProgressMonitor monitor )
+    
+        throws CoreException;
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderOperationConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderOperationConfig.java
new file mode 100644
index 0000000..fe0f82c
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryProviderOperationConfig.java
@@ -0,0 +1,181 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jst.common.project.facet.core.libprov.internal.PropertiesHost;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * This class should be subclassed in order to implement parameterization of the library
+ * provider operations (such as install and uninstall). If no additional parameters are
+ * necessary, this class can also be used directly.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public class LibraryProviderOperationConfig
+
+    extends PropertiesHost
+    
+{
+    private IFacetedProjectBase fpj;
+    private IProjectFacetVersion fv;
+    private ILibraryProvider provider;
+    
+    /**
+     * Initializes the operation config. This method is called soon after the provider
+     * is instantiated. Extenders can override in order to add to the initialization, but
+     * have make sure to forward the init call up the inheritance chain.
+     * 
+     * @param fpj the faceted project (or a working copy)
+     * @param fv the project facet that is making the request for libraries
+     * @param provider the library provider (useful if the same operation config class
+     *   is re-used between multiple providers)
+     */
+    
+    public void init( final IFacetedProjectBase fpj,
+                      final IProjectFacetVersion fv,
+                      final ILibraryProvider provider )
+    {
+        this.fpj = fpj;
+        this.fv = fv;
+        this.provider = provider;
+    }
+    
+    /**
+     * Returns the faceted project (or a working copy).
+     * 
+     * @return the faceted project (or a working copy)
+     */
+    
+    public final IFacetedProjectBase getFacetedProject()
+    {
+        return this.fpj;
+    }
+    
+    /**
+     * Returns the project facet that made the request for libraries.
+     * 
+     * @return the project facet that made the request for libraries
+     */
+    
+    public final IProjectFacet getProjectFacet()
+    {
+        return this.fv.getProjectFacet();
+    }
+    
+    /**
+     * Returns the project facet version that made the request for libraries.
+     * 
+     * @return the project facet version that made the request for libraries
+     */
+    
+    public final IProjectFacetVersion getProjectFacetVersion()
+    {
+        return this.fv;
+    }
+    
+    /**
+     * Returns the library provider. This is particularly useful in cases where the same
+     * operation config class is re-used across multiple library providers.
+     * 
+     * @return the library provider
+     */
+    
+    public final ILibraryProvider getLibraryProvider()
+    {
+        return this.provider;
+    }
+    
+    /**
+     * Adds a listener that will be notified when the property changes. If no properties
+     * are specified, the listener will be notified when any of the properties change. The 
+     * extender is responsible for defining available properties (typically via constants 
+     * in the config class) and for calling the notifyListeners method when a property changes.
+     * 
+     * @param listener the listener that should be registered
+     * @param properties the list of properties to listen to or an empty list to list to
+     *   all properties
+     */
+
+    @Override
+    public final void addListener( final IPropertyChangeListener listener,
+                                   final String... properties )
+    {
+        super.addListener( listener, properties );
+    }
+    
+    /**
+     * Removes the specified listener from the notification queue. Does nothing if the listener
+     * is not registered.
+     * 
+     * @param listener the listener that should be removed
+     */
+    
+    @Override
+    public final void removeListener( final IPropertyChangeListener listener )
+    {
+        super.removeListener( listener );
+    }
+    
+    /**
+     * Notifies registered listeners that a property has changed. The extender is responsible 
+     * for defining available properties (typically via constants in the config class) and for 
+     * calling this method when a property changes.
+     * 
+     * @param property the property that has changed
+     * @param oldValue the old value
+     * @param newValue the new value
+     */
+    
+    @Override
+    public final void notifyListeners( final String property,
+                                       final Object oldValue,
+                                       final Object newValue )
+    {
+        super.notifyListeners( property, oldValue, newValue );
+    }
+    
+    /**
+     * Validates the state of this operation config object and returns a status object
+     * describing any problems. If no problems are detected, this should return OK
+     * status (which is what the default implementation does).
+     * 
+     * @return the result of validating this operation config
+     */
+    
+    public IStatus validate()
+    {
+        return Status.OK_STATUS;
+    }
+    
+    /**
+     * Resets this operation config to its initial state (prior to any user changes). The
+     * default implementation does not do anything.
+     */
+
+    public void reset() {}
+
+    /**
+     * Allows the operation config implementation to dispose of any resources acquired during
+     * the life of this object. This is a good place to remove any external listeners that
+     * are registered. The default implementation does not do anything.
+     */
+    
+    public void dispose() {}
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryUninstallDelegate.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryUninstallDelegate.java
new file mode 100644
index 0000000..d5a7bce
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/LibraryUninstallDelegate.java
@@ -0,0 +1,221 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.beginTask;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.done;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.submon;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.worked;
+
+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.jst.common.project.facet.core.libprov.internal.LibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.internal.LibraryProviderFrameworkImpl;
+import org.eclipse.jst.common.project.facet.core.libprov.internal.PropertiesHost;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * Used for removing a library installed via the Library Provider Framework.
+ * Instance of this class would typically be embedded in facet uninstall action config objects 
+ * and then executed during the execution of those actions. 
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public final class LibraryUninstallDelegate
+
+    extends PropertiesHost
+    
+{
+    private final IFacetedProjectBase fproj;
+    private IProjectFacetVersion fv;
+    private ILibraryProvider oldProvider = null;
+    private LibraryProviderOperationConfig oldProviderUninstallOpConfig = null;
+    
+    /**
+     * Constructs a new library uninstall delegate. 
+     * 
+     * @param fproj the faceted project (or a working copy)
+     * @param fv the project facet that installed the libraries
+     */
+    
+    public LibraryUninstallDelegate( final IFacetedProjectBase fproj,
+                                     final IProjectFacetVersion fv )
+    {
+        this.fproj = fproj;
+        this.fv = fv;
+        
+        this.oldProvider = LibraryProviderFramework.getCurrentProvider( fproj.getProject(), fv.getProjectFacet() );
+        
+        if( this.oldProvider == null )
+        {
+            this.oldProviderUninstallOpConfig = null;
+        }
+        else
+        {
+            final LibraryProvider prov = (LibraryProvider) this.oldProvider;
+            
+            this.oldProviderUninstallOpConfig 
+                = prov.createOperationConfig( fproj, fv, LibraryProviderActionType.UNINSTALL );
+        
+            this.oldProviderUninstallOpConfig.addListener
+            (
+                new IPropertyChangeListener()
+                {
+                    public void propertyChanged( final String property,
+                                                 final Object oldValue,
+                                                 final Object newValue )
+                    {
+                        notifyListeners( property, oldValue, newValue );
+                    }
+                }
+            );
+        }
+    }
+    
+    /**
+     * Returns the faceted project that this uninstall delegate was configured to use. Can be a working
+     * copy.
+     * 
+     * @return the faceted project that this uninstall delegate was configured to use
+     */
+    
+    public IFacetedProjectBase getFacetedProject()
+    {
+        return this.fproj;
+    }
+    
+    /**
+     * Returns the project facet that installed the libraries.
+     * 
+     * @return the project facet that installed the libraries
+     */
+    
+    public IProjectFacet getProjectFacet()
+    {
+        return this.fv.getProjectFacet();
+    }
+    
+    /**
+     * Returns the project facet version that installed the libraries.
+     * 
+     * @return the project facet version that installed the libraries
+     */
+
+    public IProjectFacetVersion getProjectFacetVersion()
+    {
+        return this.fv;
+    }
+    
+    /**
+     * Returns the library provider that the system determine is currently installed for
+     * the specified facet.
+     * 
+     * @return the library provider that is currently installed
+     */
+    
+    public ILibraryProvider getLibraryProvider()
+    {
+        return this.oldProvider;
+    }
+    
+    /**
+     * Returns the uninstall operation config for the currently installed library.
+     * 
+     * @return the uninstall operation config for the currently installed library
+     */
+    
+    public LibraryProviderOperationConfig getUninstallOperationConfig()
+    {
+        return this.oldProviderUninstallOpConfig;
+    }
+    
+    /**
+     * Checks the validity of the library uninstall configuration. 
+     * 
+     * @return a status object describing configuration problems, if any
+     */
+    
+    public IStatus validate()
+    {
+        IStatus st = Status.OK_STATUS;
+        
+        st = this.oldProviderUninstallOpConfig.validate();
+        
+        return st;
+    }
+    
+    /**
+     * Executes the library uninstall operation.
+     * 
+     * @param monitor the progress monitor for reporting status and handling cancellation requests
+     * @throws CoreException if failed for some reason while executing the uninstall operation
+     */
+    
+    public void execute( final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        beginTask( monitor, "", 10 ); //$NON-NLS-1$
+        
+        try
+        {
+            final IFacetedProjectBase fproj = getFacetedProject();
+            final IProjectFacetVersion fv = getProjectFacetVersion();
+            final LibraryProvider provider = (LibraryProvider) getLibraryProvider();
+            
+            // Uninstall the library.
+            
+            final LibraryProviderOperation libraryUninstallOp = provider.createOperation( LibraryProviderActionType.UNINSTALL );
+            
+            final LibraryProviderOperationConfig libraryUninstallOpConfig 
+                = getUninstallOperationConfig();
+            
+            libraryUninstallOp.execute( libraryUninstallOpConfig, submon( monitor, 9 ) );
+            
+            // Remove information about which library provider was used during the install.
+            
+            LibraryProviderFrameworkImpl.get().setCurrentProvider( fproj.getProject(), fv.getProjectFacet(), null );
+            
+            worked( monitor, 1 );
+        }
+        finally
+        {
+            done( monitor );
+        }
+    }
+
+    /**
+     * Cleans up allocated resources. Client code that instantiates this class is responsible that the
+     * instance is properly disposed by calling the dispose method.
+     */
+    
+    public void dispose()
+    {
+        try
+        {
+            this.oldProviderUninstallOpConfig.dispose();
+        }
+        catch( Exception e )
+        {
+            log( e );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/NoOpLibraryProviderInstallOperationConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/NoOpLibraryProviderInstallOperationConfig.java
new file mode 100644
index 0000000..85be9fd
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/NoOpLibraryProviderInstallOperationConfig.java
@@ -0,0 +1,90 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.PLUGIN_ID;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * The install operation config corresponding to the no-op-library-provider that allows library
+ * configuration to be disabled by user. This class can be subclassed by those wishing to extend 
+ * the base implementation supplied by the framework.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public class NoOpLibraryProviderInstallOperationConfig
+
+    extends LibraryProviderOperationConfig
+    
+{
+    public static final String PARAM_WARNING = "warning";  //$NON-NLS-1$
+    
+    private String warning = null;
+    
+    /**
+     * Constructs the no-op library provider install operation config.
+     */
+    
+    public NoOpLibraryProviderInstallOperationConfig()
+    {
+        this.warning = null;
+    }
+
+    /**
+     * Initializes the operation config. This method is called soon after the provider
+     * is instantiated. Extenders can override in order to add to the initialization, but
+     * have make sure to forward the init call up the inheritance chain.
+     * 
+     * @param fpj the faceted project (or a working copy)
+     * @param fv the project facet that is making the request for libraries
+     * @param provider the library provider (useful if the same operation config class
+     *   is re-used between multiple providers)
+     */
+    
+    @Override
+    public synchronized void init( final IFacetedProjectBase fproj,
+                                   final IProjectFacetVersion fv,
+                                   final ILibraryProvider provider )
+    {
+        super.init( fproj, fv, provider );
+        
+        this.warning = provider.getParams().get( PARAM_WARNING );
+    }
+    
+    /**
+     * Validates the state of this operation config object and returns a status object
+     * describing any problems. If no problems are detected, this should return OK
+     * status.
+     * 
+     * @return the result of validating this operation config
+     */
+    
+    @Override
+    public synchronized IStatus validate()
+    {
+        IStatus st = Status.OK_STATUS;
+        
+        if( this.warning != null )
+        {
+            st = new Status( IStatus.WARNING, PLUGIN_ID, this.warning );
+        }
+        
+        return st;
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/NoOpLibraryProviderOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/NoOpLibraryProviderOperation.java
new file mode 100644
index 0000000..6d2b741
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/NoOpLibraryProviderOperation.java
@@ -0,0 +1,41 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+
+/**
+ * This operation implementation can be used in situations when an install or an uninstall 
+ * operation doesn't actually have do do anything.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public final class NoOpLibraryProviderOperation
+
+    extends LibraryProviderOperation
+    
+{
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        // The operation is a no-op.
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyLibraryProviderDetectorsExtensionPoint.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyLibraryProviderDetectorsExtensionPoint.java
new file mode 100644
index 0000000..c5f9da0
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyLibraryProviderDetectorsExtensionPoint.java
@@ -0,0 +1,162 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.PLUGIN_ID;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findExtensions;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findRequiredAttribute;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.getTopLevelElements;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.instantiate;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.loadClass;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.LegacyLibraryProviderDetector;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.InvalidExtensionException;
+
+/**
+ * Contains the logic for processing the <code>legacyLibraryProviderDetectors</code> extension point. 
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class LegacyLibraryProviderDetectorsExtensionPoint
+{
+    public static final String EXTENSION_POINT_ID = "legacyLibraryProviderDetectors"; //$NON-NLS-1$
+    
+    private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
+    private static final String EL_DETECTOR = "detector"; //$NON-NLS-1$
+
+    private static List<DetectorExtension> extensions = null;
+    
+    public static synchronized ILibraryProvider detect( final IProject project,
+                                                        final IProjectFacet facet )
+    {
+        readExtensions();
+        
+        for( Iterator<DetectorExtension> itr = extensions.iterator(); itr.hasNext(); )
+        {
+            final DetectorExtension extension = itr.next();
+            final LegacyLibraryProviderDetector detector;
+            
+            try
+            {
+                detector = extension.createDetector();
+            }
+            catch( InvalidExtensionException e )
+            {
+                // Problem already reported to the user in the log. Removing the extension from
+                // the list so that we don't keep tripping over it in the future.
+                
+                itr.remove();
+                continue;
+            }
+            
+            try
+            {
+                final ILibraryProvider provider = detector.detect( project, facet );
+                
+                if( provider != null )
+                {
+                    return provider;
+                }
+            }
+            catch( Exception e )
+            {
+                log( e );
+            }
+        }
+        
+        return null;
+    }
+    
+    private static synchronized void readExtensions()
+    {
+        if( extensions != null )
+        {
+            return;
+        }
+        
+        extensions = new ArrayList<DetectorExtension>();        
+        
+        for( IConfigurationElement element 
+             : getTopLevelElements( findExtensions( PLUGIN_ID, EXTENSION_POINT_ID ) ) )
+        {
+            if( element.getName().equals( EL_DETECTOR ) )
+            {
+                try
+                {
+                    final String pluginId = element.getContributor().getName();
+                    final String className = findRequiredAttribute( element, ATTR_CLASS );
+                    extensions.add( new DetectorExtension( pluginId, className ) );
+                }
+                catch( InvalidExtensionException e )
+                {
+                    // Continue. The problem has been reported to the user via the log.
+                }
+            }
+        }
+    }
+
+    private static final class DetectorExtension
+    {
+        private final String pluginId;
+        private final String className;
+        private WeakReference<Class<? extends LegacyLibraryProviderDetector>> classWeakReference;
+        
+        public DetectorExtension( final String pluginId,
+                                  final String className )
+        {
+            this.pluginId = pluginId;
+            this.className = className;
+        }
+        
+        public synchronized LegacyLibraryProviderDetector createDetector()
+        
+            throws InvalidExtensionException
+            
+        {
+            Class<? extends LegacyLibraryProviderDetector> detectorClass 
+                = this.classWeakReference == null ? null : this.classWeakReference.get();
+            
+            if( detectorClass == null )
+            {
+                detectorClass = loadClass( this.pluginId, this.className, LegacyLibraryProviderDetector.class );
+                
+                if( detectorClass == null )
+                {
+                    throw new InvalidExtensionException();
+                }
+                
+                this.classWeakReference = new WeakReference<Class<? extends LegacyLibraryProviderDetector>>( detectorClass );
+            }
+            
+            final LegacyLibraryProviderDetector detector = instantiate( this.pluginId, detectorClass );
+            
+            if( detector == null )
+            {
+                throw new InvalidExtensionException();
+            }
+            
+            return detector;
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyLibraryProviderInstallOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyLibraryProviderInstallOperation.java
new file mode 100644
index 0000000..0fe98de
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyLibraryProviderInstallOperation.java
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class LegacyLibraryProviderInstallOperation
+
+    extends LibraryProviderOperation
+    
+{
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        // This is never expected to be called...
+        throw new IllegalStateException();
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyRuntimeLibraryProviderDetector.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyRuntimeLibraryProviderDetector.java
new file mode 100644
index 0000000..c8f612b
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyRuntimeLibraryProviderDetector.java
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jst.common.project.facet.core.internal.ClasspathUtil;
+import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.LegacyLibraryProviderDetector;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderFramework;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class LegacyRuntimeLibraryProviderDetector
+
+    extends LegacyLibraryProviderDetector
+    
+{
+    private static final String LEGACY_RUNTIME_LIBRARY_PROVIDER_ID 
+        = "legacy-runtime-library-provider"; //$NON-NLS-1$
+    
+    @Override
+    public ILibraryProvider detect( final IProject project,
+                                    final IProjectFacet facet )
+    {
+        try
+        {
+            if( ClasspathUtil.getClasspathEntries( project, facet ).size() > 0 )
+            {
+                return LibraryProviderFramework.getProvider( LEGACY_RUNTIME_LIBRARY_PROVIDER_ID );
+            }
+        }
+        catch( CoreException e )
+        {
+            log( e );
+        }
+        
+        return null;
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyRuntimeLibraryProviderUninstallOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyRuntimeLibraryProviderUninstallOperation.java
new file mode 100644
index 0000000..c712fca
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LegacyRuntimeLibraryProviderUninstallOperation.java
@@ -0,0 +1,55 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.beginTask;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.done;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.worked;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.internal.ClasspathUtil;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class LegacyRuntimeLibraryProviderUninstallOperation
+
+    extends LibraryProviderOperation
+    
+{
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        beginTask( monitor, "", 1 ); //$NON-NLS-1$
+        
+        try
+        {
+            final IProject project = config.getFacetedProject().getProject();
+            ClasspathUtil.removeClasspathEntries( project, config.getProjectFacet() );
+            
+            worked( monitor, 1 );
+        }
+        finally
+        {
+            done( monitor );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryInstallRecord.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryInstallRecord.properties
new file mode 100644
index 0000000..ddf6482
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryInstallRecord.properties
@@ -0,0 +1,2 @@
+exceptionWhileParsing = Failed while parsing "{0}" file.
+corruptedInstallRecordFile = The install record file "{0}" is corrupted.
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryProvider.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryProvider.java
new file mode 100644
index 0000000..6c10415
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryProvider.java
@@ -0,0 +1,469 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.instantiate;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.loadClass;
+
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jst.common.project.facet.core.libprov.EnablementExpressionContext;
+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.LibraryProviderActionType;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderInstallOperationConfig;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class LibraryProvider
+
+    implements ILibraryProvider
+    
+{
+    private final class ActionDef
+    {
+        private final String configClassName;
+        private Class<LibraryProviderOperationConfig> configClass;
+        private final String operationClassName;
+        private Class<LibraryProviderOperation> operationClass;
+        
+        public ActionDef( final String configClassName,
+                          final String operationClassName )
+        {
+            if( configClassName == null )
+            {
+                this.configClassName = null;
+                this.configClass = LibraryProviderOperationConfig.class;
+            }
+            else
+            {
+                this.configClassName = configClassName;
+                this.configClass = null;
+            }
+            
+            this.operationClassName = operationClassName;
+            this.operationClass = null;
+        }
+        
+        public String getPluginId()
+        {
+            return LibraryProvider.this.getPluginId();
+        }
+        
+        public synchronized Class<LibraryProviderOperationConfig> getConfigClass()
+        {
+            if( this.configClass == null )
+            {
+                this.configClass = loadClass( getPluginId(), this.configClassName,
+                                              LibraryProviderOperationConfig.class );
+            }
+            
+            return this.configClass;
+        }
+        
+        public synchronized Class<LibraryProviderOperation> getOperationClass()
+        {
+            if( this.operationClass == null )
+            {
+                this.operationClass 
+                    = loadClass( getPluginId(), this.operationClassName, 
+                                 LibraryProviderOperation.class );
+            }
+            
+            return this.operationClass;
+        }
+    }
+    
+    private static final String EXPR_VAR_CONTEXT 
+        = "context"; //$NON-NLS-1$
+
+    private static final String EXPR_VAR_REQUESTING_PROJECT_FACET 
+        = "requestingProjectFacet"; //$NON-NLS-1$
+    
+    private static final String EXPR_VAR_PROJECT_FACETS 
+        = "projectFacets"; //$NON-NLS-1$
+    
+    private static final String EXPR_VAR_TARGETED_RUNTIMES 
+        = "targetedRuntimes"; //$NON-NLS-1$
+    
+    private static final String EXPR_VAR_PROVIDER
+        = "provider"; //$NON-NLS-1$
+    
+    private String id;
+    private String pluginId;
+    private String label;
+    private ILibraryProvider base;
+    private boolean isAbstract;
+    private boolean isHidden;
+    private Expression enablementCondition;
+    private Integer priority;
+    private final Map<String,String> params;
+    private final Map<LibraryProviderActionType,ActionDef> actionDefs;
+    
+    LibraryProvider()
+    {
+        this.id = null;
+        this.pluginId = null;
+        this.label = null;
+        this.base = null;
+        this.isAbstract = false;
+        this.isHidden = false;
+        this.enablementCondition = null;
+        this.priority = null;
+        this.params = new HashMap<String,String>();
+        this.actionDefs = new EnumMap<LibraryProviderActionType,ActionDef>( LibraryProviderActionType.class );
+    }
+    
+    public String getId()
+    {
+        return this.id;
+    }
+    
+    void setId( final String id )
+    {
+        this.id = id;
+    }
+    
+    public String getPluginId()
+    {
+        return this.pluginId;
+    }
+    
+    void setPluginId( final String pluginId )
+    {
+        this.pluginId = pluginId;
+    }
+    
+    public String getLabel()
+    {
+        final String result;
+        
+        if( this.label != null )
+        {
+            result = this.label;
+        }
+        else
+        {
+            if( this.base != null )
+            {
+                result = this.base.getLabel();
+            }
+            else
+            {
+                result = this.id;
+            }
+        }
+        
+        return result;
+    }
+    
+    void setLabel( final String label )
+    {
+        this.label = label;
+    }
+    
+    public ILibraryProvider getBaseProvider()
+    {
+        return this.base;
+    }
+    
+    void setBaseProvider( final ILibraryProvider base )
+    {
+        this.base = base;
+    }
+    
+    public ILibraryProvider getRootProvider()
+    {
+        ILibraryProvider prov = this;
+        
+        while( prov.getBaseProvider() != null )
+        {
+            prov = prov.getBaseProvider();
+        }
+        
+        return prov;
+    }
+    
+    public boolean isAbstract()
+    {
+        return this.isAbstract;
+    }
+    
+    void setIsAbstract( final boolean isAbstract )
+    {
+        this.isAbstract = isAbstract;
+    }
+    
+    public boolean isHidden()
+    {
+        return this.isHidden;
+    }
+    
+    void setIsHidden( final boolean isHidden )
+    {
+        this.isHidden = isHidden;
+    }
+    
+    public int getPriority()
+    {
+        if( this.priority != null )
+        {
+            return this.priority.intValue();
+        }
+        else
+        {
+            if( this.base != null )
+            {
+                return this.base.getPriority();
+            }
+            else
+            {
+                return 0;
+            }
+        }
+    }
+    
+    void setPriority( final int priority )
+    {
+        this.priority = Integer.valueOf( priority );
+    }
+    
+    public boolean isEnabledFor( final IFacetedProjectBase fproj,
+                                 final IProjectFacetVersion fv )
+    {
+        return isEnabledFor( fproj, fv, null );
+    }
+    
+    public boolean isEnabledFor( final IFacetedProjectBase fproj,
+                                 final IProjectFacetVersion fv,
+                                 final Map<String,Object> customVariables )
+    {
+        final EvaluationContext evalContext = new EvaluationContext( null, fv );
+        final EnablementExpressionContext context = new EnablementExpressionContext( fproj, fv, this );
+        evalContext.setAllowPluginActivation( true );
+        
+        if( customVariables != null )
+        {
+            for( Map.Entry<String,Object> entry : customVariables.entrySet() )
+            {
+                evalContext.addVariable( entry.getKey(), entry.getValue() );
+            }
+        }
+        
+        evalContext.addVariable( EXPR_VAR_CONTEXT, context );
+        evalContext.addVariable( EXPR_VAR_REQUESTING_PROJECT_FACET, fv );
+        evalContext.addVariable( EXPR_VAR_PROJECT_FACETS, fproj.getProjectFacets() );
+        evalContext.addVariable( EXPR_VAR_TARGETED_RUNTIMES, fproj.getTargetedRuntimes() );
+        evalContext.addVariable( EXPR_VAR_PROVIDER, this );
+        
+        for( Expression expression : getEnablementConditions() )
+        {
+            try
+            {
+                final EvaluationResult evalResult = expression.evaluate( evalContext );
+                
+                if( evalResult == EvaluationResult.FALSE )
+                {
+                    return false;
+                }
+            }
+            catch( CoreException e )
+            {
+                log( e );
+            }
+        }
+
+        return true;
+    }
+    
+    void setEnablementCondition( final Expression enablementCondition )
+    {
+        this.enablementCondition = enablementCondition;
+    }
+    
+    private List<Expression> getEnablementConditions()
+    {
+        final List<Expression> expressions = new ArrayList<Expression>();
+        LibraryProvider provider = this;
+        
+        while( provider != null )
+        {
+            if( provider.enablementCondition != null )
+            {
+                expressions.add( provider.enablementCondition );
+            }
+            
+            provider = (LibraryProvider) provider.base;
+        }
+        
+        return expressions;
+    }
+    
+    public Map<String,String> getParams()
+    {
+        final Map<String,String> result = new HashMap<String,String>();
+        
+        if( this.base != null )
+        {
+            result.putAll( ( (LibraryProvider) this.base ).getParams() );
+        }
+        
+        result.putAll( this.params );
+        
+        return result;
+    }
+    
+    void addParam( final String name,
+                   final String value )
+    {
+        this.params.put( name, value );
+    }
+
+    public boolean isActionSupported( final LibraryProviderActionType type )
+    {
+        return ( getActionDef( type ) != null );
+    }
+    
+    public LibraryProviderOperation createOperation( final LibraryProviderActionType type )
+    {
+        final ActionDef actionDef = getActionDef( type );
+        
+        if( actionDef == null )
+        {
+            throw new IllegalArgumentException();
+        }
+        
+        final Class<LibraryProviderOperation> cl = actionDef.getOperationClass();
+        
+        if( cl == null )
+        {
+            // The operation class could not be loaded. The problem has been reported to 
+            // the user via the log.
+            
+            return null;
+        }
+        
+        return instantiate( actionDef.getPluginId(), cl );
+    }
+
+    public LibraryProviderOperationConfig createInstallOperationConfig( final LibraryInstallDelegate libraryInstallDelegate )
+    {
+        final ActionDef actionDef = getActionDef( LibraryProviderActionType.INSTALL );
+        
+        if( actionDef == null )
+        {
+            throw new IllegalArgumentException();
+        }
+        
+        final Class<LibraryProviderOperationConfig> cl = actionDef.getConfigClass();
+        
+        if( cl == null )
+        {
+            // Either the action has no config or the config class could not be loaded. In
+            // the latter case, the problem has been reported to the user via the log.
+            
+            return null;
+        }
+        
+        final LibraryProviderOperationConfig cfg = instantiate( actionDef.getPluginId(), cl );
+        
+        if( cfg instanceof LibraryProviderInstallOperationConfig )
+        {
+            ( (LibraryProviderInstallOperationConfig) cfg ).init( libraryInstallDelegate, this );
+        }
+        else
+        {
+            cfg.init( libraryInstallDelegate.getFacetedProject(), 
+                      libraryInstallDelegate.getProjectFacetVersion(), this );
+        }
+        
+        return cfg;
+    }
+    
+    public LibraryProviderOperationConfig createOperationConfig( final IFacetedProjectBase fproj,
+                                                                 final IProjectFacetVersion fv,
+                                                                 final LibraryProviderActionType type )
+    {
+        final ActionDef actionDef = getActionDef( type );
+        
+        if( actionDef == null )
+        {
+            throw new IllegalArgumentException();
+        }
+        
+        final Class<LibraryProviderOperationConfig> cl = actionDef.getConfigClass();
+        
+        if( cl == null )
+        {
+            // Either the action has no config or the config class could not be loaded. In
+            // the latter case, the problem has been repoted to the user via the log.
+            
+            return null;
+        }
+        
+        final LibraryProviderOperationConfig cfg = instantiate( actionDef.getPluginId(), cl );
+        cfg.init( fproj, fv, this );
+        
+        return cfg;
+    }
+    
+    ActionDef getActionDef( final LibraryProviderActionType type )
+    {
+        ActionDef actionDef = this.actionDefs.get( type );
+        
+        if( actionDef == null && this.base != null )
+        {
+            actionDef = ( (LibraryProvider) this.base ).getActionDef( type );
+        }
+        
+        return actionDef;
+    }
+    
+    void addActionDef( final LibraryProviderActionType type,
+                       final String configClassName,
+                       final String operationClassName )
+    {
+        final ActionDef actionDef = new ActionDef( configClassName, operationClassName );
+        this.actionDefs.put( type, actionDef );
+    }
+    
+    public int compareTo( final ILibraryProvider other )
+    {
+        final int p1 = getPriority();
+        final int p2 = other.getPriority();
+        
+        int result = ( p1 < p2 ? -1 : ( p1 == p2 ? 0 : 1 ) );
+        
+        if( result == 0 )
+        {
+            result = getId().compareTo( other.getId() );
+        }
+        
+        return result;
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryProviderFrameworkImpl.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryProviderFrameworkImpl.java
new file mode 100644
index 0000000..6a547b8
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryProviderFrameworkImpl.java
@@ -0,0 +1,505 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.PLUGIN_ID;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.createErrorStatus;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findOptionalElement;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findRequiredAttribute;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findRequiredElement;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.getElementValue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.resources.IProject;
+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.jst.common.project.facet.core.libprov.ILibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderActionType;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderFramework;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
+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.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.InvalidExtensionException;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class LibraryProviderFrameworkImpl
+{
+    private static final String UNKNOWN_LIBRARY_PROVIDER = "unknown-library-provider"; //$NON-NLS-1$
+    
+    private static final String EXTENSION_POINT_ID = "libraryProviders"; //$NON-NLS-1$
+    
+    private static final String EL_ACTION = "action"; //$NON-NLS-1$
+    private static final String EL_CONFIG = "config"; //$NON-NLS-1$
+    private static final String EL_ENABLEMENT = "enablement"; //$NON-NLS-1$
+    private static final String EL_LABEL = "label"; //$NON-NLS-1$
+    private static final String EL_OPERATION = "operation"; //$NON-NLS-1$
+    private static final String EL_PARAM = "param"; //$NON-NLS-1$
+    private static final String EL_PRIORITY = "priority"; //$NON-NLS-1$
+    private static final String EL_PROVIDER = "provider"; //$NON-NLS-1$
+    private static final String ATTR_ABSTRACT = "abstract"; //$NON-NLS-1$
+    private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
+    private static final String ATTR_EXTENDS = "extends"; //$NON-NLS-1$
+    private static final String ATTR_HIDDEN = "hidden"; //$NON-NLS-1$
+    private static final String ATTR_ID = "id"; //$NON-NLS-1$
+    private static final String ATTR_NAME = "name"; //$NON-NLS-1$
+    private static final String ATTR_TYPE = "type"; //$NON-NLS-1$
+    private static final String ATTR_VALUE = "value"; //$NON-NLS-1$
+    
+    private static final String PREFS_LIBPROV = "libprov"; //$NON-NLS-1$
+    private static final String PREFS_PROVIDER_ID = "provider-id"; //$NON-NLS-1$
+    private static final String PREFS_LAST_PROVIDER_USED = PREFS_LIBPROV + "/last-provider-used"; //$NON-NLS-1$
+    
+    private static LibraryProviderFrameworkImpl instance = null;
+    
+    private final Set<ILibraryProvider> providers;
+    private final Set<ILibraryProvider> providersReadOnly;
+    private final Map<String,ILibraryProvider> providersLookupTable;
+    
+    public LibraryProviderFrameworkImpl()
+    {
+        this.providers = new HashSet<ILibraryProvider>();
+        this.providersReadOnly = Collections.unmodifiableSet( this.providers );
+        this.providersLookupTable = new HashMap<String,ILibraryProvider>();
+        
+        readExtensions();
+    }
+    
+    public static synchronized LibraryProviderFrameworkImpl get()
+    {
+        if( instance == null )
+        {
+            instance = new LibraryProviderFrameworkImpl();
+        }
+        
+        return instance;
+    }
+    
+    public Set<ILibraryProvider> getProviders()
+    {
+        return this.providersReadOnly;
+    }
+    
+    public boolean isProviderDefined( final String id )
+    {
+        return this.providersLookupTable.containsKey( id );
+    }
+    
+    public ILibraryProvider getProvider( final String id )
+    {
+        if( ! isProviderDefined( id ) )
+        {
+            final String msg = Resources.bind( Resources.libraryProviderNotDefined, id );
+            throw new IllegalArgumentException( msg );
+        }
+        
+        return this.providersLookupTable.get( id );
+    }
+    
+    public ILibraryProvider getCurrentProvider( final IProject project,
+                                                final IProjectFacet facet )
+    {
+        final IFacetedProject fproj;
+        
+        try
+        {
+            fproj = ProjectFacetsManager.create( project );
+        }
+        catch( CoreException e )
+        {
+            throw new RuntimeException( e );
+        }
+        
+        if( ! fproj.hasProjectFacet( facet ) )
+        {
+            return null;
+        }
+        
+        String providerId = null;
+        
+        try
+        {
+            Preferences prefs = fproj.getPreferences( facet );
+            
+            if( prefs.nodeExists( PREFS_LIBPROV ) )
+            {
+                prefs = prefs.node( PREFS_LIBPROV );
+                providerId = prefs.get( PREFS_PROVIDER_ID, null );
+            }
+        }
+        catch( BackingStoreException e )
+        {
+            throw new RuntimeException( e );
+        }
+        
+        ILibraryProvider provider = null;
+        
+        if( providerId != null )
+        {
+            if( LibraryProviderFramework.isProviderDefined( providerId ) )
+            {
+                provider = LibraryProviderFramework.getProvider( providerId );
+            }
+            else
+            {
+                provider = getProvider( UNKNOWN_LIBRARY_PROVIDER );
+            }
+        }
+        else
+        {
+            provider = LegacyLibraryProviderDetectorsExtensionPoint.detect( project, facet );
+            
+            if( provider == null )
+            {
+                provider = getProvider( UNKNOWN_LIBRARY_PROVIDER );
+            }
+        }
+        
+        return provider;
+    }
+    
+    public void setCurrentProvider( final IProject project,
+                                    final IProjectFacet facet,
+                                    final ILibraryProvider provider )
+    {
+        final IFacetedProject fproj;
+        
+        try
+        {
+            fproj = ProjectFacetsManager.create( project );
+        }
+        catch( CoreException e )
+        {
+            throw new RuntimeException( e );
+        }
+        
+        try
+        {
+            Preferences prefs = fproj.getPreferences( facet ).node( PREFS_LIBPROV );
+            
+            if( provider == null )
+            {
+                prefs.removeNode();
+            }
+            else
+            {
+                prefs.put( PREFS_PROVIDER_ID, provider.getId() );
+            }
+            
+            prefs.flush();
+        }
+        catch( BackingStoreException e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+    
+    public ILibraryProvider getLastProviderUsed( final IProjectFacetVersion fv )
+    {
+        try
+        {
+            final IProjectFacet facet = fv.getProjectFacet();
+            
+            final Preferences prefs 
+                = FacetedProjectFramework.getPreferences( facet ).node( PREFS_LAST_PROVIDER_USED );
+            
+            final String providerId = prefs.get( fv.getVersionString(), null );
+            
+            if( providerId != null )
+            {
+                if( isProviderDefined( providerId ) )
+                {
+                    return getProvider( providerId );
+                }
+            }
+        }
+        catch( BackingStoreException e )
+        {
+            log( e );
+        }
+        
+        return null;
+    }
+    
+    public void setLastProviderUsed( final IProjectFacetVersion fv,
+                                     final ILibraryProvider provider )
+    {
+        try
+        {
+            final IProjectFacet facet = fv.getProjectFacet();
+            
+            final Preferences prefs 
+                = FacetedProjectFramework.getPreferences( facet ).node( PREFS_LAST_PROVIDER_USED );
+            
+            prefs.put( fv.getVersionString(), provider.getId() );
+        
+            prefs.flush();
+        }
+        catch( BackingStoreException e )
+        {
+            log( e );
+        }
+    }
+    
+    public static void reportInvalidActionType( final String type,
+                                                final String pluginId )
+    {
+        final String msg = Resources.bind( Resources.invalidActionType, type, pluginId ); 
+        log( createErrorStatus( msg ) );
+    }
+    
+    public static void reportProviderNotDefined( final String providerId,
+                                                 final String pluginId )
+    {
+        final String msg 
+            = Resources.bind( Resources.libraryProviderNotDefinedWithPlugin, providerId,
+                              pluginId );
+        
+        log( createErrorStatus( msg ) );
+    }
+    
+    private void readExtensions()
+    {
+        final IExtensionRegistry registry = Platform.getExtensionRegistry();
+        
+        final IExtensionPoint point 
+            = registry.getExtensionPoint( PLUGIN_ID, EXTENSION_POINT_ID );
+        
+        if( point == null )
+        {
+            throw new IllegalStateException();
+        }
+        
+        final List<IConfigurationElement> cfgels = new ArrayList<IConfigurationElement>();
+        
+        for( IExtension extension : point.getExtensions() )
+        {
+            for( IConfigurationElement element : extension.getConfigurationElements() )
+            {
+                cfgels.add( element );
+            }
+        }
+        
+        final Map<LibraryProvider,String> providerToBaseIdMap 
+            = new HashMap<LibraryProvider,String>();
+
+        for( IConfigurationElement element : cfgels )
+        {
+            if( ! element.getName().equals( EL_PROVIDER ) )
+            {
+                continue;
+            }
+            
+            try
+            {
+                final LibraryProvider provider = new LibraryProvider();
+                provider.setPluginId( element.getContributor().getName() );
+                
+                provider.setId( findRequiredAttribute( element, ATTR_ID ) );
+                
+                if( this.providersLookupTable.containsKey( provider.getId() ) )
+                {
+                    final String msg 
+                        = Resources.bind( Resources.libraryProviderIdAlreadyUsed, 
+                                          provider.getId() );
+                    
+                    log( createErrorStatus( msg ) );
+                    
+                    throw new InvalidExtensionException();
+                }
+                
+                final String baseProviderId = element.getAttribute( ATTR_EXTENDS );
+                
+                if( baseProviderId != null )
+                {
+                    providerToBaseIdMap.put( provider, baseProviderId.trim() );
+                }
+                
+                final String abstractAttr = element.getAttribute( ATTR_ABSTRACT );
+                
+                if( abstractAttr != null )
+                {
+                    provider.setIsAbstract( Boolean.valueOf( abstractAttr ) );
+                }
+                
+                final String hiddenAttr = element.getAttribute( ATTR_HIDDEN );
+                
+                if( hiddenAttr != null )
+                {
+                    provider.setIsHidden( Boolean.valueOf( hiddenAttr ) );
+                }
+
+                for( IConfigurationElement child : element.getChildren() )
+                {
+                    final String childName = child.getName();
+                    
+                    if( childName.equals( EL_LABEL ) )
+                    {
+                        provider.setLabel( child.getValue().trim() );
+                    }
+                    else if( childName.equals( EL_ENABLEMENT ) )
+                    {
+                        final Expression expr;
+                        
+                        try
+                        {
+                            expr = ExpressionConverter.getDefault().perform( child );
+                        }
+                        catch( CoreException e )
+                        {
+                            log( e );
+                            throw new InvalidExtensionException();
+                        }
+                        
+                        provider.setEnablementCondition( expr );
+                    }
+                    else if( childName.equals( EL_PRIORITY ) )
+                    {
+                        final String priorityString = child.getValue().trim();
+                        final int priority;
+                        
+                        try
+                        {
+                            priority = Integer.parseInt( priorityString );
+                        }
+                        catch( NumberFormatException e )
+                        {
+                            log( e );
+                            throw new InvalidExtensionException();
+                        }
+                        
+                        provider.setPriority( priority );
+                    }
+                    else if( childName.equals( EL_PARAM ) )
+                    {
+                        final String name = findRequiredAttribute( child, ATTR_NAME );
+                        
+                        String value = child.getAttribute( ATTR_VALUE );
+                        
+                        if( value == null )
+                        {
+                            value = getElementValue( child, null );
+                        }
+                        
+                        provider.addParam( name, value );
+                    }
+                    else if( childName.equals( EL_ACTION ) )
+                    {
+                        final String type = findRequiredAttribute( child, ATTR_TYPE ).toUpperCase();
+                        final LibraryProviderActionType t;
+                        
+                        try
+                        {
+                            t = LibraryProviderActionType.valueOf( type );
+                        }
+                        catch( IllegalArgumentException e )
+                        {
+                            reportInvalidActionType( type, provider.getPluginId() );
+                            throw new InvalidExtensionException();
+                        }
+                        
+                        final IConfigurationElement elConfig 
+                            = findOptionalElement( child, EL_CONFIG );
+                        
+                        final String configClassName;
+                        
+                        if( elConfig == null )
+                        {
+                            configClassName = LibraryProviderOperationConfig.class.getName();
+                        }
+                        else
+                        {
+                            configClassName = findRequiredAttribute( elConfig, ATTR_CLASS );
+                        }
+                        
+                        final IConfigurationElement elOperation 
+                            = findRequiredElement( child, EL_OPERATION );
+                        
+                        final String operationClassName 
+                            = findRequiredAttribute( elOperation, ATTR_CLASS );
+                        
+                        provider.addActionDef( t, configClassName, operationClassName );
+                    }
+                }
+                
+                if( provider != null )
+                {
+                    this.providers.add( provider );
+                    this.providersLookupTable.put( provider.getId(), provider );
+                }
+            }
+            catch( InvalidExtensionException e )
+            {
+                // Ignore and continue. The problem has already been reported to the user
+                // in the log.
+            }
+        }
+        
+        for( Map.Entry<LibraryProvider,String> entry : providerToBaseIdMap.entrySet() )
+        {
+            final LibraryProvider provider = entry.getKey();
+            final String baseProviderId = entry.getValue();
+            final ILibraryProvider baseProvider = this.providersLookupTable.get( baseProviderId );
+            
+            if( baseProvider == null )
+            {
+                reportProviderNotDefined( baseProviderId, provider.getPluginId() );
+                this.providers.remove( provider );
+                this.providersLookupTable.remove( provider.getId() );
+            }
+            else
+            {
+                provider.setBaseProvider( baseProvider );
+            }
+        }
+    }
+    
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String libraryProviderNotDefined;
+        public static String libraryProviderNotDefinedWithPlugin;
+        public static String libraryProviderIdAlreadyUsed;
+        public static String invalidActionType;
+        
+        static
+        {
+            initializeMessages( LibraryProviderFrameworkImpl.class.getName(), 
+                                Resources.class );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryProviderFrameworkImpl.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryProviderFrameworkImpl.properties
new file mode 100644
index 0000000..5c7d718
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/LibraryProviderFrameworkImpl.properties
@@ -0,0 +1,4 @@
+libraryProviderNotDefined = Library provider "{0}" is not defined.
+libraryProviderNotDefinedWithPlugin = Library provider "{0}" is not defined. This id is referenced in plugin {1}.
+libraryProviderIdAlreadyUsed = Library provider id \"{0}\" is already used by another provider.
+invalidActionType = Invalid library provider action type \"{0}\" was used in plugin {1}.
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/PropertiesHost.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/PropertiesHost.java
new file mode 100644
index 0000000..8874578
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/PropertiesHost.java
@@ -0,0 +1,109 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import org.eclipse.jst.common.project.facet.core.libprov.IPropertyChangeListener;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public abstract class PropertiesHost
+{
+    private final Set<IPropertyChangeListener> globalListeners
+        = new CopyOnWriteArraySet<IPropertyChangeListener>();
+    
+    private final Map<String,Set<IPropertyChangeListener>> propertySpecificListeners 
+        = new HashMap<String,Set<IPropertyChangeListener>>();
+    
+    public void addListener( final IPropertyChangeListener listener,
+                             final String... properties )
+    {
+        if( properties.length == 0 )
+        {
+            synchronized( this.globalListeners )
+            {
+                this.globalListeners.add( listener );
+            }
+        }
+        else
+        {
+            synchronized( this.propertySpecificListeners )
+            {
+                for( String property : properties )
+                {
+                    Set<IPropertyChangeListener> list = this.propertySpecificListeners.get( property );
+                    
+                    if( list == null )
+                    {
+                        list = new CopyOnWriteArraySet<IPropertyChangeListener>();
+                        this.propertySpecificListeners.put( property, list );
+                    }
+                    
+                    list.add( listener );
+                }
+            }
+        }
+    }
+    
+    public void removeListener( final IPropertyChangeListener listener )
+    {
+        boolean globalListenerRemoveResult;
+        
+        synchronized( this.globalListeners )
+        {
+            globalListenerRemoveResult = this.globalListeners.remove( listener );
+        }
+        
+        if( globalListenerRemoveResult == false )
+        {
+            synchronized( this.propertySpecificListeners )
+            {
+                for( Set<IPropertyChangeListener> listeners : this.propertySpecificListeners.values() )
+                {
+                    listeners.remove( listener );
+                }
+            }
+        }
+    }
+    
+    protected void notifyListeners( final String property,
+                                    final Object oldValue,
+                                    final Object newValue )
+    {
+        for( IPropertyChangeListener listener : this.globalListeners )
+        {
+            listener.propertyChanged( property, oldValue, newValue );
+        }
+        
+        final Set<IPropertyChangeListener> listeners;
+        
+        synchronized( this.propertySpecificListeners )
+        {
+            listeners = this.propertySpecificListeners.get( property );
+        }
+        
+        if( listeners != null )
+        {
+            for( IPropertyChangeListener listener : listeners )
+            {
+                listener.propertyChanged( property, oldValue, newValue );
+            }
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/RuntimeLibraryProviderInstallOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/RuntimeLibraryProviderInstallOperation.java
new file mode 100644
index 0000000..52f335b
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/RuntimeLibraryProviderInstallOperation.java
@@ -0,0 +1,56 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.beginTask;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.done;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.worked;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.ClasspathHelper;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public class RuntimeLibraryProviderInstallOperation
+
+    extends LibraryProviderOperation
+    
+{
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        beginTask( monitor, "", 1 ); //$NON-NLS-1$
+        
+        try
+        {
+            final IProjectFacetVersion fv = config.getProjectFacetVersion();
+            
+            ClasspathHelper.addClasspathEntries( config.getFacetedProject().getProject(), fv );
+            
+            worked( monitor, 1 );
+        }
+        finally
+        {
+            done( monitor );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/RuntimeLibraryProviderPropertyTester.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/RuntimeLibraryProviderPropertyTester.java
new file mode 100644
index 0000000..835b298
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/RuntimeLibraryProviderPropertyTester.java
@@ -0,0 +1,60 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import java.util.List;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jst.common.project.facet.core.IClasspathProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.EnablementExpressionContext;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class RuntimeLibraryProviderPropertyTester
+
+    extends PropertyTester
+    
+{
+    public boolean test( final Object receiver, 
+                         final String property, 
+                         final Object[] args, 
+                         final Object value )
+    {
+        if( receiver instanceof EnablementExpressionContext )
+        {
+            final EnablementExpressionContext context = (EnablementExpressionContext) receiver;
+            final IProjectFacetVersion fv = context.getRequestingProjectFacetVersion();
+            final IRuntime runtime = context.getFacetedProject().getPrimaryRuntime();
+            
+            if( runtime != null )
+            {
+                final IClasspathProvider cpprov 
+                    = (IClasspathProvider) runtime.getAdapter( IClasspathProvider.class );
+                
+                final List<IClasspathEntry> cpentries = cpprov.getClasspathEntries( fv );
+                
+                if( cpentries != null && ! cpentries.isEmpty() )
+                {
+                    return true;
+                }
+            }
+        }
+            
+        return false;
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/RuntimeLibraryProviderUninstallOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/RuntimeLibraryProviderUninstallOperation.java
new file mode 100644
index 0000000..9dd226b
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/RuntimeLibraryProviderUninstallOperation.java
@@ -0,0 +1,56 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.beginTask;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.done;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.worked;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.ClasspathHelper;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public class RuntimeLibraryProviderUninstallOperation
+
+    extends LibraryProviderOperation
+    
+{
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        beginTask( monitor, "", 1 ); //$NON-NLS-1$
+        
+        try
+        {
+            final IProjectFacetVersion fv = config.getProjectFacetVersion();
+            
+            ClasspathHelper.removeClasspathEntries( config.getFacetedProject().getProject(), fv );
+            
+            worked( monitor, 1 );
+        }
+        finally
+        {
+            done( monitor );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/UnknownLibraryProviderInstallOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/UnknownLibraryProviderInstallOperation.java
new file mode 100644
index 0000000..764636c
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/internal/UnknownLibraryProviderInstallOperation.java
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class UnknownLibraryProviderInstallOperation
+
+    extends LibraryProviderOperation
+    
+{
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        // This is never expected to be called...
+        throw new IllegalStateException();
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/BundleReference.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/BundleReference.java
new file mode 100644
index 0000000..5b14306
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/BundleReference.java
@@ -0,0 +1,96 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.osgi;
+
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+/**
+ * @since 1.4
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class BundleReference
+{
+    private String id;
+    private VersionRange versionRange;
+    
+    public BundleReference( final String id,
+                            final VersionRange versionRange )
+    {
+        this.id = id;
+        this.versionRange = versionRange;
+    }
+    
+    public String getBundleId()
+    {
+        return this.id;
+    }
+    
+    public VersionRange getVersionRange()
+    {
+        return this.versionRange;
+    }
+    
+    public boolean isResolvable()
+    {
+        return ( getBundles() != null );
+    }
+    
+    public Bundle getBundle()
+    {
+        final Bundle[] bundles = getBundles();
+        
+        if( bundles == null )
+        {
+            return null;
+        }
+        
+        final SortedMap<Version,Bundle> bundlesByVersion = new TreeMap<Version,Bundle>(); 
+        
+        for( Bundle bundle : bundles )
+        {
+            final Version version = getBundleVersion( bundle );
+            
+            if( version != null )
+            {
+                bundlesByVersion.put( version, bundle );
+            }
+        }
+        
+        if( bundlesByVersion.isEmpty() )
+        {
+            return null;
+        }
+        else
+        {
+            return bundlesByVersion.get( bundlesByVersion.lastKey() );
+        }
+    }
+    
+    private Bundle[] getBundles()
+    {
+        return Platform.getBundles( this.id, this.versionRange == null ? null : this.versionRange.toString() );
+    }
+    
+    private static Version getBundleVersion( final Bundle bundle )
+    {
+        final String versionString = (String) bundle.getHeaders().get( "Bundle-Version" ); //$NON-NLS-1$
+        return versionString == null ? null : new Version( versionString );
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesContainer.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesContainer.java
new file mode 100644
index 0000000..5fd1f0e
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesContainer.java
@@ -0,0 +1,443 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.osgi;
+
+import static org.eclipse.jst.common.project.facet.core.JavaFacet.isJavaProject;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+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.osgi.service.resolver.VersionRange;
+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.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * @since 1.4
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class OsgiBundlesContainer
+{
+    public static final String CONTAINER_ID = "eclipse.fproj.jdt.libprov.osgi"; //$NON-NLS-1$
+    public static final IPath CONTAINER_PATH = new Path( CONTAINER_ID );
+    
+    private static final String PREFS_OSGI_BUNDLES_CONTAINER = "osgi-bundles-container"; //$NON-NLS-1$
+    private static final String PREFS_BUNDLES = "bundles"; //$NON-NLS-1$
+    private static final String PREFS_LABEL = "label"; //$NON-NLS-1$
+    
+    public static boolean isOnClasspath( final IProject project,
+                                         final IProjectFacet facet )
+    
+        throws CoreException
+        
+    {
+        if( isJavaProject( project ) )
+        {
+            return isOnClasspath( JavaCore.create( project ), facet );
+        }
+        
+        return false;
+    }
+    
+    public static boolean isOnClasspath( final IJavaProject project,
+                                         final IProjectFacet facet )
+    
+        throws CoreException
+        
+    {
+        final IClasspathEntry[] cp = project.getRawClasspath();
+        
+        for( IClasspathEntry cpe : cp )
+        {
+            if( isOsgiBundlesContainer( cpe ) )
+            {
+                final String fid = cpe.getPath().segment( 1 );
+                return facet.getId().equals( fid );
+            }
+        }
+        
+        return false;
+    }
+    
+    public static void addToClasspath( final IProject project,
+                                       final IProjectFacet facet )
+    
+        throws CoreException
+        
+    {
+        addToClasspath( project, facet, null );
+    }
+
+    public static void addToClasspath( final IProject project,
+                                       final IProjectFacet facet,
+                                       final IClasspathAttribute[] attributes )
+    
+        throws CoreException
+        
+    {
+        if( isJavaProject( project ) )
+        {
+            addToClasspath( JavaCore.create( project ), facet, attributes );
+        }
+    }
+
+    public static void addToClasspath( final IJavaProject project,
+                                       final IProjectFacet facet )
+    
+        throws CoreException
+        
+    {
+        addToClasspath( project, facet, null );
+    }
+    
+    public static void addToClasspath( final IJavaProject project,
+                                       final IProjectFacet facet,
+                                       final IClasspathAttribute[] attributes )
+    
+        throws CoreException
+        
+    {
+        if( ! isOnClasspath( project, facet ) )
+        {
+            final IClasspathEntry[] oldcp = project.getRawClasspath();
+            final IClasspathEntry[] newcp = new IClasspathEntry[ oldcp.length + 1 ];
+            System.arraycopy( oldcp, 0, newcp, 0, oldcp.length );
+            final IPath path = CONTAINER_PATH.append( facet.getId() );
+            final IClasspathAttribute[] attrs = ( attributes != null ? attributes : new IClasspathAttribute[ 0 ] );
+            newcp[ newcp.length - 1 ] = JavaCore.newContainerEntry( path, null, attrs, false );
+            
+            project.setRawClasspath( newcp, null );
+        }
+    }
+    
+    public static void removeFromClasspath( final IProject project,
+                                            final IProjectFacet facet )
+    
+        throws CoreException
+        
+    {
+        if( isJavaProject( project ) )
+        {
+            removeFromClasspath( JavaCore.create( project ), facet );
+        }
+    }
+    
+    public static void removeFromClasspath( final IJavaProject project,
+                                            final IProjectFacet facet )
+    
+        throws CoreException
+        
+    {
+        final IClasspathEntry[] oldcp = project.getRawClasspath();
+        
+        for( int i = 0; i < oldcp.length; i++ )
+        {
+            final IClasspathEntry cpe = oldcp[ i ];
+            
+            if( isOsgiBundlesContainer( cpe ) )
+            {
+                final String fid = cpe.getPath().segment( 1 );
+                
+                if( facet.getId().equals( fid ) )
+                {
+                    final IClasspathEntry[] newcp = new IClasspathEntry[ oldcp.length - 1 ];
+                    System.arraycopy( oldcp, 0, newcp, 0, i );
+                    System.arraycopy( oldcp, i + 1, newcp, i, oldcp.length - i - 1 );
+                    
+                    project.setRawClasspath( newcp, null );
+                    
+                    return;
+                }
+            }
+        }
+    }
+    
+    public static boolean isOsgiBundlesContainer( final IClasspathEntry cpe )
+    {
+        final IPath path = cpe.getPath();
+        return path.segmentCount() >= 2 && path.segment( 0 ).equals( CONTAINER_ID );
+    }
+    
+    public static List<BundleReference> getBundleReferences( final IProject project,
+                                                             final IProjectFacet facet )
+    {
+        IFacetedProject fproj = null;
+        
+        try
+        {
+            fproj = ProjectFacetsManager.create( project );
+        }
+        catch( CoreException e )
+        {
+            log( e );
+        }
+        
+        if( fproj == null )
+        {
+            return Collections.emptyList();
+        }
+        else
+        {
+            return getBundleReferences( fproj, facet );
+        }
+    }
+    
+    public static List<BundleReference> getBundleReferences( final IFacetedProject project,
+                                                             final IProjectFacet facet )
+    {
+        final List<BundleReference> bundleReferences = new ArrayList<BundleReference>();
+        
+        try
+        {
+            Preferences prefs = project.getPreferences( facet );
+            
+            if( prefs.nodeExists( PREFS_OSGI_BUNDLES_CONTAINER ) )
+            {
+                prefs = prefs.node( PREFS_OSGI_BUNDLES_CONTAINER );
+                
+                final String unparsedMetadata = prefs.get( PREFS_BUNDLES, null );
+                
+                if( unparsedMetadata != null )
+                {
+                    for( String unparsedBundleReference : unparsedMetadata.split( ";" ) ) //$NON-NLS-1$
+                    {
+                        bundleReferences.add( parseBundleReference( unparsedBundleReference ) );
+                    }
+                }
+            }
+        }
+        catch( BackingStoreException e )
+        {
+            log( e );
+        }
+        
+        return bundleReferences;
+    }
+    
+    public static void setBundleReferences( final IProject project,
+                                            final IProjectFacet facet,
+                                            final List<BundleReference> bundleReferences )
+    {
+        IFacetedProject fproj = null;
+        
+        try
+        {
+            fproj = ProjectFacetsManager.create( project );
+        }
+        catch( CoreException e )
+        {
+            log( e );
+        }
+        
+        if( fproj != null )
+        {
+            setBundleReferences( fproj, facet, bundleReferences );
+        }
+    }
+    
+    public static void setBundleReferences( final IFacetedProject project,
+                                            final IProjectFacet facet,
+                                            final List<BundleReference> bundleReferences )
+    {
+        try
+        {
+            Preferences prefs = project.getPreferences( facet );
+            
+            if( bundleReferences == null || bundleReferences.isEmpty() )
+            {
+                prefs.removeNode();
+            }
+            else
+            {
+                final StringBuilder buf = new StringBuilder();
+                
+                for( BundleReference bundleReference : bundleReferences )
+                {
+                    if( buf.length() > 0 )
+                    {
+                        buf.append( ';' );
+                    }
+                    
+                    buf.append( convert( bundleReference ) );
+                }
+                
+                prefs = prefs.node( PREFS_OSGI_BUNDLES_CONTAINER );
+                prefs.put( PREFS_BUNDLES, buf.toString() );
+            }
+            
+            prefs.flush();
+        }
+        catch( BackingStoreException e )
+        {
+            log( e );
+        }
+    }
+    
+    public static BundleReference parseBundleReference( final String bundleReferenceString )
+    {
+        String bundleId;
+        VersionRange versionRange;
+        
+        final int colon = bundleReferenceString.indexOf( ':' );
+        
+        if( colon == -1 )
+        {
+            bundleId = bundleReferenceString;
+            versionRange = null;
+        }
+        else
+        {
+            bundleId = bundleReferenceString.substring( 0, colon );
+            
+            try
+            {
+                versionRange = new VersionRange( bundleReferenceString.substring( colon + 1 ) );
+            }
+            catch( IllegalArgumentException e )
+            {
+                log( e );
+                versionRange = null;
+            }
+        }
+        
+        return new BundleReference( bundleId, versionRange );        
+    }
+    
+    public static String getContainerLabel( final IProject project,
+                                            final IProjectFacet facet )
+    {
+        IFacetedProject fproj = null;
+        
+        try
+        {
+            fproj = ProjectFacetsManager.create( project );
+        }
+        catch( CoreException e )
+        {
+            log( e );
+        }
+        
+        if( fproj == null )
+        {
+            return null;
+        }
+        else
+        {
+            return getContainerLabel( fproj, facet );
+        }
+    }
+    
+    public static String getContainerLabel( final IFacetedProject project,
+                                            final IProjectFacet facet )
+    {
+        String label = null;
+        
+        try
+        {
+            Preferences prefs = project.getPreferences( facet );
+            
+            if( prefs.nodeExists( PREFS_OSGI_BUNDLES_CONTAINER ) )
+            {
+                prefs = prefs.node( PREFS_OSGI_BUNDLES_CONTAINER );
+                label = prefs.get( PREFS_LABEL, (String) null );
+            }
+        }
+        catch( BackingStoreException e )
+        {
+            log( e );
+        }
+        
+        return label;
+    }
+    
+    public static void setContainerLabel( final IProject project,
+                                          final IProjectFacet facet,
+                                          final String label )
+    {
+        IFacetedProject fproj = null;
+        
+        try
+        {
+            fproj = ProjectFacetsManager.create( project );
+        }
+        catch( CoreException e )
+        {
+            log( e );
+        }
+        
+        if( fproj != null )
+        {
+            setContainerLabel( fproj, facet, label );
+        }
+    }
+    
+    public static void setContainerLabel( final IFacetedProject project,
+                                          final IProjectFacet facet,
+                                          final String label )
+    {
+        try
+        {
+            Preferences prefs = project.getPreferences( facet );
+            prefs = prefs.node( PREFS_OSGI_BUNDLES_CONTAINER );
+            
+            if( label == null )
+            {
+                prefs.remove( PREFS_LABEL );
+            }
+            else
+            {
+                prefs.put( PREFS_LABEL, label );
+            }
+            
+            prefs.flush();
+        }
+        catch( BackingStoreException e )
+        {
+            log( e );
+        }
+    }
+    
+    private static String convert( final BundleReference bundleReference )
+    {
+        final StringBuilder buf = new StringBuilder();
+        
+        buf.append( bundleReference.getBundleId() );
+        
+        if( bundleReference.getVersionRange() != null )
+        {
+            buf.append( ':' );
+            buf.append( bundleReference.getVersionRange().toString() );
+        }
+        
+        return buf.toString();
+    }
+    
+    /**
+     * This class should not be instantiated.
+     */
+
+    private OsgiBundlesContainer() {}
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderInstallOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderInstallOperation.java
new file mode 100644
index 0000000..790c621
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderInstallOperation.java
@@ -0,0 +1,80 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.osgi;
+
+import static org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesContainer.addToClasspath;
+import static org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesContainer.isOnClasspath;
+import static org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesContainer.*;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.beginTask;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.done;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.worked;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+
+
+/**
+ * @since 1.4
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public class OsgiBundlesLibraryProviderInstallOperation
+
+    extends LibraryProviderOperation
+
+{
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+
+        throws CoreException
+
+    {
+        beginTask( monitor, "", 1 ); //$NON-NLS-1$
+
+        try
+        {
+            final OsgiBundlesLibraryProviderInstallOperationConfig cfg
+                = (OsgiBundlesLibraryProviderInstallOperationConfig) config;
+            
+            IProject project = cfg.getFacetedProject().getProject();
+            
+            if( project == null ) // TODO: Galileo - Remove this workaround.
+            {
+                final String name = ( (IFacetedProjectWorkingCopy) config.getFacetedProject() ).getProjectName();
+                project = ResourcesPlugin.getWorkspace().getRoot().getProject( name );
+            }
+            
+            final IProjectFacet facet = cfg.getProjectFacet();
+            
+            setBundleReferences( project, facet, cfg.getBundleReferences() );
+            setContainerLabel( project, facet, cfg.getContainerLabel() );
+            
+            if( ! isOnClasspath( project, facet ) )
+            {
+                addToClasspath( project, facet, cfg.getClasspathAttributes() );
+            }
+
+        	worked( monitor, 1 );
+        }
+        finally
+        {
+            done( monitor );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderInstallOperationConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderInstallOperationConfig.java
new file mode 100644
index 0000000..b1774ee
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderInstallOperationConfig.java
@@ -0,0 +1,140 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.osgi;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin;
+import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+
+/**
+ * @since 1.4
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public class OsgiBundlesLibraryProviderInstallOperationConfig
+
+	extends LibraryProviderOperationConfig
+    
+{
+    private static final String PARAM_CONTAINER_LABEL = "container.label"; //$NON-NLS-1$
+    private static final String PARAM_BUNDLE = "bundle."; //$NON-NLS-1$
+    
+    private String containerLabelOverride;
+    private List<BundleReference> bundleReferences;
+    private List<BundleReference> bundleReferencesReadOnly;
+
+    public OsgiBundlesLibraryProviderInstallOperationConfig()
+    {
+        this.containerLabelOverride = null;
+        this.bundleReferences = new ArrayList<BundleReference>();
+        this.bundleReferencesReadOnly = Collections.unmodifiableList( this.bundleReferences );
+    }
+    
+    @Override
+    public synchronized void init( final IFacetedProjectBase fproj,
+                                   final IProjectFacetVersion fv,
+                                   final ILibraryProvider provider )
+    {
+        super.init( fproj, fv, provider );
+        
+        this.containerLabelOverride = provider.getParams().get( PARAM_CONTAINER_LABEL );
+        this.bundleReferences.addAll( getBundleReferences( provider ) );
+    }
+    
+    public List<BundleReference> getBundleReferences()
+    {
+        return this.bundleReferencesReadOnly;
+    }
+    
+    public static List<BundleReference> getBundleReferences( final ILibraryProvider provider )
+    {
+        final List<BundleReference> bundleReferences = new ArrayList<BundleReference>();
+        final Map<String,String> params = provider.getParams();
+        String unparsedBundleReference;
+        
+        for( int i = 0; ( unparsedBundleReference = params.get( PARAM_BUNDLE + String.valueOf( i ) ) ) != null; i++ )
+        {
+            bundleReferences.add( OsgiBundlesContainer.parseBundleReference( unparsedBundleReference ) );
+        }
+        
+        return bundleReferences;
+    }
+    
+    public IClasspathAttribute[] getClasspathAttributes()
+    {
+        return null;
+    }
+    
+    public String getContainerLabel()
+    {
+        return this.containerLabelOverride;
+    }
+
+    @Override
+    public IStatus validate()
+    {
+        IStatus status = super.validate();
+        
+        for( BundleReference bundleReference : this.bundleReferences )
+        {
+            if( ! bundleReference.isResolvable() )
+            {
+                final String msg;
+                final String bundleId = bundleReference.getBundleId();
+                final VersionRange versionRange = bundleReference.getVersionRange();
+                
+                if( versionRange == null )
+                {
+                    msg = NLS.bind( Resources.bunldeCannotBeResolvedNoVersion, bundleId ); 
+                }
+                else
+                {
+                    msg = NLS.bind( Resources.bundleCannotBeResolved, bundleId, versionRange.toString() );
+                }
+                
+                status = new Status( IStatus.ERROR, FacetedProjectFrameworkJavaPlugin.PLUGIN_ID, msg );
+                
+                break;
+            }
+        }
+        
+        return status;
+    }
+    
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String bundleCannotBeResolved;
+        public static String bunldeCannotBeResolvedNoVersion;
+        
+        static
+        {
+            initializeMessages( OsgiBundlesLibraryProviderInstallOperationConfig.class.getName(), 
+                                Resources.class );
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderInstallOperationConfig.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderInstallOperationConfig.properties
new file mode 100644
index 0000000..116d69b
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderInstallOperationConfig.properties
@@ -0,0 +1,2 @@
+bundleCannotBeResolved = Bundle {0} with version {1} cannot be found.
+bunldeCannotBeResolvedNoVersion = Bundle {0} cannot be found.
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderUninstallOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderUninstallOperation.java
new file mode 100644
index 0000000..eeab0f5
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/OsgiBundlesLibraryProviderUninstallOperation.java
@@ -0,0 +1,63 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.osgi;
+
+import static org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesContainer.removeFromClasspath;
+import static org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesContainer.setBundleReferences;
+import static org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesContainer.setContainerLabel;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.beginTask;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.done;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.worked;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+
+/**
+ * @since 1.4
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public class OsgiBundlesLibraryProviderUninstallOperation
+
+    extends LibraryProviderOperation
+
+{
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+
+        throws CoreException
+
+    {
+        beginTask( monitor, "", 1 ); //$NON-NLS-1$
+
+        try
+        {
+            final IProject project = config.getFacetedProject().getProject();
+            final IProjectFacet facet = config.getProjectFacet();
+            
+            removeFromClasspath( project, facet );
+            setBundleReferences( project, facet, null );
+            setContainerLabel( project, facet, null );
+
+            worked( monitor, 1 );
+        }
+        finally
+        {
+            done( monitor );
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/internal/OsgiBundlesContainerImpl.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/internal/OsgiBundlesContainerImpl.java
new file mode 100644
index 0000000..da17843
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/internal/OsgiBundlesContainerImpl.java
@@ -0,0 +1,173 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.osgi.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.ClasspathContainerInitializer;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jst.common.project.facet.core.libprov.osgi.BundleReference;
+import org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesContainer;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+import org.osgi.framework.Bundle;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class OsgiBundlesContainerImpl
+
+    implements IClasspathContainer
+    
+{
+    private final IPath containerPath;
+    private final IProjectFacet facet;
+    private final IClasspathEntry[] entries;
+    private final String description;
+    
+    private OsgiBundlesContainerImpl( final IJavaProject project,
+                                      final IPath containerPath )
+    {
+        this.containerPath = containerPath;
+        final String fid = containerPath.segment( 1 );
+        
+        if( ! ProjectFacetsManager.isProjectFacetDefined( fid ) )
+        {
+            this.facet = null;
+            this.description = NLS.bind( Resources.containerLabel, fid );
+            this.entries = new IClasspathEntry[ 0 ];
+            
+            return;
+        }
+        
+        this.facet = ProjectFacetsManager.getProjectFacet( fid );
+        
+        final IProject pj = project.getProject();
+        
+        String desc = OsgiBundlesContainer.getContainerLabel( pj, this.facet );
+        
+        if( desc == null )
+        {
+            desc = NLS.bind( Resources.containerLabel, this.facet.getLabel() );
+        }
+        
+        this.description = desc;
+
+        final List<BundleReference> bundleReferences 
+            = OsgiBundlesContainer.getBundleReferences( pj, this.facet );
+        
+        final List<IClasspathEntry> entriesList = new ArrayList<IClasspathEntry>();
+        
+        for( BundleReference bundleReference : bundleReferences )
+        {
+            final Bundle bundle = bundleReference.getBundle();
+            
+            if( bundle != null )
+            {
+                File file = null;
+                
+                try
+                {
+                    file = FileLocator.getBundleFile( bundle );
+                }
+                catch( IOException e ) {}
+                
+                if( file != null )
+                {
+                    entriesList.add( JavaCore.newLibraryEntry( new Path( file.getPath() ), null, null ) );
+                }
+            }
+        }
+        
+        this.entries = entriesList.toArray( new IClasspathEntry[ entriesList.size() ] );
+    }
+    
+    public IClasspathEntry[] getClasspathEntries()
+    {
+        return this.entries;
+    }
+
+    public String getDescription()
+    {
+        return this.description;
+    }
+
+    public int getKind()
+    {
+    	return K_APPLICATION;
+    }
+
+    public IPath getPath()
+    {
+        return this.containerPath;
+    }
+    
+    public boolean equals( final Object obj )
+    {
+        if( ! ( obj instanceof OsgiBundlesContainerImpl ) )
+        {
+            return false;
+        }
+        else
+        {
+            return this.entries.equals( ( (OsgiBundlesContainerImpl) obj ).entries );
+        }
+    }
+    
+    public static final class Initializer
+    
+        extends ClasspathContainerInitializer
+        
+    {
+        @Override
+        public void initialize( final IPath containerPath,
+                                final IJavaProject project )
+        
+            throws CoreException
+            
+        {
+            final OsgiBundlesContainerImpl container 
+                = new OsgiBundlesContainerImpl( project, containerPath );
+            
+            JavaCore.setClasspathContainer( containerPath, new IJavaProject[] { project },
+                                            new IClasspathContainer[] { container }, null );
+        }
+    }
+    
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String containerLabel;
+        
+        static
+        {
+            initializeMessages( OsgiBundlesContainerImpl.class.getName(), 
+                                Resources.class );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/internal/OsgiBundlesContainerImpl.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/internal/OsgiBundlesContainerImpl.properties
new file mode 100644
index 0000000..cc6a4cf
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/internal/OsgiBundlesContainerImpl.properties
@@ -0,0 +1 @@
+containerLabel = OSGi Bundles ({0})
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/internal/OsgiBundlesLibraryProviderResolvablePropertyTester.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/internal/OsgiBundlesLibraryProviderResolvablePropertyTester.java
new file mode 100644
index 0000000..9bafbe8
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/osgi/internal/OsgiBundlesLibraryProviderResolvablePropertyTester.java
@@ -0,0 +1,70 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.osgi.internal;
+
+import static org.eclipse.jst.common.project.facet.core.libprov.osgi.OsgiBundlesLibraryProviderInstallOperationConfig.getBundleReferences;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.jst.common.project.facet.core.libprov.EnablementExpressionContext;
+import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.osgi.BundleReference;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class OsgiBundlesLibraryProviderResolvablePropertyTester
+
+    extends PropertyTester
+    
+{
+    public boolean test( final Object receiver, 
+                         final String property, 
+                         final Object[] args, 
+                         final Object value )
+    {
+        if( receiver instanceof EnablementExpressionContext )
+        {
+            final EnablementExpressionContext context = (EnablementExpressionContext) receiver;
+            return test( context.getLibraryProvider(), value );
+        }
+        else if( receiver instanceof ILibraryProvider )
+        {
+            return test( (ILibraryProvider) receiver, value );
+        }
+            
+        return false;
+    }
+    
+    private boolean test( final ILibraryProvider provider,
+                          final Object value )
+    {
+        boolean isResolvable = true;
+        
+        for( BundleReference bundleReference : getBundleReferences( provider ) )
+        {
+            if( ! bundleReference.isResolvable() )
+            {
+                isResolvable = false;
+                break;
+            }
+        }
+        
+        if( value instanceof Boolean )
+        {
+            return value.equals( isResolvable );
+        }
+        
+        return false;
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/KeyClassesValidator.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/KeyClassesValidator.java
new file mode 100644
index 0000000..9ee5b14
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/KeyClassesValidator.java
@@ -0,0 +1,175 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.user;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.PLUGIN_ID;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * An implementation of {@link UserLibraryValidator} that checks for presence of key classes in
+ * the selected libraries. Validation fails if one or more of the key classes are not found. This
+ * validator can be used as is or subclassed.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public class KeyClassesValidator
+
+    extends UserLibraryValidator
+    
+{
+    private final Set<String> classFileNames = new HashSet<String>();
+    private final Map<String,String> classFileNameToClassName = new HashMap<String,String>();
+
+    @Override
+    public void init( final List<String> params )
+    {
+        for( String className : params )
+        {
+            final StringBuilder buf = new StringBuilder();
+            
+            for( int i = 0, n = className.length(); i < n; i++ )
+            {
+                final char ch = className.charAt( i );
+                
+                if( ch == '.' )
+                {
+                    buf.append( '/' );
+                }
+                else
+                {
+                    buf.append( ch );
+                }
+            }
+            
+            buf.append( ".class" ); //$NON-NLS-1$
+            
+            final String classFileName = buf.toString();
+            this.classFileNames.add( classFileName );
+            this.classFileNameToClassName.put( classFileName, className );
+        }
+    }
+
+    @Override
+    public IStatus validate( final UserLibraryProviderInstallOperationConfig config )
+    {
+        final Map<String,Integer> classAppearanceCounts = new HashMap<String,Integer>();
+        
+        for( String classFileName : this.classFileNames )
+        {
+            classAppearanceCounts.put( classFileName, 0 );
+        }
+        
+        for( IClasspathEntry cpe : config.resolve() )
+        {
+            if( cpe.getEntryKind() == IClasspathEntry.CPE_LIBRARY )
+            {
+                final File file = cpe.getPath().toFile();
+                
+                if( file.exists() )
+                {
+                    ZipFile zip = null;
+                    
+                    try
+                    {
+                        zip = new ZipFile( file );
+                        
+                        for( Enumeration<? extends ZipEntry> itr = zip.entries(); itr.hasMoreElements(); )
+                        {
+                            final ZipEntry zipEntry = itr.nextElement();
+                            final String name = zipEntry.getName();
+                            
+                            Integer count = classAppearanceCounts.get( name );
+                            
+                            if( count != null )
+                            {
+                                classAppearanceCounts.put( name, count + 1 );
+                            }
+                        }
+                    }
+                    catch( IOException e )
+                    {
+                        
+                    }
+                    finally
+                    {
+                        if( zip != null )
+                        {
+                            try
+                            {
+                                zip.close();
+                            }
+                            catch( IOException e ) {}
+                        }
+                    }
+                }
+            }
+        }
+        
+        for( Map.Entry<String,Integer> entry : classAppearanceCounts.entrySet() )
+        {
+            final int count = entry.getValue();
+            
+            if( count != 1 )
+            {
+                final String classFileName = entry.getKey();
+                final String className = this.classFileNameToClassName.get( classFileName );
+                final String message;
+                
+                if( count == 0 )
+                {
+                    message = Resources.bind( Resources.classNotFound, className );
+                }
+                else
+                {
+                    message = Resources.bind( Resources.classPresentMultipleTimes, className );
+                }
+                
+                return new Status( IStatus.ERROR, PLUGIN_ID, message );
+            }
+        }
+        
+        return Status.OK_STATUS;
+    }
+    
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String classNotFound;
+        public static String classPresentMultipleTimes;
+        
+        static
+        {
+            initializeMessages( KeyClassesValidator.class.getName(), 
+                                Resources.class );
+        }
+    }
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/KeyClassesValidator.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/KeyClassesValidator.properties
new file mode 100644
index 0000000..492def7
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/KeyClassesValidator.properties
@@ -0,0 +1,2 @@
+classNotFound = Required class {0} does not exist in selected libraries.
+classPresentMultipleTimes = Found multiple versions of the required class {0}. 
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderInstallOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderInstallOperation.java
new file mode 100644
index 0000000..5cedc7f
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderInstallOperation.java
@@ -0,0 +1,131 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.user;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+import static org.eclipse.jst.common.project.facet.core.libprov.user.UserLibraryProviderInstallOperationConfig.PREFS_LAST_USED_LIBRARIES;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.beginTask;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.done;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.worked;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jst.common.project.facet.core.internal.ClasspathUtil;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * The install operation corresponding to the user-library-provider that uses JDT user library facility
+ * for managing libraries. This class can be subclassed by those wishing to extend the base implementation
+ * supplied by the framework.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public class UserLibraryProviderInstallOperation
+
+    extends LibraryProviderOperation
+    
+{
+    /**
+     * Runs the library provider operation. Subclasses can override.
+     * 
+     * @param config the library provider operation config; will never be null
+     * @param monitor the progress monitor for status reporting and cancellation
+     * @throws CoreException if failed while executing the operation
+     */
+    
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        beginTask( monitor, "", 2 ); //$NON-NLS-1$
+        
+        try
+        {
+            final UserLibraryProviderInstallOperationConfig cfg
+                = (UserLibraryProviderInstallOperationConfig) config;
+            
+            final List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
+            
+            for( String libraryName : cfg.getLibraryNames() )
+            {
+                entries.add( createClasspathEntry( cfg, libraryName ) );
+            }
+            
+            final IProject project = config.getFacetedProject().getProject();
+            ClasspathUtil.addClasspathEntries( project, config.getProjectFacet(), entries );
+            
+            worked( monitor, 1 );
+            
+            try
+            {
+                Preferences prefs = FacetedProjectFramework.getPreferences( cfg.getProjectFacet() );
+                
+                prefs = prefs.node( PREFS_LAST_USED_LIBRARIES );
+                prefs = prefs.node( cfg.getProjectFacetVersion().getVersionString() );
+                
+                for( String libraryName : prefs.childrenNames() )
+                {
+                    prefs.node( libraryName ).removeNode();
+                }
+                
+                for( String libraryName : cfg.getLibraryNames() )
+                {
+                    prefs.node( libraryName );
+                }
+
+                prefs.flush();
+            }
+            catch( BackingStoreException e )
+            {
+                log( e );
+            }
+            
+            worked( monitor, 2 );
+        }
+        finally
+        {
+            done( monitor );
+        }
+    }
+    
+    /**
+     * Constructs a classpath entry for the provided user library. Subclasses can override.
+     * 
+     * @param config the user library provider install operation config
+     * @param libraryName the name of a JDT user library
+     * @return the classpath entry for the provided user library
+     */
+    
+    protected IClasspathEntry createClasspathEntry( final UserLibraryProviderInstallOperationConfig config,
+                                                    final String libraryName )
+    {
+        final IPath containerPath = new Path( JavaCore.USER_LIBRARY_CONTAINER_ID ).append( libraryName );
+        return JavaCore.newContainerEntry( containerPath );
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderInstallOperationConfig.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderInstallOperationConfig.java
new file mode 100644
index 0000000..a772390
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderInstallOperationConfig.java
@@ -0,0 +1,359 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.user;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.createErrorStatus;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.instantiate;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.UserLibrary;
+import org.eclipse.jdt.internal.core.UserLibraryManager;
+import org.eclipse.jst.common.project.facet.core.internal.ClasspathUtil;
+import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderFramework;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderInstallOperationConfig;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacet;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * The install operation config corresponding to the user-library-provider that uses JDT user library facility
+ * for managing libraries. This class can be subclassed by those wishing to extend the base implementation
+ * supplied by the framework.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+@SuppressWarnings( "restriction" )
+
+public class UserLibraryProviderInstallOperationConfig
+
+    extends LibraryProviderInstallOperationConfig
+    
+{
+    private static final String CLASS_NAME 
+        = UserLibraryProviderInstallOperationConfig.class.getName();
+    
+    /**
+     * The preferences path (in the workspace-level facet preferences) where information about
+     * user libraries that were last used for a particular facet are stored. Beneath this path,
+     * content is organized by facet version.
+     */
+    
+    public static final String PREFS_LAST_USED_LIBRARIES
+        = "user.library.provider/last.used.libraries"; //$NON-NLS-1$
+
+    /**
+     * The property corresponding to the list of selected user libraries.
+     */
+    
+    public static final String PROP_LIBRARY_NAMES 
+        = CLASS_NAME + ".LIBRARY_NAMES"; //$NON-NLS-1$
+    
+    private static final String PARAM_VALIDATOR = "validator"; //$NON-NLS-1$
+    private static final String PARAM_VALIDATOR_PARAM = "validator.param"; //$NON-NLS-1$
+
+    private List<String> libraryNames;
+    private List<String> libraryNamesReadOnly;
+    private UserLibraryValidator validator;
+    
+    /**
+     * Constructs the user library provider install operation config.
+     */
+    
+    public UserLibraryProviderInstallOperationConfig()
+    {
+        this.libraryNames = Collections.emptyList();
+        this.libraryNamesReadOnly = Collections.emptyList();
+        this.validator = null;
+    }
+
+    /**
+     * Initializes the operation config. This method is called soon after the provider
+     * is instantiated. Extenders can override in order to add to the initialization, but
+     * have make sure to forward the init call up the inheritance chain.
+     * 
+     * @param fpj the faceted project (or a working copy)
+     * @param fv the project facet that is making the request for libraries
+     * @param provider the library provider (useful if the same operation config class
+     *   is re-used between multiple providers)
+     */
+    
+    @Override
+    public synchronized void init( final IFacetedProjectBase fproj,
+                                   final IProjectFacetVersion fv,
+                                   final ILibraryProvider provider )
+    {
+        super.init( fproj, fv, provider );
+        
+        final Map<String,String> params = provider.getParams();
+        final String validatorClassName = params.get( PARAM_VALIDATOR );
+        
+        if( validatorClassName != null )
+        {
+            this.validator = instantiate( provider.getPluginId(), validatorClassName, UserLibraryValidator.class );
+            
+            if( this.validator != null )
+            {
+                final List<String> keyClassNames = new ArrayList<String>();
+                
+                int i = 0; 
+                String paramName = PARAM_VALIDATOR_PARAM + "." + String.valueOf( i ); //$NON-NLS-1$
+                String paramValue = params.get( paramName );
+                
+                while( paramValue != null )
+                {
+                    keyClassNames.add( paramValue );
+    
+                    i++; 
+                    paramName = PARAM_VALIDATOR_PARAM + "." + String.valueOf( i ); //$NON-NLS-1$
+                    paramValue = params.get( paramName );
+                }
+                
+                try
+                {
+                    this.validator.init( keyClassNames );
+                }
+                catch( Exception e )
+                {
+                    log( e );
+                    this.validator = null;
+                }
+            }
+        }
+        
+        reset();
+    }
+    
+    /**
+     * Returns the list of user libraries that are currently selected. To listen for changes
+     * to this list use PROP_LIBRARY_NAMES.
+     * 
+     * @return the list of user libraries that are currently selected
+     */
+
+    public synchronized final List<String> getLibraryNames()
+    {
+        return this.libraryNamesReadOnly;
+    }
+    
+    /**
+     * Sets the list of user libraries. 
+     * 
+     * @param libraryNames the list of user library names
+     */
+    
+    public synchronized final void setLibraryNames( final List<String> libraryNames )
+    {
+        final List<String> oldLibraryNames = this.libraryNamesReadOnly;
+        this.libraryNames = new ArrayList<String>( libraryNames );
+        this.libraryNamesReadOnly = Collections.unmodifiableList( this.libraryNames );
+        notifyListeners( PROP_LIBRARY_NAMES, oldLibraryNames, this.libraryNamesReadOnly );
+    }
+    
+    /**
+     * Adds a library to the list of selected user libraries.
+     * 
+     * @param libraryName the name of the library
+     */
+    
+    public synchronized final void addLibraryName( final String libraryName )
+    {
+        if( ! this.libraryNamesReadOnly.contains( libraryName ) )
+        {
+            final List<String> oldLibraryNames = this.libraryNamesReadOnly;
+            this.libraryNames = new ArrayList<String>( oldLibraryNames );
+            this.libraryNamesReadOnly = Collections.unmodifiableList( this.libraryNames );
+            this.libraryNames.add( libraryName );
+            notifyListeners( PROP_LIBRARY_NAMES, oldLibraryNames, this.libraryNamesReadOnly );
+        }
+    }
+    
+    /**
+     * Resolve the referenced user libraries into a collection of classpath entries that reference
+     * physical libraries. 
+     * 
+     * @return the classpath entries contributed by the referenced user libraries
+     */
+    
+    public synchronized Collection<IClasspathEntry> resolve()
+    {
+        final List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
+        final UserLibraryManager userLibraryManager = JavaModelManager.getUserLibraryManager();
+        
+        for( String libraryName : this.libraryNames )
+        {
+            final UserLibrary userLibrary = userLibraryManager.getUserLibrary( libraryName );
+            
+            if( userLibrary != null )
+            {
+                for( IClasspathEntry cpe : userLibrary.getEntries() )
+                {
+                    entries.add( cpe );
+                }
+            }
+        }
+        
+        return Collections.unmodifiableCollection( entries );
+    }
+    
+    /**
+     * Validates the state of this operation config object and returns a status object
+     * describing any problems. If no problems are detected, this should return OK
+     * status.
+     * 
+     * @return the result of validating this operation config
+     */
+    
+    @Override
+    public synchronized IStatus validate()
+    {
+        IStatus st = Status.OK_STATUS;
+        
+        if( this.libraryNames.size() == 0 )
+        {
+            st = createErrorStatus( Resources.libraryNeedsToBeSelected );
+        }
+        else
+        {
+            if( this.validator != null )
+            {
+                try
+                {
+                    st = this.validator.validate( this );
+                }
+                catch( Exception e )
+                {
+                    log( e );
+                    this.validator = null;
+                }
+            }
+        }
+        
+        return st;
+    }
+    
+    /**
+     * Resets this operation config to its initial state (prior to any user changes).
+     */
+
+    @Override
+    public synchronized void reset()
+    {
+        final IProject project = getFacetedProject().getProject();
+        final IProjectFacet f = getProjectFacet();
+        final IProjectFacetVersion fv = getProjectFacetVersion();
+        
+        List<String> newLibraryNames = null;
+
+        if( project != null )
+        {
+            final ILibraryProvider currentProvider 
+                = LibraryProviderFramework.getCurrentProvider( project, f );
+            
+            if( currentProvider == getLibraryProvider() )
+            {
+                final List<IClasspathEntry> entries;
+                
+                try
+                {
+                    entries = ClasspathUtil.getClasspathEntries( project, f );
+                }
+                catch( CoreException e )
+                {
+                    throw new RuntimeException( e );
+                }
+                
+                final List<String> libraryNamesList = new ArrayList<String>();
+
+                for( IClasspathEntry cpe : entries )
+                {
+                    if( cpe.getEntryKind() == IClasspathEntry.CPE_CONTAINER )
+                    {
+                        final IPath path = cpe.getPath();
+                        
+                        if( path.segmentCount() >= 2 && path.segment( 0 ).equals( JavaCore.USER_LIBRARY_CONTAINER_ID ) )
+                        {
+                            libraryNamesList.add( path.segment( 1 ) );
+                        }
+                    }
+                }
+                
+                newLibraryNames = libraryNamesList;
+            }
+        }
+        
+        if( newLibraryNames == null )
+        {
+            newLibraryNames = new ArrayList<String>();
+            
+            try
+            {
+                Preferences prefs = FacetedProjectFramework.getPreferences( f );
+                
+                if( prefs.nodeExists( PREFS_LAST_USED_LIBRARIES ) )
+                {
+                    prefs = prefs.node( PREFS_LAST_USED_LIBRARIES );
+                    
+                    if( prefs.nodeExists( fv.getVersionString() ) )
+                    {
+                        prefs = prefs.node( fv.getVersionString() );
+                        
+                        for( String libraryName : prefs.childrenNames() )
+                        {
+                            newLibraryNames.add( libraryName );
+                        }
+                    }
+                }
+            }
+            catch( BackingStoreException e )
+            {
+                log( e );
+            }
+        }
+        
+        setLibraryNames( newLibraryNames );
+    }
+
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String libraryNeedsToBeSelected;
+
+        static
+        {
+            initializeMessages( UserLibraryProviderInstallOperationConfig.class.getName(), 
+                                Resources.class );
+        }
+    }
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderInstallOperationConfig.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderInstallOperationConfig.properties
new file mode 100644
index 0000000..5d34536
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderInstallOperationConfig.properties
@@ -0,0 +1 @@
+libraryNeedsToBeSelected = At least one user library must be selected.
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderUninstallOperation.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderUninstallOperation.java
new file mode 100644
index 0000000..70316c6
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryProviderUninstallOperation.java
@@ -0,0 +1,68 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.user;
+
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.beginTask;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.done;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ProgressMonitorUtil.worked;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jst.common.project.facet.core.internal.ClasspathUtil;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperation;
+import org.eclipse.jst.common.project.facet.core.libprov.LibraryProviderOperationConfig;
+
+/**
+ * The uninstall operation corresponding to the user-library-provider that uses JDT user library facility
+ * for managing libraries. This class can be subclassed by those wishing to extend the base implementation
+ * supplied by the framework.
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public class UserLibraryProviderUninstallOperation
+
+    extends LibraryProviderOperation
+    
+{
+    /**
+     * Runs the library provider operation. Subclasses can override.
+     * 
+     * @param config the library provider operation config; will never be null
+     * @param monitor the progress monitor for status reporting and cancellation
+     * @throws CoreException if failed while executing the operation
+     */
+    
+    public void execute( final LibraryProviderOperationConfig config,
+                         final IProgressMonitor monitor )
+    
+        throws CoreException
+        
+    {
+        beginTask( monitor, "", 1 ); //$NON-NLS-1$
+        
+        try
+        {
+            final IProject project = config.getFacetedProject().getProject();
+            ClasspathUtil.removeClasspathEntries( project, config.getProjectFacet() );
+            
+            worked( monitor, 1 );
+        }
+        finally
+        {
+            done( monitor );
+        }
+    }
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryValidator.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryValidator.java
new file mode 100644
index 0000000..f60161c
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/UserLibraryValidator.java
@@ -0,0 +1,63 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.user;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * <p>Used to provide custom validation for user library providers. To associate a validator 
+ * with a user library provider declaration, use syntax like the following. Only one validator
+ * can be registered per provider, but any number of validator parameters can be specified using 
+ * naming convention starting with 0.</p>
+ *
+ * <pre>&lt;extension point="org.eclipse.jst.common.project.facet.core.libraryProviders">
+ *   &lt;provider id="..." extends="user-library-provider">
+ *     ...
+ *     &lt;param name="validator" value="org.eclipse.jst.common.project.facet.core.libprov.user.KeyClassesValidator"/>
+ *     &lt;param name="validator.param.0" value="javax.persistence.Entity"/>
+ *     ...
+ *   &lt;/provider>
+ * &lt;/extension></pre>
+ * 
+ * @see KeyClassesValidator
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ * @since 1.4
+ */
+
+public abstract class UserLibraryValidator
+{
+    /**
+     * Called by the framework to initialize the validator. The list of parameters is computed
+     * based on values of library provider parameters with names that follow "validator.param.x"
+     * convention, where 'x' is a number starting with 0.
+     * 
+     * <p>The default implementation does not do anything.</p>
+     * 
+     * @param params the validator parameters
+     */
+    
+    public void init( final List<String> params )
+    {
+    }
+
+    /**
+     * Called by the framework to validate the user library provider install operation config.
+     * 
+     * @param config the user library provider install operation config
+     * @return result of validation
+     */
+    
+    public abstract IStatus validate( final UserLibraryProviderInstallOperationConfig config );
+
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/internal/DownloadableLibrariesExtensionPoint.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/internal/DownloadableLibrariesExtensionPoint.java
new file mode 100644
index 0000000..b649c65
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/internal/DownloadableLibrariesExtensionPoint.java
@@ -0,0 +1,346 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.user.internal;
+
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.PLUGIN_ID;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.createErrorStatus;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.log;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.logError;
+import static org.eclipse.wst.common.project.facet.core.util.internal.DomUtil.doc;
+import static org.eclipse.wst.common.project.facet.core.util.internal.DomUtil.elements;
+import static org.eclipse.wst.common.project.facet.core.util.internal.DomUtil.text;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findExtensions;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findOptionalElement;
+import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.getTopLevelElements;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jst.common.project.facet.core.libprov.EnablementExpressionContext;
+import org.eclipse.jst.common.project.facet.core.libprov.ILibraryProvider;
+import org.eclipse.jst.common.project.facet.core.libprov.user.UserLibraryProviderInstallOperationConfig;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IFacetedProjectBase;
+import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
+import org.eclipse.wst.common.project.facet.core.util.internal.XmlParseException;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Contains the logic for processing the <code>downloadableLibraries</code> extension point. 
+ * 
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+public final class DownloadableLibrariesExtensionPoint
+{
+    public static final String EXTENSION_POINT_ID = "downloadableLibraries"; //$NON-NLS-1$
+    
+    private static final String ATTR_PATH = "path"; //$NON-NLS-1$
+    private static final String ATTR_URL = "url"; //$NON-NLS-1$
+    private static final String EL_IMPORT_DEFINITIONS = "import-definitions"; //$NON-NLS-1$
+    private static final String EL_ENABLEMENT = "enablement"; //$NON-NLS-1$
+    
+    private static final String EL_LIBRARY = "library"; //$NON-NLS-1$
+    private static final String EL_NAME = "name"; //$NON-NLS-1$
+    private static final String EL_DOWNLOAD_PROVIDER = "download-provider"; //$NON-NLS-1$
+    private static final String EL_DOWNLOAD_URL = "download-url"; //$NON-NLS-1$
+    private static final String EL_LICENSE_URL = "license-url"; //$NON-NLS-1$
+    private static final String EL_INCLUDE = "include"; //$NON-NLS-1$
+    private static final String EL_EXCLUDE = "exclude"; //$NON-NLS-1$
+    private static final String EL_ATTRIBUTES = "attributes"; //$NON-NLS-1$
+    private static final String EL_COMPONENT = "component"; //$NON-NLS-1$
+    private static final String EL_SOURCE = "source"; //$NON-NLS-1$
+    private static final String EL_JAVADOC = "javadoc"; //$NON-NLS-1$
+
+    private static final String EXPR_VAR_CONTEXT = "context"; //$NON-NLS-1$
+    private static final String EXPR_VAR_REQUESTING_PROJECT_FACET = "requestingProjectFacet"; //$NON-NLS-1$
+    private static final String EXPR_VAR_PROJECT_FACETS = "projectFacets"; //$NON-NLS-1$
+    private static final String EXPR_VAR_TARGETED_RUNTIMES = "targetedRuntimes"; //$NON-NLS-1$
+    private static final String EXPR_VAR_PROVIDER = "provider"; //$NON-NLS-1$
+
+    public static List<DownloadableLibrary> list( final UserLibraryProviderInstallOperationConfig cfg,
+                                                  final IProgressMonitor monitor )
+    {
+        final IProgressMonitor mon = ( monitor != null ? monitor : new NullProgressMonitor() );
+        
+        mon.beginTask( Resources.searchingForLibrariesTaskName, IProgressMonitor.UNKNOWN );
+        
+        try
+        {
+            final List<DownloadableLibrary> libraries = new ArrayList<DownloadableLibrary>();
+            
+            for( IConfigurationElement element 
+                 : getTopLevelElements( findExtensions( PLUGIN_ID, EXTENSION_POINT_ID ) ) )
+            {
+                if( mon.isCanceled() )
+                {
+                    return null;
+                }
+                
+                final String pluginId = element.getContributor().getName();
+                
+                if( element.getName().equals( EL_IMPORT_DEFINITIONS ) )
+                {
+                    final IConfigurationElement elEnablement = findOptionalElement( element, EL_ENABLEMENT );
+                    
+                    if( elEnablement != null )
+                    {
+                        try
+                        {
+                            final Expression expr 
+                                = ExpressionConverter.getDefault().perform( elEnablement );
+                            
+                            final EvaluationContext context
+                                = createEvaluationContext( cfg.getFacetedProject(), cfg.getProjectFacetVersion(), 
+                                                           cfg.getLibraryProvider() );
+                            
+                            if( expr.evaluate( context ) != EvaluationResult.TRUE )
+                            {
+                                continue;
+                            }
+                        }
+                        catch( CoreException e )
+                        {
+                            log( e );
+                            break;
+                        }
+                    }
+                    
+                    URL url = null;
+                    
+                    final String pathAttr = element.getAttribute( ATTR_PATH );
+                    final String urlAttr = element.getAttribute( ATTR_URL );
+                    
+                    if( pathAttr != null )
+                    {
+                        final Bundle plugin = Platform.getBundle( pluginId );
+                        url = FileLocator.find( plugin, new Path( pathAttr ), null );
+                        
+                        if( url == null )
+                        {
+                            final String msg = NLS.bind( Resources.errorPluginResourceNotFound, pluginId, pathAttr );
+                            logError( msg );
+                            continue;
+                        }
+                    }
+                    else if( urlAttr != null )
+                    {
+                        try
+                        {
+                            url = new URL( urlAttr );
+                        }
+                        catch( MalformedURLException e )
+                        {
+                            final String msg = NLS.bind( Resources.errorMalformedUrl, pluginId, urlAttr );
+                            log( createErrorStatus( msg, e ) );
+                            continue;
+                        }
+                    }
+                    else
+                    {
+                        final String msg = NLS.bind( Resources.errorMissingPathOrUrl, pluginId );
+                        logError( msg );
+                        continue;
+                    }
+                    
+                    readLibraryDefinitions( url, libraries );
+                }
+            }
+            
+            return libraries;
+        }
+        finally
+        {
+            mon.done();
+        }
+    }
+    
+    private static EvaluationContext createEvaluationContext( final IFacetedProjectBase fproj,
+                                                              final IProjectFacetVersion fv,
+                                                              final ILibraryProvider provider )
+    {
+        final EvaluationContext evalContext = new EvaluationContext( null, fv );
+        final EnablementExpressionContext context = new EnablementExpressionContext( fproj, fv, provider );
+        evalContext.addVariable( EXPR_VAR_CONTEXT, context );
+        evalContext.addVariable( EXPR_VAR_REQUESTING_PROJECT_FACET, fv );
+        evalContext.addVariable( EXPR_VAR_PROJECT_FACETS, fproj.getProjectFacets() );
+        evalContext.addVariable( EXPR_VAR_TARGETED_RUNTIMES, fproj.getTargetedRuntimes() );
+        evalContext.addVariable( EXPR_VAR_PROVIDER, provider );        
+        evalContext.setAllowPluginActivation( true );
+    
+        return evalContext;
+    }
+    
+    private static void readLibraryDefinitions( final URL url,
+                                                final List<DownloadableLibrary> libraries )
+    {
+        Document document = null;
+        InputStream in = null;
+        
+        try
+        {
+            in = url.openStream();
+        }
+        catch( IOException e )
+        {
+            final String msg = NLS.bind( Resources.errorReadingDefFile, url.toString() );
+            log( createErrorStatus( msg, e ) );
+            return;
+        }
+        
+        try
+        {
+            document = doc( in );
+        }
+        catch( XmlParseException e )
+        {
+            final String msg = NLS.bind( Resources.errorParsingDefFile, url.toString() );
+            log( createErrorStatus( msg, e ) );
+            return;
+        }
+        finally
+        {
+            try
+            {
+                in.close();
+            }
+            catch( IOException e ) {}
+        }
+        
+        if( document != null )
+        {
+            final Element root = document.getDocumentElement();
+            
+            if( root != null )
+            {
+                for( Element elLibrary : elements( root, EL_LIBRARY ) )
+                {
+                    try
+                    {
+                        final DownloadableLibrary library = new DownloadableLibrary();
+                        
+                        final String name = getRequiredElementText( url, elLibrary, EL_NAME );
+                        library.setName( name );
+                        
+                        final String provider = getRequiredElementText( url, elLibrary, EL_DOWNLOAD_PROVIDER );
+                        library.setDownloadProvider( provider );
+                        
+                        final String downloadUrl = getRequiredElementText( url, elLibrary, EL_DOWNLOAD_URL );
+                        library.setUrl( downloadUrl );
+                        
+                        final String licenseUrl = text( elLibrary, EL_LICENSE_URL );
+                        library.setLicenseUrl( licenseUrl );
+                        
+                        for( Element elInclude : elements( elLibrary, EL_INCLUDE ) )
+                        {
+                            library.addIncludePattern( text( elInclude ) );
+                        }
+
+                        for( Element elExclude : elements( elLibrary, EL_EXCLUDE ) )
+                        {
+                            library.addExcludePattern( text( elExclude ) );
+                        }
+                        
+                        for( Element elAttachment : elements( elLibrary, EL_ATTRIBUTES ) )
+                        {
+                            final String jarPath = getRequiredElementText( url, elAttachment, EL_COMPONENT );
+                            
+                            final DownloadableLibraryComponentAttributes attachment 
+                                = library.getComponentAttributes( new Path( jarPath ), true );
+                            
+                            final String sourceArchivePath = text( elAttachment, EL_SOURCE );
+                            attachment.setSourceArchivePath( sourceArchivePath );
+                            
+                            final String javadocArchivePath = text( elAttachment, EL_JAVADOC );
+                            attachment.setJavadocArchivePath( javadocArchivePath );
+                        }
+                        
+                        libraries.add( library );
+                    }
+                    catch( InvalidLibraryDefinitionException e )
+                    {
+                        // Bad library definition. Problem already reported to the user in the log,
+                        // so we just need to continue gracefully.
+                        
+                        continue;
+                    }
+                }
+            }
+        }
+    }
+    
+    private static String getRequiredElementText( final URL url,
+                                                  final Element parent,
+                                                  final String childElementName )
+    
+        throws InvalidLibraryDefinitionException
+        
+    {
+        final String val = text( parent, childElementName );
+        
+        if( val == null )
+        {
+            final String msg = NLS.bind( Resources.errorDefMissingElement, childElementName, url.toString() );
+            logError( msg );
+            throw new InvalidLibraryDefinitionException();
+        }
+        
+        return val;
+    }
+    
+    private static class InvalidLibraryDefinitionException
+    
+        extends Exception
+        
+    {
+        private static final long serialVersionUID = 1L;
+    }
+    
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String searchingForLibrariesTaskName;
+        public static String errorDefMissingElement;
+        public static String errorParsingDefFile;
+        public static String errorReadingDefFile;
+        public static String errorPluginResourceNotFound;
+        public static String errorMalformedUrl;
+        public static String errorMissingPathOrUrl;
+    
+        static
+        {
+            initializeMessages( DownloadableLibrariesExtensionPoint.class.getName(), 
+                                Resources.class );
+        }
+    }
+    
+    
+}
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/internal/DownloadableLibrariesExtensionPoint.properties b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/internal/DownloadableLibrariesExtensionPoint.properties
new file mode 100644
index 0000000..a16ed31
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/internal/DownloadableLibrariesExtensionPoint.properties
@@ -0,0 +1,7 @@
+searchingForLibrariesTaskName = Searching for libraries...
+errorDefMissingElement = The <{0}> element is missing or empty in the library definition at "{1}".
+errorParsingDefFile = Failed while parsing library definition file at "{0}".
+errorReadingDefFile = Failed while reading library definition file at "{0}".
+errorPluginResourceNotFound = Could not find resource "{1}" in plugin "{0}".
+errorMalformedUrl = Malformed URL "{1}" was specified in plugin "{0}".
+errorMissingPathOrUrl = Extension of downloadableLibraries in plugin "{0}" needs to specify either "path" or "url" attribute for the <library> element.
diff --git a/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/internal/DownloadableLibrary.java b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/internal/DownloadableLibrary.java
new file mode 100644
index 0000000..7f13774
--- /dev/null
+++ b/plugins/org.eclipse.jst.common.project.facet.core/src/org/eclipse/jst/common/project/facet/core/libprov/user/internal/DownloadableLibrary.java
@@ -0,0 +1,515 @@
+/******************************************************************************
+ * Copyright (c) 2010 Oracle
+ * 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:
+ *    Konstantin Komissarchik - initial implementation and ongoing maintenance
+ ******************************************************************************/
+
+package org.eclipse.jst.common.project.facet.core.libprov.user.internal;
+
+import static org.eclipse.jdt.core.IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME;
+import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.PLUGIN_ID;
+import static org.eclipse.wst.common.project.facet.core.util.internal.ZipUtil.unzip;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Collection;
+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.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.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.UserLibraryManager;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
+ */
+
+@SuppressWarnings( "restriction" )
+
+public final class DownloadableLibrary
+{
+    private String name;
+    private String downloadProvider;
+    private String url;
+    private String licenseUrl;
+    
+    private Map<IPath,DownloadableLibraryComponentAttributes> componentAttributesMap
+        = new HashMap<IPath,DownloadableLibraryComponentAttributes>();
+    
+    private final List<String> includePatterns = new ArrayList<String>();
+    private final List<String> includePatternsReadOnly = Collections.unmodifiableList( this.includePatterns );
+    private final List<String> excludePatterns = new ArrayList<String>();
+    private final List<String> excludePatternsReadOnly = Collections.unmodifiableList( this.excludePatterns );
+    
+    public String getName()
+    {
+        return this.name;
+    }
+    
+    public void setName( final String name )
+    {
+        this.name = name;
+    }
+    
+    public String getDownloadProvider()
+    {
+        return this.downloadProvider;
+    }
+    
+    public void setDownloadProvider( final String downloadProvider )
+    {
+        this.downloadProvider = downloadProvider;
+    }
+    
+    public String getUrl()
+    {
+        return this.url;
+    }
+    
+    public void setUrl( final String url )
+    {
+        this.url = url;
+    }
+    
+    public String getLicenseUrl()
+    {
+        return this.licenseUrl;
+    }
+    
+    public void setLicenseUrl( final String licenseUrl )
+    {
+        this.licenseUrl = licenseUrl;
+    }
+    
+    public DownloadableLibraryComponentAttributes getComponentAttributes( final IPath path )
+    {
+        return getComponentAttributes( path, false );
+    }
+    
+    public DownloadableLibraryComponentAttributes getComponentAttributes( final IPath path,
+                                                                          final boolean createIfNecessary )
+    {
+        DownloadableLibraryComponentAttributes attachment = this.componentAttributesMap.get( path );
+        
+        if( attachment == null && createIfNecessary )
+        {
+            attachment = new DownloadableLibraryComponentAttributes( path.toPortableString() );
+            this.componentAttributesMap.put( path, attachment );
+        }
+        
+        return attachment;
+    }
+    
+    public Collection<String> getIncludePatterns()
+    {
+        return this.includePatternsReadOnly;
+    }
+    
+    public void addIncludePattern( final String includePattern )
+    {
+        if( includePattern == null )
+        {
+            return;
+        }
+        
+        for( String segment : includePattern.split( "," ) ) //$NON-NLS-1$
+        {
+            segment = segment.trim();
+            
+            if( segment.length() > 0 )
+            {
+                this.includePatterns.add( segment );
+            }
+        }
+    }
+        
+    public Collection<String> getExcludePatterns()
+    {
+        return this.excludePatternsReadOnly;
+    }
+    
+    public void addExcludePattern( final String excludePattern )
+    {
+        if( excludePattern == null )
+        {
+            return;
+        }
+        
+        for( String segment : excludePattern.split( "," ) ) //$NON-NLS-1$
+        {
+            segment = segment.trim();
+            
+            if( segment.length() > 0 )
+            {
+                this.excludePatterns.add( segment );
+            }
+        }
+    }
+        
+    public void download( final File destFolder,
+                          final String localLibraryName,
+                          final IProgressMonitor monitor )
+    
+        throws CoreException, InterruptedException
+        
+    {
+        try 
+        {
+            // Create the directory where the downloaded archive will be written to
+            // and where the exploded library will reside.
+            
+            destFolder.mkdirs();
+            
+            // Make sure that destination folder is empty and clear it out if necessary.
+            
+            for( File f : destFolder.listFiles() )
+            {
+                delete( f );
+            }
+
+            // Define the temporary download file.
+            
+            final File destFile = new File( destFolder, "download.zip" ); //$NON-NLS-1$
+            
+            // Perform the download.
+                
+            download( new URL( this.url ), destFile, monitor );
+            
+            // Unzip the downloaded file.
+
+            unzip( destFile, destFolder, monitor );
+            
+            // Delete the original downloaded file.
+            
+            destFile.delete();
+            
+            // Configure the user library.
+            
+            final List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
+            final IPath destFolderPath = new Path( destFolder.getPath() );
+            
+            for( File jarFile : findAllJarFiles( destFolder ) )
+            {
+                final IPath jarPath = new Path( jarFile.getPath() );
+                final IPath relativeJarPath = jarPath.makeRelativeTo( destFolderPath );
+                
+                if( ! shouldInclude( relativeJarPath ) )
+                {
+                    continue;
+                }
+                
+                IPath sourceArchivePath = null;
+                String javadocArchivePath = null;
+
+                final DownloadableLibraryComponentAttributes attachment = getComponentAttributes( relativeJarPath );
+                
+                if( attachment != null )
+                {
+                    final String sourceArchivePathString = attachment.getSourceArchivePath();
+                    
+                    if( sourceArchivePathString != null )
+                    {
+                        sourceArchivePath = destFolderPath.append( sourceArchivePathString );
+                    }
+                    
+                    javadocArchivePath = attachment.getJavadocArchivePath();
+                    
+                    if( javadocArchivePath != null )
+                    {
+                        final int separator = javadocArchivePath.indexOf( '!' );
+                        final IPath pathInArchive;
+                        
+                        if( separator == -1 )
+                        {
+                            pathInArchive = null;
+                        }
+                        else
+                        {
+                            pathInArchive = new Path( javadocArchivePath.substring( separator + 1 ) );
+                            javadocArchivePath = javadocArchivePath.substring( 0, separator );
+                        }
+                        
+                        final IPath p = destFolderPath.append( javadocArchivePath );
+                        
+                        if( pathInArchive != null || p.toFile().isFile() )
+                        {
+                            javadocArchivePath = "jar:file:/" + p.toPortableString() + "!/"; //$NON-NLS-1$ //$NON-NLS-2$
+                            
+                            if( javadocArchivePath != null )
+                            {
+                                javadocArchivePath = javadocArchivePath + pathInArchive.toPortableString() + "/"; //$NON-NLS-1$
+                            }
+                        }
+                        else
+                        {
+                            javadocArchivePath = "file:/" + p.toPortableString() + "/"; //$NON-NLS-1$ //$NON-NLS-2$
+                        }
+                    }
+                }
+                
+                final IClasspathEntry cpe = newLibraryEntry( jarPath, sourceArchivePath, javadocArchivePath );
+                entries.add( cpe );
+            }
+            
+            final IClasspathEntry[] entriesArray 
+                = entries.toArray( new IClasspathEntry[ entries.size() ] );
+            
+            final UserLibraryManager userLibraryManager = JavaModelManager.getUserLibraryManager();
+            userLibraryManager.setUserLibrary( localLibraryName, entriesArray, false );
+        }
+        catch( IOException e )
+        {
+            final IStatus st = new Status( IStatus.ERROR, PLUGIN_ID, Resources.failedWhileDownloading, e );
+            throw new CoreException( st );
+        }
+    }
+    
+    private void download( final URL url,
+                           final File destFile,
+                           final IProgressMonitor monitor )
+    
+        throws IOException, InterruptedException
+        
+    {
+        monitor.setTaskName( Resources.progressConnecting );
+        
+        final URLConnection urlConnection = url.openConnection();
+        final int size = urlConnection.getContentLength();
+        
+        final String totalSizeString;
+        
+        if( size == -1 )
+        {
+            totalSizeString = null;
+            monitor.beginTask( Resources.progressTransferStarted, IProgressMonitor.UNKNOWN );
+        }
+        else
+        {
+            totalSizeString = formatByteCount( size );
+            monitor.beginTask( Resources.progressTransferStarted, size );
+        }
+        
+        InputStream in = null;
+        FileOutputStream out = null;
+        
+        try
+        {
+            in = urlConnection.getInputStream();
+            out = new FileOutputStream( destFile );
+            
+            final byte[] buffer = new byte[ 16 * 1024 ];
+            
+            int count = 0;
+            int bytesTransfered = 0;
+            
+            while( ( count = in.read( buffer ) ) != -1 )
+            {
+                if( monitor.isCanceled() )
+                {
+                    throw new InterruptedException();
+                }
+                
+                out.write( buffer, 0, count );
+                bytesTransfered += count;
+                
+                monitor.worked( count );
+                monitor.setTaskName( formatDownloadProgressMessage( bytesTransfered, totalSizeString ) );
+            }
+        }
+        finally
+        {
+            if( in != null )
+            {
+                try
+                {
+                    in.close();
+                }
+                catch( IOException e ) {}
+            }
+            
+            if( out != null )
+            {
+                try
+                {
+                    out.close();
+                }
+                catch( IOException e ) {}
+            }
+            
+            monitor.done();
+        }
+    }
+    
+    private boolean shouldInclude( final IPath path )
+    {
+        if( ! this.includePatterns.isEmpty() )
+        {
+            boolean included = false;
+            
+            for( String pattern : this.includePatterns )
+            {
+                if( path.equals( new Path( pattern ) ) )
+                {
+                    included = true;
+                    break;
+                }
+            }
+            
+            if( ! included )
+            {
+                return false;
+            }
+        }
+        
+        for( String pattern : this.excludePatterns )
+        {
+            if( path.equals( new Path( pattern ) ) )
+            {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    private String formatByteCount( final int byteCount )
+    {
+        if( byteCount < 1024 * 1024 )
+        {
+            return String.format( "%3.0f KB", ( (float) byteCount ) / 1024 ); //$NON-NLS-1$
+        }
+        else
+        {
+            return String.format( "%.1f MB" , ( (float) byteCount ) / ( 1024 * 1024 ) ); //$NON-NLS-1$
+        }
+    }
+    
+    private String formatDownloadProgressMessage( final int bytesTransfered,
+                                                  final String totalSizeString )
+    {
+        final String bytesTransferedString = formatByteCount( bytesTransfered );
+        
+        if( totalSizeString != null )
+        {
+            return NLS.bind( Resources.progressTransferred, bytesTransferedString, totalSizeString );
+        }
+        else
+        {
+            return NLS.bind( Resources.progressTransferredNoTotalSize, bytesTransferedString );
+        }
+    }
+    
+    private static void delete( final File f )
+
+        throws IOException
+    
+    {