[562175] Register transformation container in plugin.xml
diff --git a/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/OSGI-INF/javaproject.xml b/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/OSGI-INF/javaproject.xml
index fc863de..daed0fb 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/OSGI-INF/javaproject.xml
+++ b/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/OSGI-INF/javaproject.xml
@@ -2,6 +2,6 @@
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.m2m.qvt.oml.runtime.jdt">
    <implementation class="org.eclipse.m2m.internal.qvt.oml.jdt.ui.wizard.project.JdtProjectIntegrationImpl"/>
    <service>
-      <provide interface="org.eclipse.m2m.internal.qvt.oml.ui.wizards.project.JdtProjectIntegration"/>
+      <provide interface="org.eclipse.m2m.internal.qvt.oml.ui.wizards.project.ProjectIntegration"/>
    </service>
 </scr:component>
diff --git a/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/ui/wizard/project/JdtProjectIntegrationImpl.java b/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/ui/wizard/project/JdtProjectIntegrationImpl.java
index 7574336..662bac3 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/ui/wizard/project/JdtProjectIntegrationImpl.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/ui/wizard/project/JdtProjectIntegrationImpl.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2019 Borland Software Corporation and others.
+ * Copyright (c) 2009, 2020 Borland Software Corporation and others.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
@@ -8,23 +8,22 @@
  *
  * Contributors:
  *     Borland Software Corporation - initial API and implementation
+ *     Christopher Gerking - bug 562175
  *******************************************************************************/
 package org.eclipse.m2m.internal.qvt.oml.jdt.ui.wizard.project;
 
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.StringTokenizer;
 
 import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubMonitor;
 import org.eclipse.jdt.core.IClasspathEntry;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.JavaConventions;
@@ -37,14 +36,13 @@
 import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
 import org.eclipse.jface.util.Policy;
 import org.eclipse.m2m.internal.qvt.oml.jdt.debug.ui.launch.DebugPDEMessages;
-import org.eclipse.m2m.internal.qvt.oml.ui.wizards.project.JdtProjectIntegration;
+import org.eclipse.m2m.internal.qvt.oml.ui.wizards.project.NewProjectData;
+import org.eclipse.pde.internal.core.ClasspathComputer;
 import org.eclipse.pde.internal.core.util.CoreUtility;
 import org.eclipse.swt.widgets.Combo;
 
 @SuppressWarnings("restriction")
