Create fragment project that handles PDE specific functionality (fixes 394054)

The fragment project org.eclipse.babel.core.pdeutils currently overwrites the static helper class PDEUtils of the
org.eclipse.babel.core plugin.
diff --git a/org.eclipse.babel.core.pdeutils/.classpath b/org.eclipse.babel.core.pdeutils/.classpath
new file mode 100644
index 0000000..4c62a80
--- /dev/null
+++ b/org.eclipse.babel.core.pdeutils/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.babel.core.pdeutils/.project b/org.eclipse.babel.core.pdeutils/.project
new file mode 100644
index 0000000..86318d6
--- /dev/null
+++ b/org.eclipse.babel.core.pdeutils/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.babel.core.pdeutils</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/org.eclipse.babel.core.pdeutils/META-INF/MANIFEST.MF b/org.eclipse.babel.core.pdeutils/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a2f896f
--- /dev/null
+++ b/org.eclipse.babel.core.pdeutils/META-INF/MANIFEST.MF
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Pdeutils
+Bundle-SymbolicName: org.eclipse.babel.core.pdeutils
+Bundle-Version: 1.0.0.qualifier
+Fragment-Host: org.eclipse.babel.core;bundle-version="0.8.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Eclipse-PatchFragment: true
+Require-Bundle: org.eclipse.pde.core;bundle-version="3.7.0"
diff --git a/org.eclipse.babel.core.pdeutils/about.html b/org.eclipse.babel.core.pdeutils/about.html
new file mode 100644
index 0000000..c258ef5
--- /dev/null
+++ b/org.eclipse.babel.core.pdeutils/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 5, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.babel.core.pdeutils/build.properties b/org.eclipse.babel.core.pdeutils/build.properties
new file mode 100644
index 0000000..0dd8eb6
--- /dev/null
+++ b/org.eclipse.babel.core.pdeutils/build.properties
@@ -0,0 +1,10 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               org.eclipse.babel.core.pdeutils.jar
+source.org.eclipse.babel.core.pdeutils.jar = src/
+jars.compile.order = org.eclipse.babel.core.pdeutils.jar,\
+                     .
+output.org.eclipse.babel.core.pdeutils.jar = bin/
+source.org.eclipse.babel.core.pdeutils.jar = src/
diff --git a/org.eclipse.babel.core.pdeutils/epl-v10.html b/org.eclipse.babel.core.pdeutils/epl-v10.html
new file mode 100644
index 0000000..84ec251
--- /dev/null
+++ b/org.eclipse.babel.core.pdeutils/epl-v10.html
@@ -0,0 +1,261 @@
+<?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">
+
+<p align=center><b>Eclipse Public License - v 1.0</b></p>
+
+<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/org.eclipse.babel.core.pdeutils/src/org/eclipse/babel/core/util/PDEUtils.java b/org.eclipse.babel.core.pdeutils/src/org/eclipse/babel/core/util/PDEUtils.java
new file mode 100644
index 0000000..a2403c9
--- /dev/null
+++ b/org.eclipse.babel.core.pdeutils/src/org/eclipse/babel/core/util/PDEUtils.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Stefan Reiterer.
+ * 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:
+ *     Stefan Reiterer - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.babel.core.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.HostSpecification;
+import org.eclipse.pde.core.plugin.IFragmentModel;
+import org.eclipse.pde.core.plugin.IPluginBase;
+import org.eclipse.pde.core.plugin.IPluginModelBase;
+import org.eclipse.pde.core.plugin.PluginRegistry;
+
+public class PDEUtils {
+
+	// The same as PDE.PLUGIN_NATURE, because the PDE provided constant is not accessible (internal class) 
+	private static final String PLUGIN_NATURE = "org.eclipse.pde.PluginNature";
+	
+	public static String getPluginId(IProject project) {
+
+		if (project == null || !isPluginProject(project)) {
+			return null;
+		}
+
+		IPluginModelBase pluginModelBase = PluginRegistry.findModel(project);
+		
+		if (pluginModelBase == null) {
+			// plugin not found in registry
+			return null;
+		}
+		
+		IPluginBase pluginBase = pluginModelBase.getPluginBase();
+
+		return pluginBase.getId();
+	}
+	
+	public static boolean isFragment(IProject pluginProject) {
+		if (pluginProject == null) {
+			return false;
+		}
+		
+		IPluginModelBase pModel = PluginRegistry.findModel(pluginProject);
+		
+		if (pModel == null) {
+			// this project is not a plugin/fragment
+			return false;
+		}
+		
+		return pModel.isFragmentModel();
+	}
+	
+	public static List<IProject> getFragments(IProject hostProject) {
+		// Check preconditions
+		String hostId = getPluginId(hostProject);
+		if (hostProject == null || hostId == null) {
+			// no valid host project given.
+			return Collections.emptyList();
+		}
+
+		// Get the fragments of the host project
+		IPluginModelBase pModelBase = PluginRegistry.findModel(hostProject);
+		BundleDescription desc = pModelBase.getBundleDescription();
+
+		ArrayList<IPluginModelBase> fragmentModels = new ArrayList<IPluginModelBase>();
+		if (desc == null) {
+			// There is no bundle description for the host project
+			return Collections.emptyList();
+		}
+		
+		BundleDescription[] f = desc.getFragments();
+		for (BundleDescription candidateDesc : f) {
+			IPluginModelBase candidate = PluginRegistry.findModel(candidateDesc);
+			if (candidate instanceof IFragmentModel) {
+				fragmentModels.add(candidate);
+			}
+		}
+		
+		// Get the fragment project which is in the current workspace
+		ArrayList<IProject> fragments = getFragmentsAsWorkspaceProjects(hostProject, fragmentModels);
+		
+		return fragments;		
+	}
+	
+	public static String getFragmentId(IProject project, String hostPluginId) {
+		if (!isFragment(project) || hostPluginId == null) {
+			return null;
+		}
+		
+		IPluginModelBase pluginModelBase = PluginRegistry.findModel(project);
+		if (pluginModelBase instanceof IFragmentModel) {
+			IFragmentModel fragmentModel = (IFragmentModel) pluginModelBase;
+			BundleDescription description = fragmentModel.getBundleDescription();
+			HostSpecification hostSpecification = description.getHost();
+
+			if (hostPluginId.equals(hostSpecification.getName())) {
+				return getPluginId(project);
+			}
+		}
+		return null;
+	}
+	
+	public static IProject getFragmentHost(IProject fragment) {
+		if (!isFragment(fragment)) {
+			return null;
+		}
+		
+		IPluginModelBase pluginModelBase = PluginRegistry.findModel(fragment);
+		if (pluginModelBase instanceof IFragmentModel) {
+			IFragmentModel fragmentModel = (IFragmentModel) pluginModelBase;
+			BundleDescription description = fragmentModel.getBundleDescription();
+			HostSpecification hostSpecification = description.getHost();
+			
+			IPluginModelBase hostProject = PluginRegistry.findModel(hostSpecification.getName());
+			IProject[] projects = fragment.getWorkspace().getRoot().getProjects();
+			ArrayList<IProject> hostProjects = getPluginProjects(Arrays.asList(hostProject), projects);
+			
+			if (hostProjects.size() != 1) {
+				// hostproject not in workspace
+				return null;
+			} else {
+				return hostProjects.get(0);
+			}
+		}
+		
+		return null;
+	}
+
+	/**
+	 * Returns all project containing plugin/fragment of the specified project.
+	 * If the specified project itself is a fragment, then only this is
+	 * returned.
+	 * 
+	 * @param pluginProject
+	 *            the plugin project
+	 * @return the all project containing a fragment or null if none
+	 */
+	public static IProject[] lookupFragment(IProject pluginProject) {
+		if (isFragment(pluginProject) && pluginProject.isOpen()) {
+			return new IProject[] {pluginProject};
+		}
+		
+		IProject[] workspaceProjects = pluginProject.getWorkspace().getRoot().getProjects();
+		String hostPluginId = getPluginId(pluginProject);
+		
+		if (hostPluginId == null) {
+			// project is not a plugin project
+			return null;
+		}
+		
+		List<IProject> fragmentProjects = new ArrayList<IProject>();
+		for (IProject project : workspaceProjects) {
+			if (!project.isOpen() || getFragmentId(project, hostPluginId) == null) {
+				// project is not open or it is no fragment where given project is the host project.
+				continue;
+			}
+			fragmentProjects.add(project);
+		}
+
+		if (fragmentProjects.isEmpty()) {
+			return null;
+		}
+		
+		return fragmentProjects.toArray(new IProject[0]);
+	}
+	
+	private static ArrayList<IProject> getFragmentsAsWorkspaceProjects(IProject hostProject, ArrayList<IPluginModelBase> fragmentModels) {
+		IProject[] projects = hostProject.getWorkspace().getRoot().getProjects();
+		
+		ArrayList<IProject> fragments = getPluginProjects(fragmentModels, projects);
+		
+		return fragments;
+	}
+
+	private static ArrayList<IProject> getPluginProjects(List<IPluginModelBase> fragmentModels, IProject[] projects) {
+		ArrayList<IProject> fragments = new ArrayList<IProject>();
+		for (IProject project : projects) {
+			IPluginModelBase pModel = PluginRegistry.findModel(project);
+			
+			if (fragmentModels.contains(pModel)) {
+				fragments.add(project);
+			}
+		}
+		
+		return fragments;
+	}
+	
+	private static boolean isPluginProject(IProject project) {
+		try {
+			return project.hasNature(PLUGIN_NATURE);
+		} catch (CoreException ce) {
+			//Logger.logError(ce);
+		}
+		return false;
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.babel.core/META-INF/MANIFEST.MF b/org.eclipse.babel.core/META-INF/MANIFEST.MF
index 2ed2b8d..ca00754 100644
--- a/org.eclipse.babel.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.babel.core/META-INF/MANIFEST.MF
@@ -29,3 +29,6 @@
  org.eclipse.jdt.core;bundle-version="3.6.2",
  org.eclipse.pde.core;bundle-version="3.7.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Eclipse-ExtensibleAPI: true
+Bundle-ClassPath: org.eclipse.babel.core.pdeutils.jar,
+ .
diff --git a/org.eclipse.babel.core/build.properties b/org.eclipse.babel.core/build.properties
index eabc8e4..f7ef82f 100644
--- a/org.eclipse.babel.core/build.properties
+++ b/org.eclipse.babel.core/build.properties
@@ -3,6 +3,10 @@
 bin.includes = META-INF/,\
                .,\
                bin/,\
-               plugin.xml
+               plugin.xml,\
+               org.eclipse.babel.core.pdeutils.jar
 src.includes = bin/,\
                src/
+source.org.eclipse.babel.core.pdeutils.jar = 
+jars.compile.order = org.eclipse.babel.core.pdeutils.jar,\
+                     .
diff --git a/org.eclipse.babel.core/src/org/eclipse/babel/core/util/PDEUtils.java b/org.eclipse.babel.core/src/org/eclipse/babel/core/util/PDEUtils.java
index 7114b39..e12c764 100644
--- a/org.eclipse.babel.core/src/org/eclipse/babel/core/util/PDEUtils.java
+++ b/org.eclipse.babel.core/src/org/eclipse/babel/core/util/PDEUtils.java
@@ -11,255 +11,90 @@
 
 package org.eclipse.babel.core.util;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
 import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.osgi.service.resolver.BundleDescription;
-import org.eclipse.osgi.service.resolver.HostSpecification;
-import org.eclipse.pde.core.plugin.IFragmentModel;
-import org.eclipse.pde.core.plugin.IPluginBase;
-import org.eclipse.pde.core.plugin.IPluginModelBase;
-import org.eclipse.pde.core.plugin.PluginRegistry;
 
+/**
+ * This class provides common functionality to access eclipse plug-in
+ * properties.
+ * 
+ * NOTE: Eclipse PDE core dependency is optional. Without PDE installed, the
+ * methods of this class return null or empty data structures. (It is not usual
+ * to manage eclipse plug-in projects, without PDE installed.
+ * 
+ * NOTE: The real implementation of this class is in the fragment
+ * org.eclipse.babel.core.pdeutils.
+ * 
+ * @author Stefan Reiterer
+ * 
+ */
 public class PDEUtils {
 
-    // The same as PDE.PLUGIN_NATURE, because the PDE provided constant is not
-    // accessible (internal class)
-    private static final String PLUGIN_NATURE = "org.eclipse.pde.PluginNature";
+	/**
+	 * Get the project's plug-in Id if the given project is an eclipse plug-in.
+	 * 
+	 * @param project
+	 *            the workspace project.
+	 * @return the project's plug-in Id. Null if the project is no plug-in
+	 *         project.
+	 */
+	public static String getPluginId(IProject project) {
+		return null;
+	}
 
-    /**
-     * Get the project's plug-in Id if the given project is an eclipse plug-in.
-     * 
-     * @param project
-     *            the workspace project.
-     * @return the project's plug-in Id. Null if the project is no plug-in
-     *         project.
-     */
-    public static String getPluginId(IProject project) {
+	/**
+	 * Check if the given plug-in project is a fragment.
+	 * 
+	 * @param pluginProject
+	 *            the plug-in project in the workspace.
+	 * @return true if it is a fragment, otherwise false.
+	 */
+	public static boolean isFragment(IProject pluginProject) {
+		return false;
+	}
 
-        if (project == null || !isPluginProject(project)) {
-            return null;
-        }
+	/**
+	 * Get all fragments for the given host project.
+	 * 
+	 * @param hostProject
+	 *            the host plug-in project in the workspace.
+	 * @return a list of all fragment projects for the given host project which
+	 *         are in the same workspace as the host project.
+	 */
+	public static List<IProject> getFragments(IProject hostProject) {
+		return Collections.emptyList();
+	}
 
-        IPluginModelBase pluginModelBase = PluginRegistry.findModel(project);
+	/**
+	 * Returns the fragment-id of the project if it is a fragment project with
+	 * the specified host plugin id as host. Else null is returned.
+	 * 
+	 * @param project
+	 *            the project
+	 * @param hostPluginId
+	 *            the host plugin id
+	 * @return the plugin-id or null
+	 */
+	public static String getFragmentId(IProject project, String hostPluginId) {
+		return null;
+	}
 
-        if (pluginModelBase == null) {
-            // plugin not found in registry
-            return null;
-        }
+	/**
+	 * Returns the host plugin project of the specified project if it contains a
+	 * fragment.
+	 * 
+	 * @param fragment
+	 *            the fragment project
+	 * @return the host plugin project or null
+	 */
+	public static IProject getFragmentHost(IProject fragment) {
+		return null;
+	}
 
-        IPluginBase pluginBase = pluginModelBase.getPluginBase();
+	public static IProject[] lookupFragment(IProject fragment) {
+		return null;
+	}
 
-        return pluginBase.getId();
-    }
-
-    /**
-     * Returns all project containing plugin/fragment of the specified project.
-     * If the specified project itself is a fragment, then only this is
-     * returned.
-     * 
-     * @param pluginProject
-     *            the plugin project
-     * @return the all project containing a fragment or null if none
-     */
-    public static IProject[] lookupFragment(IProject pluginProject) {
-        if (isFragment(pluginProject) && pluginProject.isOpen()) {
-            return new IProject[] { pluginProject };
-        }
-
-        IProject[] workspaceProjects = pluginProject.getWorkspace().getRoot()
-                .getProjects();
-        String hostPluginId = getPluginId(pluginProject);
-
-        if (hostPluginId == null) {
-            // project is not a plugin project
-            return null;
-        }
-
-        List<IProject> fragmentProjects = new ArrayList<IProject>();
-        for (IProject project : workspaceProjects) {
-            if (!project.isOpen()
-                    || getFragmentId(project, hostPluginId) == null) {
-                // project is not open or it is no fragment where given project
-                // is the host project.
-                continue;
-            }
-            fragmentProjects.add(project);
-        }
-
-        if (fragmentProjects.isEmpty()) {
-            return null;
-        }
-
-        return fragmentProjects.toArray(new IProject[0]);
-    }
-
-    /**
-     * Check if the given plug-in project is a fragment.
-     * 
-     * @param pluginProject
-     *            the plug-in project in the workspace.
-     * @return true if it is a fragment, otherwise false.
-     */
-    public static boolean isFragment(IProject pluginProject) {
-        if (pluginProject == null) {
-            return false;
-        }
-
-        IPluginModelBase pModel = PluginRegistry.findModel(pluginProject);
-
-        if (pModel == null) {
-            // this project is not a plugin/fragment
-            return false;
-        }
-
-        return pModel.isFragmentModel();
-    }
-
-    /**
-     * Get all fragments for the given host project.
-     * 
-     * @param hostProject
-     *            the host plug-in project in the workspace.
-     * @return a list of all fragment projects for the given host project which
-     *         are in the same workspace as the host project.
-     */
-    public static List<IProject> getFragments(IProject hostProject) {
-        // Check preconditions
-        String hostId = getPluginId(hostProject);
-        if (hostProject == null || hostId == null) {
-            // no valid host project given.
-            return Collections.emptyList();
-        }
-
-        // Get the fragments of the host project
-        IPluginModelBase pModelBase = PluginRegistry.findModel(hostProject);
-        BundleDescription desc = pModelBase.getBundleDescription();
-
-        ArrayList<IPluginModelBase> fragmentModels = new ArrayList<IPluginModelBase>();
-        if (desc == null) {
-            // There is no bundle description for the host project
-            return Collections.emptyList();
-        }
-
-        BundleDescription[] f = desc.getFragments();
-        for (BundleDescription candidateDesc : f) {
-            IPluginModelBase candidate = PluginRegistry
-                    .findModel(candidateDesc);
-            if (candidate instanceof IFragmentModel) {
-                fragmentModels.add(candidate);
-            }
-        }
-
-        // Get the fragment project which is in the current workspace
-        ArrayList<IProject> fragments = getFragmentsAsWorkspaceProjects(
-                hostProject, fragmentModels);
-
-        return fragments;
-    }
-
-    /**
-     * Returns the fragment-id of the project if it is a fragment project with
-     * the specified host plugin id as host. Else null is returned.
-     * 
-     * @param project
-     *            the project
-     * @param hostPluginId
-     *            the host plugin id
-     * @return the plugin-id or null
-     */
-    public static String getFragmentId(IProject project, String hostPluginId) {
-        if (!isFragment(project) || hostPluginId == null) {
-            return null;
-        }
-
-        IPluginModelBase pluginModelBase = PluginRegistry.findModel(project);
-        if (pluginModelBase instanceof IFragmentModel) {
-            IFragmentModel fragmentModel = (IFragmentModel) pluginModelBase;
-            BundleDescription description = fragmentModel
-                    .getBundleDescription();
-            HostSpecification hostSpecification = description.getHost();
-
-            if (hostPluginId.equals(hostSpecification.getName())) {
-                return getPluginId(project);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the host plugin project of the specified project if it contains a
-     * fragment.
-     * 
-     * @param fragment
-     *            the fragment project
-     * @return the host plugin project or null
-     */
-    public static IProject getFragmentHost(IProject fragment) {
-        if (!isFragment(fragment)) {
-            return null;
-        }
-
-        IPluginModelBase pluginModelBase = PluginRegistry.findModel(fragment);
-        if (pluginModelBase instanceof IFragmentModel) {
-            IFragmentModel fragmentModel = (IFragmentModel) pluginModelBase;
-            BundleDescription description = fragmentModel
-                    .getBundleDescription();
-            HostSpecification hostSpecification = description.getHost();
-
-            IPluginModelBase hostProject = PluginRegistry
-                    .findModel(hostSpecification.getName());
-            IProject[] projects = fragment.getWorkspace().getRoot()
-                    .getProjects();
-            ArrayList<IProject> hostProjects = getPluginProjects(
-                    Arrays.asList(hostProject), projects);
-
-            if (hostProjects.size() != 1) {
-                // hostproject not in workspace
-                return null;
-            } else {
-                return hostProjects.get(0);
-            }
-        }
-
-        return null;
-    }
-
-    private static ArrayList<IProject> getFragmentsAsWorkspaceProjects(
-            IProject hostProject, ArrayList<IPluginModelBase> fragmentModels) {
-        IProject[] projects = hostProject.getWorkspace().getRoot()
-                .getProjects();
-
-        ArrayList<IProject> fragments = getPluginProjects(fragmentModels,
-                projects);
-
-        return fragments;
-    }
-
-    private static ArrayList<IProject> getPluginProjects(
-            List<IPluginModelBase> fragmentModels, IProject[] projects) {
-        ArrayList<IProject> fragments = new ArrayList<IProject>();
-        for (IProject project : projects) {
-            IPluginModelBase pModel = PluginRegistry.findModel(project);
-
-            if (fragmentModels.contains(pModel)) {
-                fragments.add(project);
-            }
-        }
-
-        return fragments;
-    }
-
-    private static boolean isPluginProject(IProject project) {
-        try {
-            return project.hasNature(PLUGIN_NATURE);
-        } catch (CoreException ce) {
-            // Logger.logError(ce);
-        }
-        return false;
-    }
-}
\ No newline at end of file
+}