Apply changes made in CVS HEAD
diff --git a/p2/publishing/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/ArtifactLockingTest.java b/p2/publishing/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/ArtifactLockingTest.java
index 9aab0ae..6856f31 100644
--- a/p2/publishing/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/ArtifactLockingTest.java
+++ b/p2/publishing/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/artifact/repository/ArtifactLockingTest.java
@@ -31,7 +31,7 @@
 
 	boolean canContinue = false;
 
-	public void testCancelLoad() throws InterruptedException, ProvisionException {
+	public void _testCancelLoad() throws InterruptedException, ProvisionException {
 		this.canContinue = false;
 		final IProgressMonitor progressMonitor = new NullProgressMonitor();
 		new Thread(new Runnable() {
@@ -68,7 +68,7 @@
 
 	}
 
-	public void testWaitForLoad() throws InterruptedException, ProvisionException {
+	public void _testWaitForLoad() throws InterruptedException, ProvisionException {
 		this.canContinue = false;
 		new Thread(new Runnable() {
 			public void run() {
@@ -107,7 +107,7 @@
 	 * that the block terminates.
 	 * @throws InterruptedException
 	 */
-	public void testCancel() throws InterruptedException {
+	public void _testCancel() throws InterruptedException {
 		final IProgressMonitor progressMonitor = new NullProgressMonitor();
 		this.keepRunning = true;
 
@@ -223,7 +223,7 @@
 	 * parallel, but rather, the second one waits for the first to complete.
 	 * @throws InterruptedException
 	 */
-	public void testMultipleExecuteBatch() throws InterruptedException {
+	public void _testMultipleExecuteBatch() throws InterruptedException {
 		this.lockAcquired = false;
 		Thread t1 = new Thread(new Runnable() {
 			public void run() {
diff --git a/p2/publishing/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/Bug301446.java b/p2/publishing/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/Bug301446.java
new file mode 100644
index 0000000..f7e19f5
--- /dev/null
+++ b/p2/publishing/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/planner/Bug301446.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ *  Copyright (c) 2011 IBM Corporation and others.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ * 
+ *  Contributors:
+ *      IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.tests.planner;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.p2.engine.*;
+import org.eclipse.equinox.p2.engine.IProvisioningPlan;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.Version;
+import org.eclipse.equinox.p2.planner.IPlanner;
+import org.eclipse.equinox.p2.planner.IProfileChangeRequest;
+import org.eclipse.equinox.p2.query.IQueryResult;
+import org.eclipse.equinox.p2.query.QueryUtil;
+
+public class Bug301446 extends AbstractPlannerTest {
+
+	static final Map EXPECTED_VERSIONS = new HashMap();
+	static {
+		EXPECTED_VERSIONS.put("com.ibm.commerce.toolkit.internal.common", Version.create("7.0.0.1"));
+		EXPECTED_VERSIONS.put("com.ibm.commerce.toolkit.internal.dataaccess", Version.create("7.0.0.1"));
+		EXPECTED_VERSIONS.put("com.ibm.commerce.toolkit.internal.feature.enablement", Version.create("7.0.0.5"));
+		EXPECTED_VERSIONS.put("com.ibm.commerce.toolkit.internal.openlaszlo", Version.create("7.0.0.6"));
+		EXPECTED_VERSIONS.put("com.ibm.commerce.toolkit.internal.openlaszlo.migration", Version.create("7.0.2.0"));
+		EXPECTED_VERSIONS.put("com.ibm.commerce.toolkit.internal.openlaszlo.migration.validation", Version.create("7.0.2.0"));
+		EXPECTED_VERSIONS.put("com.ibm.commerce.toolkit.internal.plugin", Version.create("7.0.0.7"));
+	}
+
+	// path to our data
+	protected String getTestDataPath() {
+		return "testData/bug301446";
+	}
+
+	// profile id
+	protected String getProfileId() {
+		return "bootProfile";
+	}
+
+	public void testInstall() {
+		IPlanner planner = createPlanner();
+
+		// create the actual plan - install everything in the repo as optional (mimic the dropins folder)
+		IQueryResult allIUs = repo.query(QueryUtil.createIUAnyQuery(), new NullProgressMonitor());
+		IProfileChangeRequest actualChangeRequest = createProfileChangeRequest(allIUs.toSet(), null, null);
+		// TODO: verify that we are going to try and install the highest version of everything
+		IProvisioningPlan actualPlan = planner.getProvisioningPlan(actualChangeRequest, null, new NullProgressMonitor());
+
+		// this is the plan that we expect - highest version only
+		Operand[] operands = ((ProvisioningPlan) actualPlan).getOperands();
+		for (int i = 0; i < operands.length; i++) {
+			Operand o = operands[i];
+			if (!(o instanceof InstallableUnitOperand))
+				continue;
+			IInstallableUnit iu = ((InstallableUnitOperand) o).second();
+			if (iu == null) {
+				// we are un-installing an IU, is it interesting?
+				iu = ((InstallableUnitOperand) o).first();
+				Version expected = (Version) EXPECTED_VERSIONS.get(iu.getId());
+				if (expected == null)
+					continue;
+				Version actual = iu.getVersion();
+				assertFalse("Removing IU: " + iu.getId() + " Version: " + expected, actual.equals(expected));
+				continue;
+			}
+			// we are installing an IU
+			Version expected = (Version) EXPECTED_VERSIONS.get(iu.getId());
+			if (expected == null)
+				continue;
+			Version actual = iu.getVersion();
+			assertTrue("Adding IU: " + iu.getId() + " Actual: " + actual + " Expected: " + expected, actual.equals(expected));
+		}
+	}
+
+}
diff --git a/p2/publishing/org.eclipse.equinox.p2.tests/testData/bug301446/p2/org.eclipse.equinox.p2.engine/profileRegistry/bootProfile.profile/1297370265829.profile.gz b/p2/publishing/org.eclipse.equinox.p2.tests/testData/bug301446/p2/org.eclipse.equinox.p2.engine/profileRegistry/bootProfile.profile/1297370265829.profile.gz
new file mode 100644
index 0000000..67203fa
--- /dev/null
+++ b/p2/publishing/org.eclipse.equinox.p2.tests/testData/bug301446/p2/org.eclipse.equinox.p2.engine/profileRegistry/bootProfile.profile/1297370265829.profile.gz
Binary files differ
diff --git a/p2/publishing/org.eclipse.equinox.p2.tests/testData/bug301446/repo/content.jar b/p2/publishing/org.eclipse.equinox.p2.tests/testData/bug301446/repo/content.jar
new file mode 100644
index 0000000..08dc747
--- /dev/null
+++ b/p2/publishing/org.eclipse.equinox.p2.tests/testData/bug301446/repo/content.jar
Binary files differ
diff --git a/p2/publishing/org.eclipse.pde.build.tests/src/org/eclipse/pde/build/internal/tests/p2/PublishingTests.java b/p2/publishing/org.eclipse.pde.build.tests/src/org/eclipse/pde/build/internal/tests/p2/PublishingTests.java
index 5012625..ce8e97a 100755
--- a/p2/publishing/org.eclipse.pde.build.tests/src/org/eclipse/pde/build/internal/tests/p2/PublishingTests.java
+++ b/p2/publishing/org.eclipse.pde.build.tests/src/org/eclipse/pde/build/internal/tests/p2/PublishingTests.java
@@ -1987,4 +1987,49 @@
 		assertZipPermissions(zip, "eclipse/meToo.txt", "-rwxr-xr-x");
 		assertZipPermissions(zip, "eclipse/file.txt", "-rwxr-xr-x");
 	}
+
+	public void testBug329162() throws Exception {
+		IFolder buildFolder = newTest("329162");
+
+		IFolder bundle = Utils.createFolder(buildFolder, "plugins/bundle");
+		Utils.writeBuffer(bundle.getFile("src/A.java"), new StringBuffer("import b.B; public class A { B b = new B(); public void Bar(){}}"));
+		Utils.writeBuffer(bundle.getFile("src/b/B.java"), new StringBuffer("package b; public class B { public int i = 0; public void Foo(){}}"));
+		Utils.generateBundle(bundle, "bundle");
+
+		Utils.generateFeature(buildFolder, "F", null, new String[] {"bundle", "org.eclipse.osgi"});
+
+		IFolder templateFolder = Utils.createFolder(buildFolder, "features/template");
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("<feature id=\"template\" label=\"FooSource\" version=\"1.0.0.v123\">		\n");
+		buffer.append(" <description>generated source</description>		\n");
+		buffer.append("</feature>											\n");
+		Utils.writeBuffer(templateFolder.getFile("feature.xml"), buffer);
+		IFolder sourceTemplate = Utils.createFolder(templateFolder, "sourceTemplateFeature");
+		buffer = new StringBuffer();
+		buffer.append("requires.0.namespace=org.eclipse.equinox.p2.iu	\n");
+		buffer.append("requires.0.name=testid0							\n");
+		buffer.append("requires.0.range=[1.2.3,1.3)						\n");
+		Utils.writeBuffer(sourceTemplate.getFile("p2.inf"), buffer);
+
+		Properties properties = BuildConfiguration.getBuilderProperties(buildFolder);
+		properties.put("topLevelElementId", "F");
+		properties.put("p2.gathering", "true");
+		properties.put("sourceBundleMode", "all");
+		properties.put("sourceBundleTemplateFeature", "template");
+		properties.put("sourceBundleFeatureVersion", "1.0.0.v123");
+		properties.put("individualSourceBundles", "true");
+		Utils.storeBuildProperties(buildFolder, properties);
+		runBuild(buildFolder);
+
+		IMetadataRepository repo = loadMetadataRepository(buildFolder.getFolder("buildRepo").getLocationURI());
+		IInstallableUnit iu = getIU(repo, "template.source.feature.group");
+		assertRequires(iu, P2InfUtils.NAMESPACE_IU, "bundle.source");
+		assertRequires(iu, P2InfUtils.NAMESPACE_IU, "org.eclipse.osgi.source");
+		assertRequires(iu, P2InfUtils.NAMESPACE_IU, "testid0");
+		assertEquals(iu.getProperty("org.eclipse.equinox.p2.name"), "FooSource");
+		assertEquals(iu.getProperty("org.eclipse.equinox.p2.description"), "generated source");
+
+		getIU(repo, "org.eclipse.osgi.source");
+		getIU(repo, "bundle.source");
+	}
 }
diff --git a/p2/publishing/org.eclipse.pde.build/scripts/genericTargets.xml b/p2/publishing/org.eclipse.pde.build/scripts/genericTargets.xml
index 351a026..0021191 100755
--- a/p2/publishing/org.eclipse.pde.build/scripts/genericTargets.xml
+++ b/p2/publishing/org.eclipse.pde.build/scripts/genericTargets.xml
@@ -104,6 +104,10 @@
 		parallelThreadsPerProcessor="${parallelThreadsPerProcessor}"
 		customEESources="${customEESources}"
 		contextRepository="${transformedRepoLocation},${p2.context.repos}"
+		sourceBundleMode="${sourceBundleMode}"
+		sourceBundleTemplateFeature="${sourceBundleTemplateFeature}"
+		sourceBundleFeatureId="${sourceBundleFeatureId}"
+		sourceBundleFeatureVersion="${sourceBundleFeatureVersion}"
 	/>
 </target>
 
diff --git a/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AbstractScriptGenerator.java b/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AbstractScriptGenerator.java
index c9439f4..744c6fc 100755
--- a/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AbstractScriptGenerator.java
+++ b/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AbstractScriptGenerator.java
@@ -199,6 +199,14 @@
 	}
 
 	public static Properties readProperties(String location, String fileName, int errorLevel) throws CoreException {
+		if (location == null) {
+			if (errorLevel != IStatus.INFO && errorLevel != IStatus.OK) {
+				String message = NLS.bind(Messages.exception_missingFile, fileName);
+				BundleHelper.getDefault().getLog().log(new Status(errorLevel, PI_PDEBUILD, EXCEPTION_READING_FILE, message, null));
+			}
+			return MissingProperties.getInstance();
+		}
+
 		Properties result = new Properties();
 		File file = new File(location, fileName);
 		try {
diff --git a/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AssembleConfigScriptGenerator.java b/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AssembleConfigScriptGenerator.java
index bf24353..4887577 100755
--- a/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AssembleConfigScriptGenerator.java
+++ b/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AssembleConfigScriptGenerator.java
@@ -323,8 +323,18 @@
 	protected void generateCleanupAssembly(boolean assembling) {
 		String condition = (assembling && BuildDirector.p2Gathering) ? PROPERTY_RUN_PACKAGER : null;
 		script.printTargetDeclaration(TARGET_CLEANUP_ASSEMBLY, null, null, condition, null);
-		if (!FORMAT_FOLDER.equalsIgnoreCase(archiveFormat))
-			script.printDeleteTask(Utils.getPropertyFormat(PROPERTY_ASSEMBLY_TMP), null, null);
+
+		if (!FORMAT_FOLDER.equalsIgnoreCase(archiveFormat)) {
+			script.printAvailableTask(PROPERTY_ASSEMBLY_TMP + ".exists", Utils.getPropertyFormat(PROPERTY_ASSEMBLY_TMP)); //$NON-NLS-1$
+			script.printAntCallTask("_" + TARGET_CLEANUP_ASSEMBLY, true, null); //$NON-NLS-1$
+			script.printTargetEnd();
+
+			script.printTargetDeclaration("_" + TARGET_CLEANUP_ASSEMBLY, null, PROPERTY_ASSEMBLY_TMP + ".exists", null, null); //$NON-NLS-1$//$NON-NLS-2$
+			String toDir = Utils.getPropertyFormat(PROPERTY_ASSEMBLY_TMP) + "." + configInfo.toStringReplacingAny(".", ANY_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+			FileSet fromDir = new FileSet(Utils.getPropertyFormat(PROPERTY_ASSEMBLY_TMP), null, null, null, null, null, null);
+			script.printMoveTask(toDir, new FileSet[] {fromDir}, true);
+			script.printDeleteTask(toDir, null, TRUE, null);
+		}
 		script.printTargetEnd();
 		script.println();
 	}
diff --git a/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AssemblyInformation.java b/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AssemblyInformation.java
index ff3b380..6d71cd3 100755
--- a/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AssemblyInformation.java
+++ b/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/AssemblyInformation.java
@@ -67,6 +67,16 @@
 		return ((AssemblyLevelConfigInfo) assembleInformation.get(config)).getPlugins();
 	}
 
+	public Set getAllPlugins() {
+		Collection pluginsByConfig = assembleInformation.values();
+		Set result = new LinkedHashSet();
+		for (Iterator iter = pluginsByConfig.iterator(); iter.hasNext();) {
+			Collection allPlugins = ((AssemblyLevelConfigInfo) iter.next()).getPlugins();
+			result.addAll(allPlugins);
+		}
+		return result;
+	}
+
 	public Collection getBinaryPlugins(Config config) {
 		Collection allPlugins = getPlugins(config);
 		Set result = new LinkedHashSet(allPlugins.size());
diff --git a/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/BuildScriptGenerator.java b/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/BuildScriptGenerator.java
index 15016c6..f91458a 100755
--- a/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/BuildScriptGenerator.java
+++ b/p2/publishing/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/BuildScriptGenerator.java
@@ -15,6 +15,7 @@
 import java.util.*;
 import org.eclipse.core.runtime.*;
 import org.eclipse.equinox.p2.publisher.eclipse.Feature;
+import org.eclipse.equinox.p2.publisher.eclipse.FeatureEntry;
 import org.eclipse.osgi.service.resolver.BundleDescription;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.pde.internal.build.builder.*;
@@ -82,6 +83,20 @@
 	private boolean flatten = false;
 	private boolean sourceReferences = false;
 
+	// what kind of source bundles to auto output.  See #generateSourceBundles()
+	private String sourceBundleMode = null;
+
+	// the default id is a generic feature name as uber source features have no inherent 
+	// semantics or scope.
+	private String sourceBundleTemplateFeature = "org.eclipse.pde.build.uber.feature"; //$NON-NLS-1$
+	private String sourceBundleFeatureId = null;  //default is sourceBundleTemplateFeature + ".source"
+
+	// the default version is simply time-based as uber source features have no inherent 
+	// semantics or scope.
+	// XXX need a better way to version this feature.  Ideally the feature would not even 
+	// be persisted in the p2 metadata so this would not matter.
+	private String sourceBundleFeatureVersion = "1.0.0." + System.currentTimeMillis(); //$NON-NLS-1$
+
 	private static final String PROPERTY_ARCHIVESFORMAT = "archivesFormat"; //$NON-NLS-1$
 
 	/**
@@ -238,6 +253,9 @@
 					generator.generate(feature);
 				}
 
+				if (sourceBundleMode != null)
+					generateSourceBundles(generator);
+
 				if (features.size() != 1)
 					featureInfo = new String[] {"all"}; //$NON-NLS-1$
 
@@ -260,6 +278,42 @@
 		}
 	}
 
+	/**
+	 * Generate source bundles for this build.  The exact set of source bundles generated depends on 
+	 * the source output mode ((see {@link #setSourceBundleMode(String)}), the set of features
+	 * and bundles being built and the pre-existence of related source bundles. 
+	 * 
+	 * This step may result in the creation of an "uber source feature" that captures
+	 * a list of the generated source bundles.  
+	 * 
+	 * @param generator the build director to use when generating the source bundles
+	 */
+	private void generateSourceBundles(BuildDirector generator) throws CoreException {
+		Set allBundles = "all".equalsIgnoreCase(sourceBundleMode) ? generator.getAssemblyData().getAllPlugins() : generator.getAssemblyData().getAllCompiledPlugins(); //$NON-NLS-1$
+
+		BuildTimeFeature feature = getSite(false).findFeature(sourceBundleTemplateFeature, null, false);
+		if (feature == null)
+			feature = new BuildTimeFeature(sourceBundleTemplateFeature, sourceBundleFeatureVersion);
+
+		if (sourceBundleFeatureId == null)
+			sourceBundleFeatureId = sourceBundleTemplateFeature + ".source"; //$NON-NLS-1$
+
+		for (Iterator iterator = allBundles.iterator(); iterator.hasNext();) {
+			BundleDescription bundle = (BundleDescription) iterator.next();
+			if (!Utils.isSourceBundle(bundle))
+				feature.addEntry(new FeatureEntry(bundle.getSymbolicName(), bundle.getVersion().toString(), true));
+		}
+
+		SourceGenerator sourceGenerator = new SourceGenerator();
+		sourceGenerator.setExtraEntries(new String[] {}); //TODO set extra entries to include more, or exclude something
+		sourceGenerator.setDirector(generator);
+		sourceGenerator.setIndividual(true);
+		sourceGenerator.generateSourceFeature(feature, sourceBundleFeatureId);
+
+		BuildTimeFeature sourceFeature = getSite(false).findFeature(sourceBundleFeatureId, feature.getVersion(), true);
+		generator.generate(sourceFeature);
+	}
+
 	protected void generateVersionsLists(AssemblyInformation assemblageInformation) throws CoreException {
 		if (assemblageInformation == null)
 			return;
@@ -466,6 +520,38 @@
 	}
 
 	/**
+	 * Whether or not to automatically output source bundles corresponding to the bundles involved in 
+	 * the build.  If set to null, no special source bundle generation is done.  If set to "built", only the
+	 * source bundles corresponding to bundles actually compiled are output.  If set to "all" then all 
+	 * available source related to bundles in the build are output.
+	 * 
+	 * @param value the source bundle output mode.
+	 */
+	public void setSourceBundleMode(String value) {
+		sourceBundleMode = value;
+	}
+
+	/**
+	 * Sets the id to use for the uber source feature if needed.  See {@link #setSourceBundleMode(String)}
+	 * @param value the id of the generated source feature
+	 */
+	public void setSourceBundleFeatureId(String value) {
+		sourceBundleFeatureId = value;
+	}
+
+	public void setSourceBundleTemplateFeature(String value) {
+		sourceBundleTemplateFeature = value;
+	}
+
+	/**
+	 * Sets the version to use for the uber source feature if needed.  See {@link #setSourceBundleMode(String)}
+	 * @param value the version of the generated source feature
+	 */
+	public void setSourceBundleFeatureVersion(String value) {
+		sourceBundleFeatureVersion = value;
+	}
+
+	/**
 	 * @param value The reportResolutionErrors to set.
 	 */
 	public void setReportResolutionErrors(boolean value) {
diff --git a/p2/publishing/org.eclipse.pde.build/src_ant/org/eclipse/pde/internal/build/tasks/BuildScriptGeneratorTask.java b/p2/publishing/org.eclipse.pde.build/src_ant/org/eclipse/pde/internal/build/tasks/BuildScriptGeneratorTask.java
index 4ac8159..2c151d3 100755
--- a/p2/publishing/org.eclipse.pde.build/src_ant/org/eclipse/pde/internal/build/tasks/BuildScriptGeneratorTask.java
+++ b/p2/publishing/org.eclipse.pde.build/src_ant/org/eclipse/pde/internal/build/tasks/BuildScriptGeneratorTask.java
@@ -338,4 +338,24 @@
 		if (uris.size() > 0)
 			generator.setContextMetadataRepositories((URI[]) uris.toArray(new URI[uris.size()]));
 	}
+
+	public void setSourceBundleFeatureId(String value) {
+		if (value != null && !value.startsWith("${")) //$NON-NLS-1$
+			generator.setSourceBundleFeatureId(value);
+	}
+
+	public void setSourceBundleTemplateFeature(String value) {
+		if (value != null && !value.startsWith("${")) //$NON-NLS-1$
+			generator.setSourceBundleTemplateFeature(value);
+	}
+
+	public void setSourceBundleFeatureVersion(String value) {
+		if (value != null && !value.startsWith("${")) //$NON-NLS-1$
+			generator.setSourceBundleFeatureVersion(value);
+	}
+
+	public void setSourceBundleMode(String value) {
+		if (value != null && !value.startsWith("${")) //$NON-NLS-1$
+			generator.setSourceBundleMode(value);
+	}
 }
diff --git a/p2/publishing/org.eclipse.pde.build/templates/headless-build/build.properties b/p2/publishing/org.eclipse.pde.build/templates/headless-build/build.properties
index 45a1813..427880d 100755
--- a/p2/publishing/org.eclipse.pde.build/templates/headless-build/build.properties
+++ b/p2/publishing/org.eclipse.pde.build/templates/headless-build/build.properties
@@ -117,6 +117,24 @@
 #Control the creation of a file containing the version included in each configuration - on by default 
 #generateVersionsLists=false
 
+############## SOURCE BUNDLE CONTROL ################
+# Set this property to have source bundles created and output into build repository.
+# This does NOT put them in the build output (e.g., product) itself.
+# Valid values are: not set, built, all.
+# 		built = only source for bundles that are actually built/compiled in this run are output
+#		all = all available source is collected and output
+#sourceBundleMode=all
+
+# When outputting autogenerated source bundles a feature is created to contain all the automatic
+# source bundles.  Typically this feature is not needed and can be ignored. As such, it is given a default
+# name and version.  These properties can be used to override the defaults.
+#  sourceBundleTemplateFeature - can specify an existing feature which will be augmented to form the generated source feature
+#  sourceBundleFeatureId - will be the id of generated source feature which contains all the generated source bundles, default value
+#                          is sourceBundleTemplateFeature + ".source" if sourceBundleTemplateFeature is specified
+#sourceBundleTemplateFeature=
+#sourceBundleFeatureId=
+#sourceBundleFeatureVersion=
+
 ############## BUILD NAMING CONTROL ################
 # The directory into which the build elements are fetched and where
 # the build takes place.
diff --git a/p2/publishing/org.eclipse.pde.publishing/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java b/p2/publishing/org.eclipse.pde.publishing/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java
index 0114bd5..d125381 100644
--- a/p2/publishing/org.eclipse.pde.publishing/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java
+++ b/p2/publishing/org.eclipse.pde.publishing/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java
@@ -788,7 +788,7 @@
 		productName = attributes.getValue(ATTRIBUTE_NAME);
 		application = attributes.getValue(ATTRIBUTE_APPLICATION);
 		if (attributes.getIndex(ATTRIBUTE_INCLUDE_LAUNCHERS) >= 0)
-			includeLaunchers = Boolean.parseBoolean(attributes.getValue(ATTRIBUTE_INCLUDE_LAUNCHERS));
+			includeLaunchers = Boolean.valueOf(attributes.getValue(ATTRIBUTE_INCLUDE_LAUNCHERS));
 		String use = attributes.getValue("useFeatures"); //$NON-NLS-1$
 		if (use != null)
 			useFeatures = Boolean.valueOf(use).booleanValue();