-public class JdtProjectIntegrationImpl implements JdtProjectIntegration {
-
-	private static final IPath REQUIRED_PLUGINS_CONTAINER_PATH = new Path("org.eclipse.pde.core.requiredPlugins"); //$NON-NLS-1$
+public class JdtProjectIntegrationImpl extends PdeProjectIntegrationImpl {
 
 	private static Map<String, Integer> fSeverityTable;
 	private static final int SEVERITY_ERROR = 3;
@@ -53,68 +51,55 @@
 
 	static {
 		fSeverityTable = new HashMap<String, Integer>(3);
-		fSeverityTable.put(JavaCore.IGNORE, new Integer(SEVERITY_IGNORE));
-		fSeverityTable.put(JavaCore.WARNING, new Integer(SEVERITY_WARNING));
-		fSeverityTable.put(JavaCore.ERROR, new Integer(SEVERITY_ERROR));
+		fSeverityTable.put(JavaCore.IGNORE, Integer.valueOf(SEVERITY_IGNORE));
+		fSeverityTable.put(JavaCore.WARNING, Integer.valueOf(SEVERITY_WARNING));
+		fSeverityTable.put(JavaCore.ERROR, Integer.valueOf(SEVERITY_ERROR));
 	}
 
-	public void setupJava(IProject project, boolean isPDE, String sourceFolder, String outFolder, String executionEnv,
-			IProgressMonitor monitor) throws CoreException {
-
-		CoreUtility.addNatureToProject(project, JavaCore.NATURE_ID, monitor);
-
-		IContainer srcContainer = createFolder(project, sourceFolder, monitor);
-		IContainer binContainer = createFolder(project, outFolder, monitor);
-
-		IJavaProject javaProject = JavaCore.create(project);
-		javaProject.setOutputLocation(binContainer.getFullPath(), monitor);
-
-		monitor.subTask(DebugPDEMessages.Setup_SettingClasspath);
-
-		IClasspathEntry[] entries = new IClasspathEntry[isPDE ? 3 : 1];
-		if (isPDE) {
-			String executionEnvironment = executionEnv;
-			setComplianceOptions(javaProject, executionEnvironment, true);
-			entries[0] = createJREEntry(executionEnvironment);
-			entries[1] = createContainerEntry();
+	public void setupProject(IProject project, NewProjectData data, IProgressMonitor monitor) throws CoreException {
+		
+		try {
+			SubMonitor subMonitor = SubMonitor.convert(monitor, 6);
+			
+			super.setupProject(project, data, subMonitor.split(1));
+			
+			if (data.isCreateJava()) {
+				CoreUtility.addNatureToProject(project, JavaCore.NATURE_ID, subMonitor.split(1));
+		
+				IContainer srcContainer = getFolder(project, data.getSourceFolderName(), subMonitor.split(1));
+				IContainer binContainer = getFolder(project, data.getOutFolderName(), subMonitor.split(1));
+		
+				IJavaProject javaProject = JavaCore.create(project);
+				javaProject.setOutputLocation(binContainer.getFullPath(), subMonitor.split(1));
+		
+				subMonitor.subTask(DebugPDEMessages.Setup_SettingClasspath);
+		
+				IClasspathEntry[] entries = new IClasspathEntry[data.isPlugin() ? 3 : 1];
+				if (data.isPlugin()) {
+					String executionEnvironment = data.getfExecutionEnv();
+					ClasspathComputer.setComplianceOptions(javaProject, executionEnvironment, true);
+					entries[0] = ClasspathComputer.createJREEntry(executionEnvironment);
+					entries[1] = ClasspathComputer.createContainerEntry();
+				}
+		
+				entries[entries.length - 1] = JavaCore.newSourceEntry(srcContainer.getFullPath());
+				javaProject.setRawClasspath(entries, subMonitor.split(1));
+				
+				if(data.isDoGenerateClass()) {
+					generateTopLevelPluginClass(subMonitor.split(1));
+				}
+			}
+			
+		} finally {
+			SubMonitor.done(monitor);
 		}
-
-		entries[entries.length - 1] = JavaCore.newSourceEntry(srcContainer.getFullPath());
-		javaProject.setRawClasspath(entries, monitor);
 	}
 
 	public String getRequiredExecutionEnv(String executionEnv) {
 		if (getEEnv(executionEnv) == null) {
 			return null;
 		}
-		return "Bundle-RequiredExecutionEnvironment: " + executionEnv; //$NON-NLS-1$
-	}
-
-	/**
-	 * Returns a classpath container entry for the given execution environment.
-	 * @param ee id of the execution environment
-	 * @return classpath container entry
-	 */
-	private static IClasspathEntry createJREEntry(String ee) {
-		return JavaCore.newContainerEntry(getEEPath(ee));
-	}
-
-	/**
-	 * Returns the JRE container path for the execution environment with the given id.
-	 * @param ee execution environment id
-	 * @return JRE container path for the execution environment
-	 */
-	private static IPath getEEPath(String ee) {
-		IPath path = null;
-		if (ee != null) {
-			IExecutionEnvironment env = getEEnv(ee);
-			if (env != null)
-				path = JavaRuntime.newJREContainerPath(env);
-		}
-		if (path == null) {
-			path = JavaRuntime.newDefaultJREContainerPath();
-		}
-		return path;
+		return executionEnv;
 	}
 
 	private static IExecutionEnvironment getEEnv(String ee) {
@@ -124,79 +109,9 @@
 		}
 		return null;
 	}
-
-	private static IClasspathEntry createContainerEntry() {
-		return JavaCore.newContainerEntry(REQUIRED_PLUGINS_CONTAINER_PATH);
-	}
-
-	private static void setComplianceOptions(IJavaProject project, String eeId, boolean overrideExisting) {
-		@SuppressWarnings("unchecked")
-		Map<String, String> projectMap = project.getOptions(false);
-		IExecutionEnvironment ee = null;
-		Map<String, String> options = null;
-		if (eeId != null) {
-			ee = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(eeId);
-			if (ee != null) {
-				options = ee.getComplianceOptions();
-			}
-		}
-		if (options == null) {
-			if (overrideExisting && projectMap.size() > 0) {
-				projectMap.remove(JavaCore.COMPILER_COMPLIANCE);
-				projectMap.remove(JavaCore.COMPILER_SOURCE);
-				projectMap.remove(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
-				projectMap.remove(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER);
-				projectMap.remove(JavaCore.COMPILER_PB_ENUM_IDENTIFIER);
-			} else {
-				return;
-			}
-		} else {
-			String compliance = options.get(JavaCore.COMPILER_COMPLIANCE);
-			for (Entry<String, String> entry : options.entrySet()) {
-				String option = entry.getKey();
-				String value = entry.getValue();
-				if (JavaCore.VERSION_1_3.equals(compliance) || JavaCore.VERSION_1_4.equals(compliance)) {
-					if (JavaCore.COMPILER_PB_ASSERT_IDENTIFIER.equals(option) || JavaCore.COMPILER_PB_ENUM_IDENTIFIER.equals(option)) {
-						// for 1.3 & 1.4 projects, only override the existing setting if the default setting
-						// is a greater severity than the existing setting
-						setMinimumCompliance(projectMap, option, value, overrideExisting);
-					} else {
-						setCompliance(projectMap, option, value, overrideExisting);
-					}
-				} else {
-					setCompliance(projectMap, option, value, overrideExisting);
-				}
-			}
-		}
-
-		project.setOptions(projectMap);
-	}
-
-	private static void setMinimumCompliance(Map<String, String> map, String key, String minimumValue, boolean override) {
-		if (minimumValue != null && (override || !map.containsKey(key))) {
-			String currentValue = map.get(key);
-			int current = currentValue != null && fSeverityTable.containsKey(currentValue) ? fSeverityTable.get(currentValue) : 0;
-			int minimum = minimumValue != null && fSeverityTable.containsKey(minimumValue) ? fSeverityTable.get(minimumValue) : 0;
-			if (current < minimum) {
-				map.put(key, minimumValue);
-			}
-		}
-	}
-
-	private static void setCompliance(Map<String, String> map, String key, String value, boolean override) {
-		if (value != null && (override || !map.containsKey(key))) {
-			map.put(key, value);
-		}
-	}
-
-	private static IContainer createFolder(IProject project, String folderName, IProgressMonitor monitor) throws CoreException {
-		if(folderName == null || folderName.trim().length() == 0) {
-			return project;
-		}
-
-		IFolder folder = project.getFolder(folderName);
+	
+	protected void createFolder(IFolder folder, IProgressMonitor monitor) throws CoreException {
 		org.eclipse.jdt.internal.ui.util.CoreUtility.createFolder(folder, true, true, monitor);
-		return folder;
 	}
 
 	public String getClassField(String id, String suffix) {
@@ -288,8 +203,8 @@
 			if (defaultCC.endsWith(eeCompliance))
 				return environments[i].getId();
 		}
-
-		return "J2SE-1.5";//"JavaSE-1.7"; //$NON-NLS-1$
+		
+		return "J2SE-1.5"; //$NON-NLS-1$
 	}
-
+	
 }
diff --git a/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/ui/wizard/project/PdeProjectIntegrationImpl.java b/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/ui/wizard/project/PdeProjectIntegrationImpl.java
new file mode 100644
index 0000000..c328232
--- /dev/null
+++ b/plugins/org.eclipse.m2m.qvt.oml.runtime.jdt/src/org/eclipse/m2m/internal/qvt/oml/jdt/ui/wizard/project/PdeProjectIntegrationImpl.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2020 Borland Software Corporation and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ *     Borland Software Corporation - initial API and implementation
+ *     Christopher Gerking - bug 562175
+ *******************************************************************************/
+package org.eclipse.m2m.internal.qvt.oml.jdt.ui.wizard.project;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.m2m.internal.qvt.oml.runtime.project.PlatformPluginUnitResolver;
+import org.eclipse.m2m.internal.qvt.oml.ui.wizards.project.NewProjectData;
+import org.eclipse.m2m.internal.qvt.oml.ui.wizards.project.ProjectIntegration;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.eclipse.pde.core.build.IBuildEntry;
+import org.eclipse.pde.core.plugin.IPluginElement;
+import org.eclipse.pde.core.plugin.IPluginExtension;
+import org.eclipse.pde.core.plugin.IPluginReference;
+import org.eclipse.pde.core.project.IBundleProjectDescription;
+import org.eclipse.pde.core.project.IBundleProjectService;
+import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
+import org.eclipse.pde.internal.core.plugin.WorkspacePluginModel;
+import org.eclipse.pde.internal.core.plugin.WorkspacePluginModelBase;
+import org.eclipse.pde.internal.core.project.PDEProject;
+import org.eclipse.pde.internal.core.project.RequiredBundleDescription;
+import org.eclipse.pde.internal.core.util.CoreUtility;
+import org.eclipse.pde.internal.ui.wizards.plugin.PluginClassCodeGenerator;
+import org.eclipse.pde.internal.ui.wizards.plugin.PluginFieldData;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+
+@SuppressWarnings("restriction")
+public abstract class PdeProjectIntegrationImpl implements ProjectIntegration {
+	
+	private PluginClassCodeGenerator fGenerator;
+	
+	private PluginFieldData toFieldData(NewProjectData projectData) {
+		PluginFieldData fieldData = new PluginFieldData();
+		
+		fieldData.setClassname(projectData.getClassName());
+		fieldData.setDoGenerateClass(projectData.isDoGenerateClass());
+		fieldData.setExecutionEnvironment(projectData.getfExecutionEnv());
+		fieldData.setName(projectData.getName());
+		fieldData.setOutputFolderName(projectData.getOutFolderName());
+		fieldData.setProvider(projectData.getProviderName());
+		fieldData.setSourceFolderName(projectData.getSourceFolderName());
+		fieldData.setVersion(projectData.getVersion());
+		fieldData.setUIPlugin(false);
+		
+		return fieldData;
+	}
+	
+	public void setupProject(IProject project, final NewProjectData data, IProgressMonitor monitor) throws CoreException {
+	
+		try {
+			if (data.isPlugin()) {
+				
+				SubMonitor subMonitor = SubMonitor.convert(monitor, 4);
+				
+				fGenerator = new PluginClassCodeGenerator(project, data.getClassName(), toFieldData(data), false);
+				
+				// add plugin nature to project
+				CoreUtility.addNatureToProject(project, IBundleProjectDescription.PLUGIN_NATURE, subMonitor.split(1));
+					    			    	
+				// generate the manifest.mf file
+				createManifest(project, data, subMonitor.split(1));
+				
+				// generate the plugin.xml file
+				createPluginXml(project, data, subMonitor.split(1));
+				
+				// generate the build.properties file
+				createBuildProperties(project, data, subMonitor.split(1));
+		    }
+		} finally {
+			SubMonitor.done(monitor);
+		}
+
+	}
+		
+	private IPluginReference[] getDependencies() {
+		if (fGenerator == null) {
+			return new IPluginReference[0];
+		}
+		return fGenerator.getDependencies();
+	}
+	
+	protected void generateTopLevelPluginClass(IProgressMonitor monitor) throws CoreException {
+		fGenerator.generate(monitor);
+	}
+	
+	private void createManifest(IProject project, NewProjectData data, IProgressMonitor monitor) throws CoreException {
+		
+ 		SubMonitor subMonitor = SubMonitor.convert(monitor);
+		
+		try {		
+	    	BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
+	    	ServiceReference<IBundleProjectService> serviceReference = context.getServiceReference(IBundleProjectService.class);
+	    	IBundleProjectService service = context.getService(serviceReference);
+	    	IBundleProjectDescription description = service.getDescription(project);
+	    		    		    	
+	    	description.setBundleName(data.getName());
+	    	description.setSymbolicName(data.getID());
+	    	description.setBundleVersion(new Version(data.getVersion()));
+	    	if (data.isDoGenerateClass() && !data.getClassName().isEmpty()) {
+				description.setActivator(data.getClassName());
+			}
+			if (!data.getProviderName().isEmpty()) {
+				description.setBundleVendor(data.getProviderName());
+			}
+			
+			IPluginReference[] dependencies = getDependencies();
+			if (dependencies.length > 0) {
+				List<RequiredBundleDescription> requiredBundles = new ArrayList<RequiredBundleDescription>();
+				for (IPluginReference pluginReference : dependencies) {	
+					requiredBundles.add(new RequiredBundleDescription(pluginReference.getId(), new VersionRange(pluginReference.getVersion()), false, false));
+				}
+				description.setRequiredBundles(requiredBundles.toArray(new RequiredBundleDescription[] {}));
+			}
+	
+			if (data.isCreateJava()) {
+				String requiredEnv = getRequiredExecutionEnv(data.getfExecutionEnv());
+				if (requiredEnv != null) {
+					description.setExecutionEnvironments(new String[] {requiredEnv});
+				}
+			}
+			
+			description.setActivationPolicy(Constants.ACTIVATION_LAZY);
+			
+			description.setSingleton(true);
+			
+	    	description.apply(subMonitor);
+	    	context.ungetService(serviceReference);
+	    	
+		} finally {
+			SubMonitor.done(monitor);
+		}
+	}
+	
+	private void createBuildProperties(IProject project, NewProjectData data, IProgressMonitor monitor) throws CoreException {
+		
+		SubMonitor subMonitor = SubMonitor.convert(monitor, 3);
+		
+		try {
+			IFile buildProperties = PDEProject.getBuildProperties(project);
+			WorkspaceBuildModel buildModel = new WorkspaceBuildModel(buildProperties);
+			buildModel.load();
+			buildModel.setEditable(true);
+	
+			if(data.isCreateJava()) {
+				IPath sourceFolder = asBinIncludesFolder(getFolder(project, data.getSourceFolderName(), subMonitor.split(1)));
+				IPath outFolder = asBinIncludesFolder(getFolder(project, data.getOutFolderName(), subMonitor.split(1)));
+	
+				IBuildEntry sourceEntry = buildModel.getFactory().createEntry(IBuildEntry.JAR_PREFIX + "."); //$NON-NLS-1$
+				sourceEntry.addToken(sourceFolder.toString());
+				buildModel.getBuild().add(sourceEntry);
+				
+				IBuildEntry outputEntry = buildModel.getFactory().createEntry(IBuildEntry.OUTPUT_PREFIX + "."); //$NON-NLS-1$
+				outputEntry.addToken(outFolder.toString());
+				buildModel.getBuild().add(outputEntry);
+			}
+
+			IBuildEntry binIncludesEntry = buildModel.getBuild().getEntry(IBuildEntry.BIN_INCLUDES);
+			
+			if(data.isCreateJava()) {
+				binIncludesEntry.addToken("."); //$NON-NLS-1$
+			}
+	
+			IContainer qvtContainer = getFolder(project, data.getQVTSourceFolderName(), subMonitor.split(1));
+			IPath qvtFolder = asBinIncludesFolder(qvtContainer);
+			if(!project.equals(qvtContainer) || !data.isCreateJava()) {
+				binIncludesEntry.addToken(qvtFolder.toString());
+			}
+			
+			binIncludesEntry.addToken(PDEProject.getPluginXml(project).getProjectRelativePath().toString());
+			
+			buildModel.save();
+		}
+		finally {
+			SubMonitor.done(monitor);
+		}
+	}
+	
+	private void createPluginXml(IProject project, NewProjectData data, IProgressMonitor monitor) throws CoreException {
+		
+		try {
+			// register QVT source container in plugin.xml
+			IFile pluginXml = PDEProject.getPluginXml(project);
+	    	WorkspacePluginModelBase pluginModel = new WorkspacePluginModel(pluginXml, false);
+	    	pluginModel.load();
+	    	pluginModel.setEditable(true);
+	    	IPluginExtension pluginExtension = pluginModel.createExtension();
+	    	IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(PlatformPluginUnitResolver.SOURCE_CONTAINER_POINT);
+	    	pluginExtension.setPoint(extensionPoint.getUniqueIdentifier());
+	    	IPluginElement element = pluginModel.createElement(pluginExtension);
+	    	element.setName(PlatformPluginUnitResolver.SOURCE_CONTAINER);
+	    	element.setAttribute(PlatformPluginUnitResolver.CONTAINER_PATH, data.getQVTSourceFolderName());
+	    	pluginExtension.add(element);
+	    	pluginModel.getExtensions().add(pluginExtension);
+	    	pluginModel.save();
+		}
+		finally {
+			SubMonitor.done(monitor);
+		}
+		
+	}
+		
+	private IPath asBinIncludesFolder(IContainer container) {
+		if(container.equals(container.getProject())) {
+			return new Path("."); //$NON-NLS-1$
+		}
+		IPath result = container.getProjectRelativePath();   
+		while(result.hasTrailingSeparator()) {
+			result = result.removeTrailingSeparator();
+		}
+		// ensure single trailing slash
+		return result.addTrailingSeparator(); 
+	}
+	
+	protected IContainer getFolder(IProject project, String folderName, IProgressMonitor monitor) throws CoreException {
+		try {
+			if(folderName == null || folderName.trim().length() == 0) {
+				return project;			
+			}
+			
+			IFolder folder = project.getFolder(folderName);
+			if(!folder.exists()) {
+				createFolder(folder, monitor);
+			}
+			return folder;
+		} finally {
+			SubMonitor.done(monitor);
+		}
+	}
+	
+	protected void createFolder(IFolder folder, IProgressMonitor monitor) throws CoreException {
+		CoreUtility.createFolder(folder);	
+	}
+
+}
diff --git a/plugins/org.eclipse.m2m.qvt.oml.runtime/META-INF/MANIFEST.MF b/plugins/org.eclipse.m2m.qvt.oml.runtime/META-INF/MANIFEST.MF
index d84b9b2..b6f3017 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.runtime/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.m2m.qvt.oml.runtime/META-INF/MANIFEST.MF
@@ -15,12 +15,13 @@
    org.eclipse.m2m.qvt.oml.debug.core,
    org.eclipse.m2m.qvt.oml.runtime.jdt",
  org.eclipse.m2m.internal.qvt.oml.runtime.project;
-  x-friends:="org.eclipse.m2m.qvt.oml.runtime.ui,
+  x-friends:="org.eclipse.m2m.qvt.oml.debug.core,
    org.eclipse.m2m.qvt.oml.editor.ui,
    org.eclipse.m2m.qvt.oml.project,
-   org.eclipse.m2m.qvt.oml.debug.core,
    org.eclipse.m2m.qvt.oml.runtime.jdt,
-   org.eclipse.m2m.tests.qvt.oml",
+   org.eclipse.m2m.qvt.oml.runtime.ui,
+   org.eclipse.m2m.tests.qvt.oml,
+   org.eclipse.m2m.tests.qvt.oml.ui",
  org.eclipse.m2m.internal.qvt.oml.runtime.project.config;x-friends:="org.eclipse.m2m.qvt.oml.runtime.ui",
  org.eclipse.m2m.internal.qvt.oml.runtime.resource;x-internal:=true,
  org.eclipse.m2m.internal.qvt.oml.runtime.util;x-friends:="org.eclipse.m2m.qvt.oml.runtime.ui,org.eclipse.m2m.tests.qvt.oml",
diff --git a/plugins/org.eclipse.m2m.qvt.oml.runtime/src/org/eclipse/m2m/internal/qvt/oml/runtime/project/PlatformPluginUnitResolver.java b/plugins/org.eclipse.m2m.qvt.oml.runtime/src/org/eclipse/m2m/internal/qvt/oml/runtime/project/PlatformPluginUnitResolver.java
index d8d883a..ee6da52 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.runtime/src/org/eclipse/m2m/internal/qvt/oml/runtime/project/PlatformPluginUnitResolver.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.runtime/src/org/eclipse/m2m/internal/qvt/oml/runtime/project/PlatformPluginUnitResolver.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2018 Borland Software Corporation and others.
+ * Copyright (c) 2009, 2020 Borland Software Corporation and others.
  * 
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
@@ -8,6 +8,7 @@
  *   
  * Contributors:
  *     Borland Software Corporation - initial API and implementation
+ *     Christopher Gerking - bug 562175
  *******************************************************************************/
 package org.eclipse.m2m.internal.qvt.oml.runtime.project;
 
@@ -45,9 +46,9 @@
  */
 public class PlatformPluginUnitResolver extends DelegatingUnitResolver {
 	
-    private static final String SOURCE_CONTAINER_POINT = QvtRuntimePlugin.ID + ".qvtTransformationContainer"; //$NON-NLS-1$
-    private static final String SOURCE_CONTAINER = "sourceContainer"; //$NON-NLS-1$
-    private static final String CONTAINER_PATH = "path"; //$NON-NLS-1$
+    public static final String SOURCE_CONTAINER_POINT = QvtRuntimePlugin.ID + ".qvtTransformationContainer"; //$NON-NLS-1$
+    public static final String SOURCE_CONTAINER = "sourceContainer"; //$NON-NLS-1$
+    public static final String CONTAINER_PATH = "path"; //$NON-NLS-1$
 	
 	private final Bundle fBundle;
 	private final List<IPath> fSrcContainers;
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.m2m.qvt.oml.ui/META-INF/MANIFEST.MF
index 9559133..ee50053 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.m2m.qvt.oml.ui/META-INF/MANIFEST.MF
@@ -21,6 +21,6 @@
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.m2m.internal.qvt.oml.ui;x-internal:=true,
  org.eclipse.m2m.internal.qvt.oml.ui.wizards;x-internal:=true,
- org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;x-internal:=true
+ org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;x-friends:="org.eclipse.m2m.tests.qvt.oml.ui"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Automatic-Module-Name: org.eclipse.m2m.qvt.oml.ui
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/JdtProjectIntegrationHelper.java b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/JdtProjectIntegrationHelper.java
deleted file mode 100644
index ba947ff..0000000
--- a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/JdtProjectIntegrationHelper.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2018 Borland Software Corporation and others.
- * 
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- * 
- * Contributors:
- *     Borland Software Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
-
-import org.eclipse.core.resources.IProject;
-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.m2m.internal.qvt.oml.ui.QVTUIPlugin;
-import org.eclipse.swt.widgets.Combo;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-
-public class JdtProjectIntegrationHelper {
-	
-	private static final JdtProjectIntegration jdtIntegartion = getJdtProjectIntegration();
-	
-	private static JdtProjectIntegration getJdtProjectIntegration() {
-		try {
-			BundleContext bundleContext = QVTUIPlugin.getDefault().getBundle().getBundleContext();
-			@SuppressWarnings("unchecked")
-			ServiceReference<JdtProjectIntegration> serviceReference =
-				(ServiceReference<JdtProjectIntegration>) bundleContext.getServiceReference(JdtProjectIntegration.class.getName());
-			return serviceReference == null ? null : bundleContext.getService(serviceReference);
-		}
-		catch (Throwable e) {
-			QVTUIPlugin.log(e);
-		}
-		return null;
-	}
-
-
-	static boolean isJdtIntegration() {
-		return jdtIntegartion != null;
-	}
-	
-	static void setupJava(IProject project, boolean isPDE, String sourceFolder, String outFolder, String executionEnv,
-			IProgressMonitor monitor) throws CoreException {
-		
-		if (jdtIntegartion != null) {
-			jdtIntegartion.setupJava(project, isPDE, sourceFolder, outFolder, executionEnv, monitor);
-		}		
-	}
-
-	static String getRequiredExecutionEnv(String executionEnv) {
-		if (jdtIntegartion != null) {
-			return jdtIntegartion.getRequiredExecutionEnv(executionEnv);
-		}
-		return null;
-	}
-
-	static String getClassField(String id, String suffix) {
-		if (jdtIntegartion != null) {
-			return jdtIntegartion.getClassField(id, suffix);
-		}
-		return ""; //$NON-NLS-1$
-	}
-
-	static IStatus validateJavaTypeName(String name) {
-		if (jdtIntegartion != null) {
-			return jdtIntegartion.validateJavaTypeName(name);
-		}
-		return Status.OK_STATUS;
-	}
-
-	static void fillExecutionEnvironments(Combo combo) {
-		if (jdtIntegartion != null) {
-			jdtIntegartion.fillExecutionEnvironments(combo);
-		}
-	}
-
-}
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewProjectCreationOperation.java b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewProjectCreationOperation.java
index ca76bf9..1f28218 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewProjectCreationOperation.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewProjectCreationOperation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2019 Borland Software Corporation and others.
+ * Copyright (c) 2009, 2020 Borland Software Corporation and others.
  * 
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
@@ -8,22 +8,15 @@
  * 
  * Contributors:
  *     Borland Software Corporation - initial API and implementation
- *     Christopher Gerking - bugs 319078, 414662, 536601
+ *     Christopher Gerking - bugs 319078, 414662, 536601, 562175
  *******************************************************************************/
 package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.UnsupportedEncodingException;
 import java.lang.reflect.InvocationTargetException;
 import java.net.URI;
-import java.util.Arrays;
 
 import org.eclipse.core.filesystem.URIUtil;
 import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
@@ -31,23 +24,14 @@
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.SubMonitor;
-import org.eclipse.m2m.internal.qvt.oml.ui.QVTUIPlugin;
+import org.eclipse.m2m.internal.qvt.oml.project.builder.QVTOBuilderConfig;
 import org.eclipse.ui.actions.WorkspaceModifyOperation;
 
-class NewProjectCreationOperation extends WorkspaceModifyOperation {
-
-	private static final String BUILD_FILENAME_DESCRIPTOR = "build.properties"; //$NON-NLS-1$
-	
-	private static final String PLUGIN_NATURE = "org.eclipse.pde.PluginNature"; //$NON-NLS-1$
-	
+public class NewProjectCreationOperation extends WorkspaceModifyOperation {
 		
 	// instance fields
-	private PluginClassCodeGenerator fGenerator;	
-	
 	private NewProjectData fData;
 	
 	private IProject fProjectHandle; 
@@ -62,104 +46,32 @@
 		fProjectHandle = projectHandle;
 	}
 	
-	protected void createContents(IProgressMonitor monitor, IProject project) throws CoreException, InterruptedException {
-		SubMonitor.done(monitor);
+	protected void createContents(IProgressMonitor monitor, IProject project) throws CoreException, InterruptedException {		
+		try {
+			SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.NewQVTProjectWizard_Create, 2);
+		
+	    	IContainer srcContainer = project.getFolder(fData.getQVTSourceFolderName());
+	    	if(srcContainer instanceof IFolder) {
+	        	SourceContainerUpdater.ensureDestinationExists((IFolder) srcContainer, subMonitor.split(1));
+	    	}
+	
+	    	QVTOBuilderConfig qvtConfig = QVTOBuilderConfig.getConfig(project);
+	    	qvtConfig.setSourceContainer(srcContainer);
+	    	qvtConfig.addTransformationNature();
+	    	
+	    	subMonitor.worked(1);
+		} finally {
+			SubMonitor.done(monitor);
+		}
 	}
 	
-	private void createBuildProperties(IProject project, IProgressMonitor monitor) throws CoreException {
-		
-		SubMonitor subMonitor = SubMonitor.convert(monitor, 4);
-		
-		IFile buildProperties = project.getFile(BUILD_FILENAME_DESCRIPTOR);
-		StringWriter contents = new StringWriter();
-		PrintWriter wr = new PrintWriter(contents, true);
-		
-		if(fData.isCreateJava()) {
-			IPath sourceFolder = asBinIncludesFolder(createJavaFolder(fData.getSourceFolderName(), subMonitor.split(1)));
-			IPath outFolder = asBinIncludesFolder(createJavaFolder(fData.getOutFolderName(), subMonitor.split(1)));
-
-			wr.append("source.. = ").println(sourceFolder.toString()); //$NON-NLS-1$
-			wr.append("output.. = ").println(outFolder.toString()); //$NON-NLS-1$
-		}
-
-		char[] alignChars = new char[15];
-		Arrays.fill(alignChars, ' ');
-		String indent = new String(alignChars);
-		
-		wr.print("bin.includes = META-INF/"); //$NON-NLS-1$
-		if(fData.isCreateJava()) {
-			wr.println(",\\"); //$NON-NLS-1$
-			wr.append(indent).append('.');
-		}
-
-		IContainer qvtContainer = createJavaFolder(fData.getQVTSourceFolderName(), subMonitor.split(1));
-		IPath qvtFolder = asBinIncludesFolder(qvtContainer);
-		if(!fProjectHandle.equals(qvtContainer) || !fData.isCreateJava()) {
-			wr.println(",\\"); //$NON-NLS-1$
-			wr.append(indent).append(qvtFolder.toString());
-		}
-
-		wr.println();
-		wr.flush();
-		
-		InputStream is = createContentStreamForNewFile(buildProperties, contents.getBuffer().toString());
-		buildProperties.create(is, false, subMonitor.split(1));
-	}
-
-	private void createManifest(IFolder metaFolder, IProgressMonitor monitor) throws CoreException {
-		IFile manifest = metaFolder.getFile("MANIFEST.MF"); //$NON-NLS-1$
-		StringWriter contents = new StringWriter();
-		PrintWriter wr = new PrintWriter(contents, true);
-
-		wr.println("Manifest-Version: 1.0"); //$NON-NLS-1$
-		wr.println("Bundle-ManifestVersion: 2"); //$NON-NLS-1$
-		wr.append("Bundle-Name: ").println(fData.getName()); //$NON-NLS-1$
-		wr.append("Bundle-SymbolicName: ").println(fData.getID()); //$NON-NLS-1$
-		wr.append("Bundle-Version: ").println(fData.getVersion()); //$NON-NLS-1$
-		if (fData.isDoGenerateClass() && fData.getClassName().length() > 0) {
-			wr.append("Bundle-Activator: ").println(fData.getClassName()); //$NON-NLS-1$
-		}
-		if (fData.getProviderName().length() > 0) {
-			wr.append("Bundle-Vendor: ").println(fData.getProviderName()); //$NON-NLS-1$
-		}
-
-		PluginReference[] dependencies = getDependencies();
-		if (dependencies.length > 0) {
-			wr.append("Require-Bundle:"); //$NON-NLS-1$
-
-			int i = 0;
-			for (PluginReference pluginReference : dependencies) {
-				if (i++ > 0) {
-					wr.println(',');
-				}
-				wr.append(' ');
-				wr.append(pluginReference.getId());
-			}
-			wr.println();
-		}
-
-		if (fData.isCreateJava()) {
-			String requiredEnv = JdtProjectIntegrationHelper.getRequiredExecutionEnv(fData.getfExecutionEnv());
-			if (requiredEnv != null) {
-				wr.println(requiredEnv);
-			}
-		}
-		
-		wr.println("Bundle-ActivationPolicy: lazy"); //$NON-NLS-1$
-
-		wr.flush();
-
-		InputStream is = createContentStreamForNewFile(manifest, contents.getBuffer().toString());
-		manifest.create(is, false, monitor);
-	}
-
 	/*
 	 * (non-Javadoc)
 	 * 
 	 * @see org.eclipse.ui.actions.WorkspaceModifyOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
 	 */
 	@Override
-	protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
+	public void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
 		SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.NewProjectCreationOperation_createQVTProjectTask, 2);
 				
 		try {
@@ -170,129 +82,32 @@
 			SubMonitor.done(monitor);
 		}
 	}
-
-
-	private void generateTopLevelPluginClass(IProgressMonitor monitor) throws CoreException {
-		fGenerator.generate(monitor);
-	}
-
-	private PluginReference[] getDependencies() {
-		if (fGenerator == null) {
-			return new PluginReference[0];
-		}
-		return fGenerator.getDependencies();
-	}
 	
 	private void createProject(IProgressMonitor monitor) throws CoreException {
 		
-		// compute total amount of work
-		int totalWork = 2;
-		totalWork += fData.isPlugin() ? 4 : 0;
-		totalWork += fData.isCreateJava() ? 2 : 0;
-		
-        SubMonitor subMonitor = SubMonitor.convert(monitor, totalWork);
-		
-        URI location = URIUtil.toURI(fData.getLocation());
-
-		IWorkspace workspace = ResourcesPlugin.getWorkspace();
-		final IProjectDescription description = workspace.newProjectDescription(fProjectHandle.getName());
-		if (location != null && ResourcesPlugin.getWorkspace().getRoot().getLocationURI().equals(location)) {
-			location = null;
-		}
-		description.setLocationURI(location); 
-						
-		if(!fProjectHandle.exists()) {
-			fProjectHandle.create(description, subMonitor.split(1));
-		}
-		subMonitor.setWorkRemaining(totalWork - 1);
-
-        fProjectHandle.open(IResource.BACKGROUND_REFRESH, subMonitor.split(1));
-        
-        if (fData.isPlugin()) {
-			addNatureToProject(fProjectHandle, PLUGIN_NATURE, subMonitor.split(1));
+		try {
+	        SubMonitor subMonitor = SubMonitor.convert(monitor, 3);
 			
-			fGenerator = new PluginClassCodeGenerator(fProjectHandle, fData);
-        }
-        			
-		if(fData.isCreateJava()) {
-			JdtProjectIntegrationHelper.setupJava(fProjectHandle, true, 
-					fData.getSourceFolderName(), fData.getOutFolderName(), fData.getfExecutionEnv(), subMonitor.split(1));
-
-			if(fData.isDoGenerateClass()) {
-				generateTopLevelPluginClass(subMonitor.split(1));
-			}	
-		}
-					
-		if (fData.isPlugin()) {
-			// generate the manifest file
-			IFolder metaFolder = fProjectHandle.getFolder("META-INF"); //$NON-NLS-1$
-			metaFolder.create(true, true, subMonitor.split(1));
-
-			createManifest(metaFolder, subMonitor.split(1));
-			
-			// generate the build.properties file
-			createBuildProperties(fProjectHandle, subMonitor.split(1));
-
-		}
-	}
-
-	private void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException {
-		IProjectDescription description = proj.getDescription();
-		String[] prevNatures = description.getNatureIds();
-		String[] newNatures = new String[prevNatures.length + 1];
-		System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
-		newNatures[prevNatures.length] = natureId;
-		description.setNatureIds(newNatures);
-		proj.setDescription(description, monitor);
-	}
+	        URI location = URIUtil.toURI(fData.getLocation());
 	
-	private InputStream createContentStreamForNewFile(IFile fileHandle, String contents) {
-		String charset = null;
-		try {
-			charset = fileHandle.getProject().getDefaultCharset();
-		} catch (CoreException e) {
-			QVTUIPlugin.log(e.getStatus());
-		}
-
-		if(charset == null) {
-			charset = ResourcesPlugin.getEncoding();
-		}
-
-		byte[] bytes;
-		try {
-			bytes = contents.getBytes(charset);
-		} catch (UnsupportedEncodingException e) {
-			bytes = contents.getBytes();	
-		}
-		
-		return new ByteArrayInputStream(bytes);
-	}
-	
-	private IPath asBinIncludesFolder(IContainer container) {
-		if(container.equals(fProjectHandle)) {
-			return new Path("."); //$NON-NLS-1$
-		}
-		IPath result = container.getProjectRelativePath();   
-		while(result.hasTrailingSeparator()) {
-			result = result.removeTrailingSeparator();
-		}
-		// ensure single trailing slash
-		return result.addTrailingSeparator(); 
-	}
-	
-	private IContainer createJavaFolder(String folderName, IProgressMonitor monitor) throws CoreException {
-		try {
-			if(folderName == null || folderName.trim().length() == 0) {
-				return fProjectHandle;			
+			IWorkspace workspace = ResourcesPlugin.getWorkspace();
+			final IProjectDescription description = workspace.newProjectDescription(fProjectHandle.getName());
+			if (location != null && ResourcesPlugin.getWorkspace().getRoot().getLocationURI().equals(location)) {
+				location = null;
 			}
-			
-			IFolder folder = fProjectHandle.getFolder(folderName);
-			if(!folder.exists()) {
-				folder.create(true, true, monitor);
+			description.setLocationURI(location); 
+							
+			if(!fProjectHandle.exists()) {
+				fProjectHandle.create(description, subMonitor.split(1));
 			}
-			return folder;
+			subMonitor.setWorkRemaining(2);
+	
+	        fProjectHandle.open(IResource.BACKGROUND_REFRESH, subMonitor.split(1));
+	                			
+			ProjectIntegrationHelper.setupProject(fProjectHandle, fData, subMonitor.split(1));
 		} finally {
 			SubMonitor.done(monitor);
 		}
-	}	
+	}
+	
 }
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewProjectData.java b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewProjectData.java
index 401501b..9779936 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewProjectData.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewProjectData.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2018 Borland Software Corporation and others.
+ * Copyright (c) 2009, 2020 Borland Software Corporation and others.
  * 
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
@@ -8,13 +8,13 @@
  * 
  * Contributors:
  *     Borland Software Corporation - initial API and implementation
- *     Christopher Gerking - bug 319078
+ *     Christopher Gerking - bugs 319078, 562175
  *******************************************************************************/
 package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
 
 import org.eclipse.core.runtime.IPath;
 
-class NewProjectData {	
+public class NewProjectData {	
 
 	private String fName;
 	
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectContentPage.java b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectContentPage.java
index 9837d80..edbf77a 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectContentPage.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectContentPage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2018 Borland Software Corporation and others.
+ * Copyright (c) 2007, 2020 Borland Software Corporation and others.
  * 
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
@@ -8,6 +8,7 @@
  * 
  * Contributors:
  *     Borland Software Corporation - initial API and implementation
+ *     Christopher Gerking - bug 562175
  *******************************************************************************/
 package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
 
@@ -128,10 +129,10 @@
 		myExecEnvLabel.setText(Messages.ContentPage_executionenv); 
 		myExecEnvCombo = createCombo(propertiesGroup, SWT.READ_ONLY | SWT.BORDER, 1);
 		
-		myExecEnvLabel.setEnabled(JdtProjectIntegrationHelper.isJdtIntegration());
-		myExecEnvCombo.setEnabled(JdtProjectIntegrationHelper.isJdtIntegration());
+		myExecEnvLabel.setEnabled(ProjectIntegrationHelper.isProjectIntegration());
+		myExecEnvCombo.setEnabled(ProjectIntegrationHelper.isProjectIntegration());
 		
-		JdtProjectIntegrationHelper.fillExecutionEnvironments(myExecEnvCombo);
+		ProjectIntegrationHelper.fillExecutionEnvironments(myExecEnvCombo);
 	}
 
 	private void createPluginClassGroup(Composite container) {
@@ -226,7 +227,7 @@
 		String errorMessage = validateProperties();
 
 		if (errorMessage == null && myGenerateClass.isEnabled() && myGenerateClass.getSelection()) {
-			IStatus status = JdtProjectIntegrationHelper.validateJavaTypeName(myClassText.getText());
+			IStatus status = ProjectIntegrationHelper.validateJavaTypeName(myClassText.getText());
 			if (status.getSeverity() == IStatus.ERROR) {
 				errorMessage = status.getMessage();
 			} else if (status.getSeverity() == IStatus.WARNING) {
@@ -293,7 +294,7 @@
 			}
 			if ((myChangedGroups & CLASS_GROUP) == 0) {
 				int oldChanged = myChangedGroups;
-				String clsField = JdtProjectIntegrationHelper.getClassField(computeId(), "Activator"); //$NON-NLS-1$
+				String clsField = ProjectIntegrationHelper.getClassField(computeId(), "Activator"); //$NON-NLS-1$
 				myClassText.setText(clsField);
 				myChangedGroups = oldChanged;
 			}
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectCreationPage.java b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectCreationPage.java
index 7bf9db1..558b857 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectCreationPage.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectCreationPage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2018 Borland Software Corporation and others.
+ * Copyright (c) 2007, 2020 Borland Software Corporation and others.
  * 
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
@@ -8,7 +8,7 @@
  * 
  * Contributors:
  *     Borland Software Corporation - initial API and implementation
- *     Christopher Gerking - bug 319078
+ *     Christopher Gerking - bugs 319078, 562175
  *******************************************************************************/
 package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
 
@@ -193,7 +193,7 @@
 		fSimplePlugin.setLayoutData(gd);
 		
 		// select simple plugin type by default
-		if (JdtProjectIntegrationHelper.isJdtIntegration()) {
+		if (ProjectIntegrationHelper.isProjectIntegration()) {
 			fSimplePlugin.setSelection(true);
 		}
 		else {
@@ -212,7 +212,7 @@
         
         fJavaPlugin.setLayoutData(gd);
         
-        fJavaPlugin.setEnabled(JdtProjectIntegrationHelper.isJdtIntegration());
+        fJavaPlugin.setEnabled(ProjectIntegrationHelper.isProjectIntegration());
         
         fJavaSettingsGroup = new Group(projectTypeGroup, SWT.NONE);
         fJavaSettingsGroup.setText(Messages.ProjectStructurePage_JavaProjectSettings); 
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectWizard.java b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectWizard.java
index 29d470b..aaa34f0 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectWizard.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/NewQVTProjectWizard.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2019 Borland Software Corporation and others.
+ * Copyright (c) 2007, 2020 Borland Software Corporation and others.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
@@ -8,28 +8,23 @@
  *
  * Contributors:
  *     Borland Software Corporation - initial API and implementation
- *     Christopher Gerking - bugs 319078, 536601
+ *     Christopher Gerking - bugs 319078, 536601, 562175
  *******************************************************************************/
 package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
 
 import java.lang.reflect.InvocationTargetException;
 
 import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExecutableExtension;
-import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubMonitor;
 import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.wizard.IWizardPage;
 import org.eclipse.jface.wizard.Wizard;
 import org.eclipse.jface.wizard.WizardSelectionPage;
-import org.eclipse.m2m.internal.qvt.oml.project.builder.QVTOBuilderConfig;
 import org.eclipse.m2m.internal.qvt.oml.ui.QVTUIPlugin;
 import org.eclipse.m2m.internal.qvt.oml.ui.QvtPluginImages;
 import org.eclipse.ui.INewWizard;
@@ -113,12 +108,7 @@
 	}
 
 	private WorkspaceModifyOperation createNewProjectOperation() {
-		return new NewProjectCreationOperation(fMainPage.getProjectHandle(), fProjectData) {
-			@Override
-			protected void createContents(IProgressMonitor monitor, IProject project) throws CoreException, InterruptedException {
-				doPostCreateProjectAction(project, monitor);
-			}
-		};
+		return new NewProjectCreationOperation(fMainPage.getProjectHandle(), fProjectData);
 	}
 
 	@Override
@@ -160,22 +150,6 @@
         return true;
 	}
 
-
-    private void doPostCreateProjectAction(IProject createdProject, IProgressMonitor monitor) throws CoreException {
-    	SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.NewQVTProjectWizard_Create, 2);
-
-    	IContainer srcContainer = fMainPage.getQVTSourceContainerHandle();
-    	if(srcContainer instanceof IFolder) {
-        	SourceContainerUpdater.ensureDestinationExists((IFolder)srcContainer, subMonitor.split(1));
-    	}
-
-    	QVTOBuilderConfig qvtConfig = QVTOBuilderConfig.getConfig(createdProject);
-    	qvtConfig.setSourceContainer(srcContainer);
-    	qvtConfig.addTransformationNature();
-
-    	subMonitor.worked(1);
-    }
-
     private INewQVTElementDestinationWizardDelegate getDestinationProvider() {
     	assert fMainPage != null;
 
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/PluginClassCodeGenerator.java b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/PluginClassCodeGenerator.java
index 5c57215..9c6ad04 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/PluginClassCodeGenerator.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/PluginClassCodeGenerator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009,2018 Borland Software Corporation and others.
+ * Copyright (c) 2009, 2020 Borland Software Corporation and others.
  * 
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
@@ -8,7 +8,7 @@
  * 
  * Contributors:
  *     Borland Software Corporation - initial API and implementation
- *     Christopher Gerking - bug 414662
+ *     Christopher Gerking - bugs 414662, 562175
  *******************************************************************************/
 package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
 
@@ -31,6 +31,11 @@
 import org.eclipse.m2m.internal.qvt.oml.compiler.UnitProxy;
 import org.eclipse.m2m.internal.qvt.oml.ui.QVTUIPlugin;
 
+/**
+ * @deprecated as per bug 562175. 
+ * Use {@link org.eclipse.pde.internal.ui.wizards.plugin.PluginClassCodeGenerator} instead.
+ */
+@Deprecated
 class PluginClassCodeGenerator {
 	
 	private final IProject fProject;
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/JdtProjectIntegration.java b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/ProjectIntegration.java
similarity index 79%
rename from plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/JdtProjectIntegration.java
rename to plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/ProjectIntegration.java
index 38213a0..0892d28 100644
--- a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/JdtProjectIntegration.java
+++ b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/ProjectIntegration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2018 Borland Software Corporation and others.
+ * Copyright (c) 2009, 2020 Borland Software Corporation and others.
  * 
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v2.0
@@ -8,6 +8,7 @@
  * 
  * Contributors:
  *     Borland Software Corporation - initial API and implementation
+ *     Christopher Gerking - bug 562175
  *******************************************************************************/
 package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
 
@@ -17,10 +18,10 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.swt.widgets.Combo;
 
-public interface JdtProjectIntegration {
+public interface ProjectIntegration {
 
-	void setupJava(IProject project, boolean isPDE, String sourceFolder, String outFolder, String executionEnv, IProgressMonitor monitor) throws CoreException;		
-
+	void setupProject(IProject project, NewProjectData data, IProgressMonitor monitor) throws CoreException;		
+	
 	String getRequiredExecutionEnv(String executionEnv);
 	
 	String getClassField(String id, String suffix);
diff --git a/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/ProjectIntegrationHelper.java b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/ProjectIntegrationHelper.java
new file mode 100644
index 0000000..d53c1dd
--- /dev/null
+++ b/plugins/org.eclipse.m2m.qvt.oml.ui/src/org/eclipse/m2m/internal/qvt/oml/ui/wizards/project/ProjectIntegrationHelper.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2020 Borland Software Corporation and others.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * 
+ * Contributors:
+ *     Borland Software Corporation - initial API and implementation
+ *     Christopher Gerking - bug 562175
+ *******************************************************************************/
+package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
+
+import org.eclipse.core.resources.IProject;
+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.m2m.internal.qvt.oml.ui.QVTUIPlugin;
+import org.eclipse.swt.widgets.Combo;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class ProjectIntegrationHelper {
+	
+	private static final ProjectIntegration projectIntegration = getProjectIntegration();
+	
+	private static ProjectIntegration getProjectIntegration() {
+		try {
+			BundleContext bundleContext = QVTUIPlugin.getDefault().getBundle().getBundleContext();
+			@SuppressWarnings("unchecked")
+			ServiceReference<ProjectIntegration> serviceReference =
+				(ServiceReference<ProjectIntegration>) bundleContext.getServiceReference(ProjectIntegration.class.getName());
+			return serviceReference == null ? null : bundleContext.getService(serviceReference);
+		}
+		catch (Throwable e) {
+			QVTUIPlugin.log(e);
+		}
+		return null;
+	}
+
+
+	static boolean isProjectIntegration() {
+		return projectIntegration != null;
+	}
+	
+	static void setupProject(IProject project, NewProjectData data, IProgressMonitor monitor) throws CoreException {
+		
+		if (projectIntegration != null) {
+			projectIntegration.setupProject(project, data, monitor);
+		}		
+	}
+
+	static String getRequiredExecutionEnv(String executionEnv) {
+		if (projectIntegration != null) {
+			return projectIntegration.getRequiredExecutionEnv(executionEnv);
+		}
+		return null;
+	}
+
+	static String getClassField(String id, String suffix) {
+		if (projectIntegration != null) {
+			return projectIntegration.getClassField(id, suffix);
+		}
+		return ""; //$NON-NLS-1$
+	}
+
+	static IStatus validateJavaTypeName(String name) {
+		if (projectIntegration != null) {
+			return projectIntegration.validateJavaTypeName(name);
+		}
+		return Status.OK_STATUS;
+	}
+
+	static void fillExecutionEnvironments(Combo combo) {
+		if (projectIntegration != null) {
+			projectIntegration.fillExecutionEnvironments(combo);
+		}
+	}
+
+}