Revert "Bug 501120 - Retire org.eclipse.pde.ui/src_samples"

This reverts commit be39e0c7ed74730a2054b37820401f7c063fdb95.
diff --git a/ui/org.eclipse.pde.ui/.classpath b/ui/org.eclipse.pde.ui/.classpath
index 01836c4..539a852 100644
--- a/ui/org.eclipse.pde.ui/.classpath
+++ b/ui/org.eclipse.pde.ui/.classpath
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="src_samples"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
 	<classpathentry kind="output" path="bin"/>
diff --git a/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
index fc499da..d6e105c 100644
--- a/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
@@ -38,6 +38,7 @@
  org.eclipse.pde.internal.ui.preferences;x-friends:="org.eclipse.pde.api.tools.ui",
  org.eclipse.pde.internal.ui.properties;x-internal:=true,
  org.eclipse.pde.internal.ui.refactoring;x-internal:=true,
+ org.eclipse.pde.internal.ui.samples;x-internal:=true,
  org.eclipse.pde.internal.ui.search;x-internal:=true,
  org.eclipse.pde.internal.ui.search.dependencies;x-internal:=true,
  org.eclipse.pde.internal.ui.search.dialogs;x-internal:=true,
diff --git a/ui/org.eclipse.pde.ui/plugin.xml b/ui/org.eclipse.pde.ui/plugin.xml
index bfdb097..1a91367 100644
--- a/ui/org.eclipse.pde.ui/plugin.xml
+++ b/ui/org.eclipse.pde.ui/plugin.xml
@@ -398,6 +398,14 @@
             <contentTypeBinding contentTypeId="org.eclipse.pde.targetFile"/>
       </editor>
       <editor
+            name="%editors.sample.name"
+            default="true"
+            icon="$nl$/icons/obj16/build_exec.png"
+            filenames="sample.properties"
+            class="org.eclipse.pde.internal.ui.samples.SampleEditor"
+            id="org.eclipse.pde.ui.sampleEditor">
+      </editor>
+      <editor
             default="false"
             icon="$nl$/icons/obj16/discovery.png"
             id="org.eclipse.pde.ui.schemaPreviewLauncher"
diff --git a/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ProjectNamesPage.java b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ProjectNamesPage.java
new file mode 100644
index 0000000..313eabc
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ProjectNamesPage.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2015 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.pde.internal.ui.samples;
+
+import java.util.HashSet;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.pde.internal.ui.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ *
+ */
+public class ProjectNamesPage extends WizardPage {
+	private SampleWizard wizard;
+	private Composite container;
+
+	/**
+	 * @param pageName
+	 */
+	public ProjectNamesPage(SampleWizard wizard) {
+		super("projects"); //$NON-NLS-1$
+		this.wizard = wizard;
+		setTitle(PDEUIMessages.ProjectNamesPage_title);
+		setDescription(PDEUIMessages.ProjectNamesPage_desc);
+	}
+
+	@Override
+	public void setVisible(boolean visible) {
+		setPageComplete(wizard.getSelection() != null);
+		if (container != null)
+			updateEntries();
+		super.setVisible(visible);
+	}
+
+	void updateEntries() {
+		IConfigurationElement selection = wizard.getSelection();
+		if (selection != null) {
+			setMessage(null);
+			IConfigurationElement[] projects = selection.getChildren("project"); //$NON-NLS-1$
+			Control[] children = container.getChildren();
+			if (projects.length == 1 && children.length == 2) {
+				Text text = (Text) children[1];
+				text.setText(projects[0].getAttribute("name")); //$NON-NLS-1$
+				validateEntries();
+				return;
+			}
+			// dispose all
+			for (int i = 0; i < children.length; i++) {
+				children[i].dispose();
+			}
+			// create entries
+			if (projects.length == 1) {
+				createEntry(PDEUIMessages.ProjectNamesPage_projectName, projects[0].getAttribute("name")); //$NON-NLS-1$
+			} else {
+				for (int i = 0; i < projects.length; i++) {
+					String label = NLS.bind(PDEUIMessages.ProjectNamesPage_multiProjectName, "" + (i + 1)); //$NON-NLS-1$
+					createEntry(label, projects[i].getAttribute("name")); //$NON-NLS-1$
+				}
+			}
+			container.layout();
+			validateEntries();
+		} else {
+			setMessage(PDEUIMessages.ProjectNamesPage_noSampleFound, IMessageProvider.WARNING);
+		}
+	}
+
+	public String[] getProjectNames() {
+		Control[] children = container.getChildren();
+		String[] names = new String[children.length / 2];
+
+		int index = 0;
+		for (int i = 0; i < children.length; i++) {
+			if (children[i] instanceof Text) {
+				String name = ((Text) children[i]).getText();
+				names[index++] = name;
+			}
+		}
+		return names;
+	}
+
+	private void createEntry(String labelName, String projectName) {
+		Label label = new Label(container, SWT.NULL);
+		label.setText(labelName);
+		label.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER));
+		final Text text = new Text(container, SWT.SINGLE | SWT.BORDER);
+		text.setText(projectName);
+		text.addModifyListener(new ModifyListener() {
+			@Override
+			public void modifyText(ModifyEvent e) {
+				validateEntries();
+			}
+		});
+		text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+	}
+
+	private void validateEntries() {
+		Control[] children = container.getChildren();
+		boolean empty = false;
+
+		HashSet<String> set = new HashSet<>();
+		for (int i = 0; i < children.length; i++) {
+			if (children[i] instanceof Text) {
+				String name = ((Text) children[i]).getText();
+				if (name.length() == 0) {
+					empty = true;
+					break;
+				}
+				IStatus nameStatus = PDEPlugin.getWorkspace().validateName(name, IResource.PROJECT);
+				if (!nameStatus.isOK()) {
+					setErrorMessage(nameStatus.getMessage());
+					setPageComplete(false);
+					return;
+				}
+				set.add(name);
+			}
+		}
+		if (empty) {
+			setErrorMessage(PDEUIMessages.ProjectNamesPage_emptyName);
+			setPageComplete(false);
+		} else {
+			int nnames = set.size();
+			int nfields = children.length / 2;
+			if (nfields > nnames) {
+				setErrorMessage(PDEUIMessages.ProjectNamesPage_duplicateNames);
+				setPageComplete(false);
+			} else {
+				setPageComplete(true);
+				setErrorMessage(null);
+			}
+		}
+	}
+
+	@Override
+	public void createControl(Composite parent) {
+		container = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		container.setLayout(layout);
+		setControl(container);
+		updateEntries();
+
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(container, IHelpContextIds.PROJECT_NAMES);
+	}
+}
diff --git a/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ReviewPage.java b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ReviewPage.java
new file mode 100644
index 0000000..808486a
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ReviewPage.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2015 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.pde.internal.ui.samples;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.pde.internal.ui.IHelpContextIds;
+import org.eclipse.pde.internal.ui.PDEUIMessages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.HyperlinkSettings;
+import org.eclipse.ui.forms.widgets.ScrolledFormText;
+
+public class ReviewPage extends WizardPage {
+	private SampleWizard wizard;
+	private ScrolledFormText formText;
+
+	/**
+	 * @param pageName
+	 */
+	public ReviewPage(SampleWizard wizard) {
+		super("last"); //$NON-NLS-1$
+		this.wizard = wizard;
+		setTitle(PDEUIMessages.ReviewPage_title);
+		setDescription(PDEUIMessages.ReviewPage_desc);
+	}
+
+	@Override
+	public void setVisible(boolean visible) {
+		setPageComplete(wizard.getSelection() != null);
+		if (formText != null)
+			updateContent();
+		super.setVisible(visible);
+	}
+
+	private void updateContent() {
+		StringBuffer buf = new StringBuffer();
+		buf.append("<form>"); //$NON-NLS-1$
+		IConfigurationElement selection = wizard.getSelection();
+		if (selection != null) {
+			setMessage(null);
+			IConfigurationElement[] desc = selection.getChildren("description"); //$NON-NLS-1$
+			if (desc.length == 1)
+				buf.append(NLS.bind(PDEUIMessages.ReviewPage_descContent, (new String[] {selection.getAttribute("name"), desc[0].getValue()}))); //$NON-NLS-1$
+			else
+				buf.append(NLS.bind(PDEUIMessages.ReviewPage_content, selection.getAttribute("name"))); //$NON-NLS-1$
+		} else {
+			setMessage(PDEUIMessages.ReviewPage_noSampleFound, IMessageProvider.WARNING);
+		}
+		buf.append("</form>"); //$NON-NLS-1$
+		formText.setText(buf.toString());
+	}
+
+	@Override
+	public void createControl(Composite parent) {
+		Composite container = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		container.setLayout(layout);
+		container.setLayoutData(new GridData(GridData.FILL_BOTH));
+		formText = new ScrolledFormText(container, true);
+		formText.setBackground(parent.getBackground());
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.widthHint = 300;
+		gd.heightHint = 300;
+		formText.setLayoutData(gd);
+		HyperlinkSettings settings = new HyperlinkSettings(parent.getDisplay());
+		formText.getFormText().setHyperlinkSettings(settings);
+		setControl(container);
+		updateContent();
+
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(container, IHelpContextIds.REVIEW);
+	}
+}
diff --git a/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleEditor.java b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleEditor.java
new file mode 100644
index 0000000..ce56bf3
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleEditor.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2015 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.pde.internal.ui.samples;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.ui.ILaunchShortcut;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.pde.internal.ui.*;
+import org.eclipse.pde.ui.launcher.EclipseLaunchShortcut;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.*;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.widgets.*;
+import org.eclipse.ui.part.EditorPart;
+
+/**
+ * @see EditorPart
+ */
+public class SampleEditor extends EditorPart {
+	private FormToolkit toolkit;
+	private ScrolledForm form;
+	private FormText descText;
+	private FormText instText;
+	private ILaunchShortcut defaultShortcut;
+	private InputFileListener inputFileListener;
+
+	class InputFileListener implements IResourceChangeListener, IResourceDeltaVisitor {
+		@Override
+		public void resourceChanged(IResourceChangeEvent event) {
+			if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
+				IResourceDelta delta = event.getDelta();
+				try {
+					delta.accept(this);
+				} catch (CoreException e) {
+					PDEPlugin.logException(e);
+				}
+			}
+		}
+
+		@Override
+		public boolean visit(IResourceDelta delta) throws CoreException {
+			IResource resource = delta.getResource();
+			if (resource instanceof IFile) {
+				IFile file = (IFile) resource;
+				if (file.equals(((IFileEditorInput) getEditorInput()).getFile())) {
+					if (delta.getKind() == IResourceDelta.REMOVED || delta.getKind() == IResourceDelta.REPLACED)
+						close();
+					return false;
+				}
+			}
+			return true;
+		}
+	}
+
+	/**
+	 *
+	 */
+	public SampleEditor() {
+		defaultShortcut = new EclipseLaunchShortcut();
+		PDEPlugin.getDefault().getLabelProvider().connect(this);
+	}
+
+	/**
+	 * @see EditorPart#createPartControl
+	 */
+	@Override
+	public void createPartControl(Composite parent) {
+		toolkit = new FormToolkit(parent.getDisplay());
+		form = toolkit.createScrolledForm(parent);
+		Properties properties = loadContent();
+		form.setText(properties.getProperty("name")); //$NON-NLS-1$
+		TableWrapLayout layout = new TableWrapLayout();
+		layout.verticalSpacing = 10;
+		layout.topMargin = 10;
+		layout.bottomMargin = 10;
+		layout.leftMargin = 10;
+		layout.rightMargin = 10;
+		form.getBody().setLayout(layout);
+
+		final String launcher = properties.getProperty("launcher"); //$NON-NLS-1$
+		final String launchTarget = properties.getProperty("launchTarget"); //$NON-NLS-1$
+
+		descText = toolkit.createFormText(form.getBody(), true);
+		descText.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
+		String desc = properties.getProperty("description"); //$NON-NLS-1$
+		String content = NLS.bind(PDEUIMessages.SampleEditor_desc, (desc != null ? desc : "")); //$NON-NLS-1$
+		descText.setText(content, true, false);
+		final String helpURL = properties.getProperty("helpHref"); //$NON-NLS-1$
+		if (helpURL != null) {
+			Hyperlink moreLink = toolkit.createHyperlink(form.getBody(), "Read More", SWT.NULL); //$NON-NLS-1$
+			moreLink.addHyperlinkListener(new HyperlinkAdapter() {
+				@Override
+				public void linkActivated(HyperlinkEvent e) {
+					PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(helpURL);
+				}
+			});
+		}
+		instText = toolkit.createFormText(form.getBody(), true);
+		instText.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
+		StringBuffer buf = new StringBuffer();
+		buf.append(PDEUIMessages.SampleEditor_content);
+		instText.setText(buf.toString(), true, false);
+		instText.addHyperlinkListener(new HyperlinkAdapter() {
+			@Override
+			public void linkActivated(HyperlinkEvent e) {
+				Object href = e.getHref();
+				if (href.equals("help")) { //$NON-NLS-1$
+					PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(helpURL);
+				} else if (href.equals("run")) { //$NON-NLS-1$
+					doRun(launcher, launchTarget, false);
+				} else if (href.equals("debug")) { //$NON-NLS-1$
+					doRun(launcher, launchTarget, true);
+				}
+			}
+		});
+		instText.setImage("run", PDEPlugin.getDefault().getLabelProvider().get(PDEPluginImages.DESC_RUN_EXC)); //$NON-NLS-1$
+		instText.setImage("debug", PDEPlugin.getDefault().getLabelProvider().get(PDEPluginImages.DESC_DEBUG_EXC)); //$NON-NLS-1$
+		instText.setImage("help", PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_INFO_TSK)); //$NON-NLS-1$
+	}
+
+	private void doRun(String launcher, String target, final boolean debug) {
+		ILaunchShortcut shortcut = defaultShortcut;
+		final ISelection selection;
+		if (target != null) {
+			selection = new StructuredSelection();
+		} else
+			selection = new StructuredSelection();
+		final ILaunchShortcut fshortcut = shortcut;
+		BusyIndicator.showWhile(form.getDisplay(), new Runnable() {
+			@Override
+			public void run() {
+				fshortcut.launch(selection, debug ? ILaunchManager.DEBUG_MODE : ILaunchManager.RUN_MODE);
+			}
+		});
+	}
+
+	private Properties loadContent() {
+		IStorageEditorInput input = (IStorageEditorInput) getEditorInput();
+		Properties properties = new Properties();
+		try {
+			IStorage storage = input.getStorage();
+			InputStream is = storage.getContents();
+			properties.load(is);
+			is.close();
+		} catch (IOException e) {
+			PDEPlugin.logException(e);
+		} catch (CoreException e) {
+			PDEPlugin.logException(e);
+		}
+		return properties;
+	}
+
+	@Override
+	public void dispose() {
+		if (inputFileListener != null) {
+			PDEPlugin.getWorkspace().removeResourceChangeListener(inputFileListener);
+			inputFileListener = null;
+		}
+		toolkit.dispose();
+		PDEPlugin.getDefault().getLabelProvider().disconnect(this);
+		super.dispose();
+	}
+
+	/**
+	 * @see EditorPart#setFocus
+	 */
+	@Override
+	public void setFocus() {
+		form.setFocus();
+	}
+
+	/**
+	 * @see EditorPart#doSave
+	 */
+	@Override
+	public void doSave(IProgressMonitor monitor) {
+	}
+
+	/**
+	 * @see EditorPart#doSaveAs
+	 */
+	@Override
+	public void doSaveAs() {
+	}
+
+	/**
+	 * @see EditorPart#isDirty
+	 */
+	@Override
+	public boolean isDirty() {
+		return false;
+	}
+
+	/**
+	 * @see EditorPart#isSaveAsAllowed
+	 */
+	@Override
+	public boolean isSaveAsAllowed() {
+		return false;
+	}
+
+	/**
+	 * @see EditorPart#init
+	 */
+	@Override
+	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+		setSite(site);
+		setInput(input);
+		inputFileListener = new InputFileListener();
+		PDEPlugin.getWorkspace().addResourceChangeListener(inputFileListener);
+	}
+
+	public void close() {
+		Display display = getSite().getShell().getDisplay();
+		display.asyncExec(new Runnable() {
+			@Override
+			public void run() {
+				if (toolkit != null) {
+					getSite().getPage().closeEditor(SampleEditor.this, false);
+				}
+			}
+		});
+	}
+}
diff --git a/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleOperation.java b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleOperation.java
new file mode 100644
index 0000000..1090da1
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleOperation.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2015 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
+ *     Johannes Ahlers <Johannes.Ahlers@gmx.de> - bug 477677
+ *******************************************************************************/
+package org.eclipse.pde.internal.ui.samples;
+
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.Properties;
+import java.util.zip.ZipFile;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.pde.internal.ui.*;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.wizards.datatransfer.ImportOperation;
+import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;
+import org.osgi.framework.Bundle;
+
+public class SampleOperation implements IRunnableWithProgress {
+	private static final String SAMPLE_PROPERTIES = "sample.properties"; //$NON-NLS-1$
+
+	private IConfigurationElement sample;
+
+	private String[] projectNames;
+
+	private IFile sampleManifest;
+
+	private IOverwriteQuery query;
+
+	private boolean yesToAll;
+
+	private boolean cancel;
+
+	private IProject[] createdProjects;
+
+	/**
+	 *
+	 */
+	public SampleOperation(IConfigurationElement sample, String[] projectNames, IOverwriteQuery query) {
+		this.sample = sample;
+		this.query = query;
+		this.projectNames = projectNames;
+	}
+
+	public IFile getSampleManifest() {
+		return sampleManifest;
+	}
+
+	public IProject[] getCreatedProjects() {
+		return createdProjects;
+	}
+
+	@Override
+	public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+		try {
+			ICoreRunnable op = new ICoreRunnable() {
+				@Override
+				public void run(IProgressMonitor monitor) throws CoreException {
+					IConfigurationElement[] projects = sample.getChildren("project"); //$NON-NLS-1$
+					SubMonitor subMonitor = SubMonitor.convert(monitor, PDEUIMessages.SampleOperation_creating,
+							projects.length);
+					createdProjects = new IProject[projects.length];
+					try {
+						for (int i = 0; i < projects.length; i++) {
+							IFile file = importProject(projectNames[i], projects[i],
+									subMonitor.split(1));
+							if (file != null && sampleManifest == null)
+								sampleManifest = file;
+							if (file != null) {
+								createdProjects[i] = file.getProject();
+							}
+							if (cancel)
+								// if user has cancelled operation, exit.
+								break;
+						}
+					} catch (InterruptedException e) {
+						throw new OperationCanceledException();
+					} catch (InvocationTargetException e) {
+						throwCoreException(e);
+					}
+				}
+			};
+			PDEPlugin.getWorkspace().run(op, monitor);
+		} catch (CoreException e) {
+			throw new InvocationTargetException(e);
+		} catch (OperationCanceledException e) {
+			throw e;
+		}
+	}
+
+	private void throwCoreException(InvocationTargetException e) throws CoreException {
+		Throwable t = e.getCause();
+		Status status = new Status(IStatus.ERROR, IPDEUIConstants.PLUGIN_ID, IStatus.OK, e.getMessage(), t);
+		throw new CoreException(status);
+	}
+
+	private IFile importProject(String name, IConfigurationElement config, IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
+		String path = config.getAttribute("archive"); //$NON-NLS-1$
+		if (name == null || path == null)
+			return null;
+		IWorkspace workspace = PDEPlugin.getWorkspace();
+		IWorkspaceRoot root = workspace.getRoot();
+		IProject project = root.getProject(name);
+		boolean skip = false;
+
+		SubMonitor subMonitor = SubMonitor.convert(monitor, name, 5);
+		if (project.exists()) {
+			if (!yesToAll) {
+				String returnId = query.queryOverwrite(project.getFullPath().toString());
+				if (returnId.equals(IOverwriteQuery.ALL)) {
+					yesToAll = true;
+					skip = false;
+				} else if (returnId.equals(IOverwriteQuery.YES)) {
+					skip = false;
+				} else if (returnId.equals(IOverwriteQuery.NO)) {
+					skip = true;
+				} else if (returnId.equals(IOverwriteQuery.CANCEL)) {
+					skip = true;
+					cancel = true;
+				}
+			}
+			if (!skip) {
+				project.delete(true, true, subMonitor.split(1));
+				project = root.getProject(name);
+			} else {
+				subMonitor.worked(1);
+			}
+		}
+		if (skip) {
+			subMonitor.worked(4);
+			IFile manifest = project.getFile(SAMPLE_PROPERTIES);
+			return manifest;
+		}
+
+		project.create(subMonitor.split(1));
+		project.open(subMonitor.split(1));
+		Bundle bundle = Platform.getBundle(sample.getNamespaceIdentifier());
+		ZipFile zipFile = getZipFileFromPluginDir(path, bundle);
+		importFilesFromZip(zipFile, project.getFullPath(), subMonitor.split(1));
+		return createSampleManifest(project, config, subMonitor.split(1));
+	}
+
+	private IFile createSampleManifest(IProject project, IConfigurationElement config, IProgressMonitor monitor) throws CoreException {
+		IFile file = project.getFile(SAMPLE_PROPERTIES);
+		if (!file.exists()) {
+			try {
+				ByteArrayOutputStream out = new ByteArrayOutputStream();
+				Properties properties = new Properties();
+				createSampleManifestContent(config.getAttribute("name"), properties); //$NON-NLS-1$
+				properties.store(out, ""); //$NON-NLS-1$
+				out.flush();
+				String contents = out.toString();
+				out.close();
+				ByteArrayInputStream stream = new ByteArrayInputStream(contents.getBytes("UTF8")); //$NON-NLS-1$
+				file.create(stream, true, monitor);
+				stream.close();
+			} catch (UnsupportedEncodingException e) {
+			} catch (IOException e) {
+			}
+		}
+		return file;
+	}
+
+	private void createSampleManifestContent(String projectName, Properties properties) {
+		writeProperty(properties, "id", sample.getAttribute("id")); //$NON-NLS-1$ //$NON-NLS-2$
+		writeProperty(properties, "name", sample.getAttribute("name")); //$NON-NLS-1$ //$NON-NLS-2$
+		writeProperty(properties, "projectName", projectName); //$NON-NLS-1$
+		writeProperty(properties, "launcher", sample.getAttribute("launcher")); //$NON-NLS-1$ //$NON-NLS-2$
+		IConfigurationElement desc[] = sample.getChildren("description"); //$NON-NLS-1$
+		if (desc.length == 1) {
+			writeProperty(properties, "helpHref", desc[0] //$NON-NLS-1$
+					.getAttribute("helpHref")); //$NON-NLS-1$
+			writeProperty(properties, "description", desc[0].getValue()); //$NON-NLS-1$
+		}
+	}
+
+	private void writeProperty(Properties properties, String name, String value) {
+		if (value == null)
+			return;
+		properties.setProperty(name, value);
+	}
+
+	private ZipFile getZipFileFromPluginDir(String pluginRelativePath, Bundle bundle) throws CoreException {
+		try {
+			URL starterURL = FileLocator.resolve(bundle.getEntry(pluginRelativePath));
+			return new ZipFile(FileLocator.toFileURL(starterURL).getFile());
+		} catch (IOException e) {
+			String message = pluginRelativePath + ": " + e.getMessage(); //$NON-NLS-1$
+			Status status = new Status(IStatus.ERROR, PDEPlugin.getPluginId(), IStatus.ERROR, message, e);
+			throw new CoreException(status);
+		}
+	}
+
+	private void importFilesFromZip(ZipFile srcZipFile, IPath destPath, IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+		ZipFileStructureProvider structureProvider = new ZipFileStructureProvider(srcZipFile);
+		ImportOperation op = new ImportOperation(destPath, structureProvider.getRoot(), structureProvider, query);
+		op.run(monitor);
+	}
+}
diff --git a/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleStandbyContent.java b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleStandbyContent.java
new file mode 100644
index 0000000..5c32f5a
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleStandbyContent.java
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2015 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.pde.internal.ui.samples;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Properties;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.ui.ILaunchShortcut;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.pde.internal.ui.*;
+import org.eclipse.pde.ui.launcher.EclipseLaunchShortcut;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.*;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.widgets.*;
+import org.eclipse.ui.intro.IIntroPart;
+import org.eclipse.ui.intro.config.IStandbyContentPart;
+import org.eclipse.ui.part.ISetSelectionTarget;
+
+public class SampleStandbyContent implements IStandbyContentPart {
+	private ScrolledForm form;
+	private Hyperlink moreLink;
+	private String helpURL;
+	private String launcher;
+	private String launchTarget;
+	private FormText descText;
+	private FormText instText;
+	private ILaunchShortcut defaultShortcut;
+	private IConfigurationElement sample;
+	// cached input.
+	private String input;
+
+	private static String MEMENTO_SAMPLE_ID_ATT = "sampleId"; //$NON-NLS-1$
+
+	/**
+	 *
+	 */
+	public SampleStandbyContent() {
+		defaultShortcut = new EclipseLaunchShortcut();
+		PDEPlugin.getDefault().getLabelProvider().connect(this);
+	}
+
+	@Override
+	public void createPartControl(Composite parent, FormToolkit toolkit) {
+		form = toolkit.createScrolledForm(parent);
+		//form.setBackgroundImage(PDEPlugin.getDefault().getLabelProvider().get(
+		//		PDEPluginImages.DESC_FORM_BANNER));
+		TableWrapLayout layout = new TableWrapLayout();
+		layout.verticalSpacing = 10;
+		layout.topMargin = 10;
+		layout.bottomMargin = 10;
+		layout.leftMargin = 10;
+		layout.rightMargin = 10;
+		form.getBody().setLayout(layout);
+		descText = toolkit.createFormText(form.getBody(), true);
+		descText.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
+		descText.setText("", false, false); //$NON-NLS-1$
+		moreLink = toolkit.createHyperlink(form.getBody(), "Read More", //$NON-NLS-1$
+				SWT.NULL);
+		moreLink.addHyperlinkListener(new HyperlinkAdapter() {
+			@Override
+			public void linkActivated(HyperlinkEvent e) {
+				if (helpURL != null)
+					PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(helpURL);
+			}
+		});
+		instText = toolkit.createFormText(form.getBody(), true);
+		instText.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));
+		StringBuffer buf = new StringBuffer();
+		buf.append(PDEUIMessages.SampleStandbyContent_content);
+		instText.setText(buf.toString(), true, false);
+		instText.addHyperlinkListener(new HyperlinkAdapter() {
+			@Override
+			public void linkActivated(HyperlinkEvent e) {
+				Object href = e.getHref();
+				if (href.equals("help")) { //$NON-NLS-1$
+					PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(helpURL);
+				} else if (href.equals("browse")) { //$NON-NLS-1$
+					doBrowse();
+				} else if (href.equals("run")) { //$NON-NLS-1$
+					doRun(launcher, launchTarget, false);
+				} else if (href.equals("debug")) { //$NON-NLS-1$
+					doRun(launcher, launchTarget, true);
+				}
+			}
+		});
+		instText.setImage("run", PDEPlugin.getDefault().getLabelProvider().get( //$NON-NLS-1$
+				PDEPluginImages.DESC_RUN_EXC));
+		instText.setImage("debug", PDEPlugin.getDefault().getLabelProvider() //$NON-NLS-1$
+				.get(PDEPluginImages.DESC_DEBUG_EXC));
+		instText.setImage("help", PlatformUI.getWorkbench().getSharedImages() //$NON-NLS-1$
+				.getImage(ISharedImages.IMG_OBJS_INFO_TSK));
+	}
+
+	private void doRun(String launcher, String target, final boolean debug) {
+		ILaunchShortcut shortcut = defaultShortcut;
+		final ISelection selection;
+		if (target != null) {
+			selection = new StructuredSelection();
+		} else
+			selection = new StructuredSelection();
+		final ILaunchShortcut fshortcut = shortcut;
+		BusyIndicator.showWhile(form.getDisplay(), new Runnable() {
+			@Override
+			public void run() {
+				fshortcut.launch(selection, debug ? ILaunchManager.DEBUG_MODE : ILaunchManager.RUN_MODE);
+			}
+		});
+	}
+
+	private void doBrowse() {
+		IWorkspaceRoot root = PDEPlugin.getWorkspace().getRoot();
+		IProject[] projects = root.getProjects();
+		ISetSelectionTarget target = findTarget();
+		if (target == null)
+			return;
+		String sid = sample.getAttribute("id"); //$NON-NLS-1$
+		if (sid == null)
+			return;
+		ArrayList<IResource> items = new ArrayList<>();
+		for (int i = 0; i < projects.length; i++) {
+			IProject project = projects[i];
+			if (!project.exists() || !project.isOpen())
+				continue;
+			IFile pfile = project.getFile("sample.properties"); //$NON-NLS-1$
+			if (pfile.exists()) {
+				try {
+					InputStream is = pfile.getContents();
+					Properties prop = new Properties();
+					prop.load(is);
+					is.close();
+					String id = prop.getProperty("id"); //$NON-NLS-1$
+					if (id != null && id.equals(sid)) {
+						//match
+						IResource res = findSelectReveal(project, prop.getProperty("projectName")); //$NON-NLS-1$
+						if (res != null)
+							items.add(res);
+					}
+				} catch (IOException e) {
+					PDEPlugin.logException(e);
+				} catch (CoreException e) {
+					PDEPlugin.logException(e);
+				}
+			}
+		}
+		if (items.size() > 0)
+			target.selectReveal(new StructuredSelection(items));
+	}
+
+	private ISetSelectionTarget findTarget() {
+		String id = sample.getAttribute("targetViewId"); //$NON-NLS-1$
+		if (id == null)
+			return null;
+		IViewPart view = PDEPlugin.getActivePage().findView(id);
+		if (view == null || !(view instanceof ISetSelectionTarget))
+			return null;
+		return (ISetSelectionTarget) view;
+	}
+
+	private IResource findSelectReveal(IProject project, String originalName) {
+		IConfigurationElement[] projects = sample.getChildren("project"); //$NON-NLS-1$
+		for (int i = 0; i < projects.length; i++) {
+			if (originalName.equals(projects[i].getAttribute("name"))) { //$NON-NLS-1$
+				String path = projects[i].getAttribute("selectReveal"); //$NON-NLS-1$
+				if (path == null)
+					continue;
+				IResource res = project.findMember(path);
+				if (res != null && res.exists())
+					return res;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public Control getControl() {
+		return form;
+	}
+
+	public void init(IIntroPart introPart) {
+	}
+
+	@Override
+	public void setInput(Object input) {
+		// if the new input is null, use cached input from momento.
+		if (input != null)
+			this.input = (String) input;
+		String sampleId = this.input.toString();
+		IConfigurationElement[] samples = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.pde.ui.samples"); //$NON-NLS-1$
+		for (int i = 0; i < samples.length; i++) {
+			IConfigurationElement sample = samples[i];
+			String id = sample.getAttribute("id"); //$NON-NLS-1$
+			if (id != null && id.equals(sampleId)) {
+				update(sample);
+				return;
+			}
+		}
+		update(null);
+	}
+
+	private void update(IConfigurationElement sample) {
+		this.sample = sample;
+		if (form == null)
+			return;
+		String title = sample != null ? sample.getAttribute("name") : ""; //$NON-NLS-1$ //$NON-NLS-2$
+		form.setText(title);
+		if (sample != null) {
+			launcher = sample.getAttribute("launcher"); //$NON-NLS-1$
+			launchTarget = sample.getAttribute("launchTarget"); //$NON-NLS-1$
+		} else {
+			launcher = null;
+			launchTarget = null;
+		}
+		IConfigurationElement[] descConfig = sample != null ? sample.getChildren("description") : null; //$NON-NLS-1$
+		if (descConfig != null && descConfig.length == 1) {
+			String desc = descConfig[0].getValue();
+			String content = NLS.bind(PDEUIMessages.SampleStandbyContent_desc, (desc != null ? desc : "")); //$NON-NLS-1$
+			helpURL = descConfig[0].getAttribute("helpHref"); //$NON-NLS-1$
+			moreLink.setVisible(helpURL != null);
+			descText.setText(content, true, false);
+		} else {
+			moreLink.setVisible(false);
+			descText.setText("", false, false); //$NON-NLS-1$
+		}
+		form.reflow(true);
+	}
+
+	@Override
+	public void setFocus() {
+		form.setFocus();
+	}
+
+	@Override
+	public void dispose() {
+		PDEPlugin.getDefault().getLabelProvider().disconnect(this);
+	}
+
+	@Override
+	public void init(IIntroPart introPart, IMemento memento) {
+		// try to restore last state.
+		input = getCachedInput(memento);
+
+	}
+
+	/**
+	* Tries to create the last content part viewed, based on sample id.
+	*
+	* @param memento
+	*/
+	private String getCachedInput(IMemento memento) {
+		if (memento == null)
+			return null;
+		return memento.getString(MEMENTO_SAMPLE_ID_ATT);
+
+	}
+
+	@Override
+	public void saveState(IMemento memento) {
+		String currentSampleId = input;
+		if (input != null)
+			memento.putString(MEMENTO_SAMPLE_ID_ATT, currentSampleId);
+
+	}
+}
diff --git a/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleWizard.java b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleWizard.java
new file mode 100644
index 0000000..358f67a
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SampleWizard.java
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2015 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.pde.internal.ui.samples;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashSet;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.pde.internal.ui.*;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.*;
+import org.eclipse.ui.activities.IWorkbenchActivitySupport;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.ide.IDE;
+
+public class SampleWizard extends Wizard implements INewWizard, IExecutableExtension {
+	private IConfigurationElement[] samples;
+	private IConfigurationElement selection;
+	private ProjectNamesPage namesPage;
+	private ReviewPage lastPage;
+
+	private boolean sampleEditorNeeded = true;
+	private boolean switchPerspective = true;
+	private boolean selectRevealEnabled = true;
+	private boolean activitiesEnabled = true;
+
+	private class ImportOverwriteQuery implements IOverwriteQuery {
+		@Override
+		public String queryOverwrite(String file) {
+			String[] returnCodes = {YES, NO, ALL, CANCEL};
+			int returnVal = openDialog(file);
+			return returnVal < 0 ? CANCEL : returnCodes[returnVal];
+		}
+
+		private int openDialog(final String file) {
+			final int[] result = {IDialogConstants.CANCEL_ID};
+			getShell().getDisplay().syncExec(new Runnable() {
+				@Override
+				public void run() {
+					String title = PDEUIMessages.SampleWizard_title;
+					String msg = NLS.bind(PDEUIMessages.SampleWizard_overwrite, file);
+					String[] options = {IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.CANCEL_LABEL};
+					MessageDialog dialog = new MessageDialog(getShell(), title, null, msg, MessageDialog.QUESTION, options, 0);
+					result[0] = dialog.open();
+				}
+			});
+			return result[0];
+		}
+	}
+
+	/**
+	 * The default constructor.
+	 *
+	 */
+	public SampleWizard() {
+		PDEPlugin.getDefault().getLabelProvider().connect(this);
+		setDefaultPageImageDescriptor(PDEPluginImages.DESC_NEWEXP_WIZ);
+		samples = Platform.getExtensionRegistry().getConfigurationElementsFor("org.eclipse.pde.ui.samples"); //$NON-NLS-1$
+		namesPage = new ProjectNamesPage(this);
+		lastPage = new ReviewPage(this);
+		setNeedsProgressMonitor(true);
+		setWindowTitle(PDEUIMessages.ShowSampleAction_title);
+	}
+
+	@Override
+	public void dispose() {
+		PDEPlugin.getDefault().getLabelProvider().disconnect(this);
+		super.dispose();
+	}
+
+	public IConfigurationElement[] getSamples() {
+		return samples;
+	}
+
+	/**
+	 *
+	 */
+	@Override
+	public void addPages() {
+		if (selection == null) {
+			addPage(new SelectionPage(this));
+		}
+		addPage(namesPage);
+		addPage(lastPage);
+	}
+
+	/**
+	 *
+	 */
+	@Override
+	public boolean performFinish() {
+		try {
+			String perspId = selection.getAttribute("perspectiveId"); //$NON-NLS-1$
+			IWorkbenchPage page = PDEPlugin.getActivePage();
+			if (perspId != null && switchPerspective) {
+				PlatformUI.getWorkbench().showPerspective(perspId, page.getWorkbenchWindow());
+			}
+			SampleOperation op = new SampleOperation(selection, namesPage.getProjectNames(), new ImportOverwriteQuery());
+			getContainer().run(true, true, op);
+			IFile sampleManifest = op.getSampleManifest();
+			if (selectRevealEnabled) {
+				selectReveal(getShell());
+			}
+			if (activitiesEnabled)
+				enableActivities();
+			if (sampleEditorNeeded && sampleManifest != null)
+				IDE.openEditor(page, sampleManifest, true);
+		} catch (InvocationTargetException e) {
+			PDEPlugin.logException(e);
+			return false;
+		} catch (InterruptedException e) {
+			//PDEPlugin.logException(e);
+			return false;
+		} catch (CoreException e) {
+			PDEPlugin.logException(e);
+			return false;
+		} catch (OperationCanceledException e) {
+			return false;
+		}
+		return true;
+	}
+
+	public void selectReveal(Shell shell) {
+		/*
+		shell.getDisplay().asyncExec(new Runnable() {
+			public void run() {
+				doSelectReveal();
+			}
+		});
+		*/
+	}
+
+	/*private void doSelectReveal() {
+		if (selection == null || createdProjects==null)
+			return;
+		String viewId = selection.getAttribute("targetViewId"); //$NON-NLS-1$
+		if (viewId == null)
+			return;
+		IWorkbenchWindow window = PlatformUI.getWorkbench()
+				.getActiveWorkbenchWindow();
+		if (window == null)
+			return;
+		IWorkbenchPage page = window.getActivePage();
+		if (page == null)
+			return;
+		IViewPart view = page.findView(viewId);
+		if (view == null || !(view instanceof ISetSelectionTarget))
+			return;
+		ISetSelectionTarget target = (ISetSelectionTarget) view;
+		IConfigurationElement[] projects = selection.getChildren("project"); //$NON-NLS-1$
+
+		ArrayList items = new ArrayList();
+		for (int i = 0; i < projects.length; i++) {
+			String path = projects[i].getAttribute("selectReveal"); //$NON-NLS-1$
+			if (path == null)
+				continue;
+			IResource resource = createdProjects[i].findMember(path);
+			if (resource.exists())
+				items.add(resource);
+		}
+		if (items.size() > 0)
+			target.selectReveal(new StructuredSelection(items));
+	}
+	*/
+	public void enableActivities() {
+		IConfigurationElement[] elements = selection.getChildren("activity"); //$NON-NLS-1$
+		HashSet<String> activitiesToEnable = new HashSet<>();
+		IWorkbenchActivitySupport workbenchActivitySupport = PlatformUI.getWorkbench().getActivitySupport();
+
+		for (int i = 0; i < elements.length; i++) {
+			IConfigurationElement element = elements[i];
+			String id = element.getAttribute("id"); //$NON-NLS-1$
+			if (id == null)
+				continue;
+			activitiesToEnable.add(id);
+		}
+		HashSet<String> set = new HashSet<String>(workbenchActivitySupport.getActivityManager().getEnabledActivityIds());
+		set.addAll(activitiesToEnable);
+		workbenchActivitySupport.setEnabledActivityIds(set);
+	}
+
+	/**
+	 *
+	 */
+	@Override
+	public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException {
+		String variable = data != null && data instanceof String ? data.toString() : null;
+		if (variable != null) {
+			for (int i = 0; i < samples.length; i++) {
+				IConfigurationElement element = samples[i];
+				String id = element.getAttribute("id"); //$NON-NLS-1$
+				if (id != null && id.equals(variable)) {
+					setSelection(element);
+					break;
+				}
+			}
+		}
+	}
+
+	@Override
+	public void init(IWorkbench workbench, IStructuredSelection selection) {
+	}
+
+	/**
+	 * @return Returns the selection.
+	 */
+	public IConfigurationElement getSelection() {
+		return selection;
+	}
+
+	/**
+	 * @param selection
+	 *            The selection to set.
+	 */
+	public void setSelection(IConfigurationElement selection) {
+		this.selection = selection;
+	}
+
+	/**
+	 * @return Returns the sampleEditorNeeded.
+	 */
+	public boolean isSampleEditorNeeded() {
+		return sampleEditorNeeded;
+	}
+
+	/**
+	 * @param sampleEditorNeeded
+	 *            The sampleEditorNeeded to set.
+	 */
+	public void setSampleEditorNeeded(boolean sampleEditorNeeded) {
+		this.sampleEditorNeeded = sampleEditorNeeded;
+	}
+
+	/**
+	 * @return Returns the switchPerspective.
+	 * @todo Generated comment
+	 */
+	public boolean isSwitchPerspective() {
+		return switchPerspective;
+	}
+
+	/**
+	 * @param switchPerspective The switchPerspective to set.
+	 * @todo Generated comment
+	 */
+	public void setSwitchPerspective(boolean switchPerspective) {
+		this.switchPerspective = switchPerspective;
+	}
+
+	/**
+	 * @return Returns the selectRevealEnabled.
+	 * @todo Generated comment
+	 */
+	public boolean isSelectRevealEnabled() {
+		return selectRevealEnabled;
+	}
+
+	/**
+	 * @param selectRevealEnabled The selectRevealEnabled to set.
+	 * @todo Generated comment
+	 */
+	public void setSelectRevealEnabled(boolean selectRevealEnabled) {
+		this.selectRevealEnabled = selectRevealEnabled;
+	}
+
+	/**
+	 * @return Returns the activitiesEnabled.
+	 * @todo Generated comment
+	 */
+	public boolean getActivitiesEnabled() {
+		return activitiesEnabled;
+	}
+
+	/**
+	 * @param activitiesEnabled The activitiesEnabled to set.
+	 * @todo Generated comment
+	 */
+	public void setActivitiesEnabled(boolean activitiesEnabled) {
+		this.activitiesEnabled = activitiesEnabled;
+	}
+
+	public void updateEntries() {
+		namesPage.updateEntries();
+	}
+}
diff --git a/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SelectionPage.java b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SelectionPage.java
new file mode 100644
index 0000000..dae21f0
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/SelectionPage.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2016 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
+ *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 487943
+ *******************************************************************************/
+package org.eclipse.pde.internal.ui.samples;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.pde.internal.ui.*;
+import org.eclipse.pde.internal.ui.parts.TablePart;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.PlatformUI;
+
+public class SelectionPage extends WizardPage {
+	private TablePart part;
+	private Text desc;
+	private SampleWizard wizard;
+
+	class SelectionPart extends TablePart {
+		public SelectionPart() {
+			super(new String[] {"More Info"}); //$NON-NLS-1$
+		}
+
+		@Override
+		protected void buttonSelected(Button button, int index) {
+			if (index == 0)
+				doMoreInfo();
+		}
+
+		@Override
+		protected void selectionChanged(IStructuredSelection selection) {
+			updateSelection(selection);
+		}
+
+		@Override
+		protected void handleDoubleClick(IStructuredSelection selection) {
+		}
+	}
+
+	class SampleProvider implements IStructuredContentProvider {
+		@Override
+		public Object[] getElements(Object input) {
+			return wizard.getSamples();
+		}
+	}
+
+	class SampleLabelProvider extends LabelProvider {
+		private Image image;
+
+		public SampleLabelProvider() {
+			image = PDEPlugin.getDefault().getLabelProvider().get(PDEPluginImages.DESC_NEWEXP_TOOL);
+		}
+
+		@Override
+		public String getText(Object obj) {
+			IConfigurationElement sample = (IConfigurationElement) obj;
+			return sample.getAttribute("name"); //$NON-NLS-1$
+		}
+
+		@Override
+		public Image getImage(Object obj) {
+			return image;
+		}
+	}
+
+	/**
+	 * @param pageName
+	 */
+	public SelectionPage(SampleWizard wizard) {
+		super("selection"); //$NON-NLS-1$
+		this.wizard = wizard;
+		setTitle(PDEUIMessages.SelectionPage_title);
+		setDescription(PDEUIMessages.SelectionPage_desc);
+		part = new SelectionPart();
+	}
+
+	@Override
+	public void createControl(Composite parent) {
+		Composite container = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		container.setLayout(layout);
+		layout.numColumns = 2;
+		part.setMinimumSize(300, 300);
+		part.createControl(container, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, 2, null);
+		part.getTableViewer().setContentProvider(new SampleProvider());
+		part.getTableViewer().setLabelProvider(new SampleLabelProvider());
+		desc = new Text(container, SWT.MULTI | SWT.BORDER | SWT.WRAP | SWT.V_SCROLL);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.heightHint = 64;
+		desc.setLayoutData(gd);
+		part.getTableViewer().setInput(this);
+		updateSelection(null);
+		setControl(container);
+
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(container, IHelpContextIds.SELECTION);
+	}
+
+	private void doMoreInfo() {
+		if (wizard.getSelection() != null) {
+			IConfigurationElement desc[] = wizard.getSelection().getChildren("description"); //$NON-NLS-1$
+			String helpHref = desc[0].getAttribute("helpHref"); //$NON-NLS-1$
+			PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(helpHref);
+		}
+	}
+
+	private void updateSelection(IStructuredSelection selection) {
+		if (selection == null) {
+			desc.setText(""); //$NON-NLS-1$
+			part.setButtonEnabled(0, false);
+			setPageComplete(false);
+		} else {
+			IConfigurationElement sample = (IConfigurationElement) selection.getFirstElement();
+			String text = ""; //$NON-NLS-1$
+			String helpHref = null;
+			IConfigurationElement[] sampleDesc = sample.getChildren("description"); //$NON-NLS-1$
+			if (sampleDesc.length == 1) {
+				text = sampleDesc[0].getValue();
+				helpHref = sampleDesc[0].getAttribute("helpHref"); //$NON-NLS-1$
+			}
+			desc.setText(text);
+			part.setButtonEnabled(0, helpHref != null);
+			wizard.setSelection(sample);
+			wizard.updateEntries();
+			setPageComplete(true);
+		}
+	}
+}
diff --git a/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ShowSampleAction.java b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ShowSampleAction.java
new file mode 100644
index 0000000..e485cdd
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ShowSampleAction.java
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2015 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.pde.internal.ui.samples;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.provisional.configurator.Configurator;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.engine.IProfile;
+import org.eclipse.equinox.p2.engine.IProfileRegistry;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.operations.InstallOperation;
+import org.eclipse.equinox.p2.operations.ProvisioningJob;
+import org.eclipse.equinox.p2.query.*;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.equinox.p2.ui.ProvisioningUI;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.pde.internal.ui.*;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.intro.IIntroSite;
+import org.eclipse.ui.intro.config.*;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class ShowSampleAction extends Action implements IIntroAction {
+	private static final String SAMPLE_FEATURE_ID = "org.eclipse.sdk.samples"; //$NON-NLS-1$
+	private static final String UPDATE_SITE = "http://www.eclipse.org/pde/samples/site.xml"; //$NON-NLS-1$
+	private String sampleId;
+
+	private ProvisioningUI provUI;
+
+	/**
+	 *
+	 */
+	public ShowSampleAction() {
+		provUI = ProvisioningUI.getDefaultUI();
+	}
+
+	@Override
+	public void run(IIntroSite site, Properties params) {
+		sampleId = params.getProperty("id"); //$NON-NLS-1$
+		if (sampleId == null)
+			return;
+
+		Runnable r = new Runnable() {
+			@Override
+			public void run() {
+				if (!ensureSampleFeaturePresent())
+					return;
+
+				SampleWizard wizard = new SampleWizard();
+				try {
+					wizard.setInitializationData(null, "class", sampleId); //$NON-NLS-1$
+					wizard.setSampleEditorNeeded(false);
+					wizard.setSwitchPerspective(false);
+					wizard.setSelectRevealEnabled(false);
+					wizard.setActivitiesEnabled(false);
+					WizardDialog dialog = new WizardDialog(PDEPlugin.getActiveWorkbenchShell(), wizard);
+					dialog.create();
+					if (dialog.open() == Window.OK) {
+						switchToSampleStandby(wizard);
+					}
+				} catch (CoreException e) {
+					PDEPlugin.logException(e);
+				}
+			}
+		};
+
+		Shell currentShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+		currentShell.getDisplay().asyncExec(r);
+	}
+
+	private void switchToSampleStandby(SampleWizard wizard) {
+		StringBuffer url = new StringBuffer();
+		url.append("http://org.eclipse.ui.intro/showStandby?"); //$NON-NLS-1$
+		url.append("pluginId=org.eclipse.pde.ui"); //$NON-NLS-1$
+		url.append("&"); //$NON-NLS-1$
+		url.append("partId=org.eclipse.pde.ui.sampleStandbyPart"); //$NON-NLS-1$
+		url.append("&"); //$NON-NLS-1$
+		url.append("input="); //$NON-NLS-1$
+		url.append(sampleId);
+		IIntroURL introURL = IntroURLFactory.createIntroURL(url.toString());
+		if (introURL != null) {
+			introURL.execute();
+			ensureProperContext(wizard);
+		}
+	}
+
+	private void ensureProperContext(SampleWizard wizard) {
+		IConfigurationElement sample = wizard.getSelection();
+		String perspId = sample.getAttribute("perspectiveId"); //$NON-NLS-1$
+		if (perspId != null) {
+			try {
+				wizard.enableActivities();
+				PlatformUI.getWorkbench().showPerspective(perspId, PDEPlugin.getActiveWorkbenchWindow());
+				wizard.selectReveal(PDEPlugin.getActiveWorkbenchShell());
+			} catch (WorkbenchException e) {
+				PDEPlugin.logException(e);
+			}
+		}
+		enableActivities(sample);
+	}
+
+	private void enableActivities(IConfigurationElement sample) {
+	}
+
+	/**
+	 * Ensure the sample feature is present. If not present, attempt to install it.
+	 *
+	 * @return <code>true</code> if the sample features are present, and
+	 * <code>false</code> otherwise.
+	 */
+	private boolean ensureSampleFeaturePresent() {
+		IProfile profile = getProfile();
+		if (profile == null)
+			return false;
+		if (checkFeature(profile))
+			return true;
+		// the feature is not present - ask to download
+		if (MessageDialog.openQuestion(PDEPlugin.getActiveWorkbenchShell(), PDEUIMessages.ShowSampleAction_msgTitle, PDEUIMessages.ShowSampleAction_msgDesc)) {
+			return downloadFeature();
+		}
+		return false;
+	}
+
+	private boolean checkFeature(IProfile profile) {
+		return !profile.query(getSampleFeatureQuery(), null).isEmpty();
+	}
+
+	/**
+	 * Returns <code>true</code> if the sample feature is already installed, or if
+	 * it won't be possible to install the feature (required services are missing). Returns
+	 * <code>false</code> if the features are missing and should be installed.
+	 */
+	private IProfile getProfile() {
+		IProvisioningAgent agent = provUI.getSession().getProvisioningAgent();
+		if (agent == null)
+			return null;
+		IProfileRegistry registry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME);
+		if (registry == null)
+			return null;
+		return registry.getProfile(provUI.getProfileId());
+	}
+
+	IQuery<IInstallableUnit> getSampleFeatureQuery() {
+		return QueryUtil.createIUQuery(SAMPLE_FEATURE_ID);
+	}
+
+	/**
+	 * Download the sample feature, returning <code>true</code> if the feature
+	 * was installed successfully, and <code>false</code> otherwise.
+	 */
+	private boolean downloadFeature() {
+		IRunnableWithProgress op = new IRunnableWithProgress() {
+			@Override
+			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+				try {
+					SubMonitor sub = SubMonitor.convert(monitor, PDEUIMessages.ShowSampleAction_installing, 100);
+					InstallOperation operation = createInstallOperation(sub.split(10));
+					operation.resolveModal(sub.split(20));
+					IStatus status = operation.getResolutionResult();
+					if (status.getSeverity() == IStatus.CANCEL) {
+						throw new InterruptedException();
+					} else if (!(status.isOK() || status.getSeverity() == IStatus.INFO)) {
+						throw new CoreException(status);
+					}
+					ProvisioningJob job = operation.getProvisioningJob(null);
+					status = job.runModal(sub.split(70));
+					if (!(status.isOK() || status.getSeverity() == IStatus.INFO)) {
+						throw new CoreException(status);
+					}
+					applyConfiguration();
+				} catch (Exception e) {
+					throw new InvocationTargetException(e);
+				}
+			}
+		};
+		try {
+			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(op);
+		} catch (InvocationTargetException e) {
+			PDEPlugin.logException(e);
+			return false;
+		} catch (InterruptedException e) {
+			PDEPlugin.logException(e);
+		}
+		return true;
+	}
+
+	/**
+	 * Returns a Collection<IInstallableUnit> of the installable units that contain the samples
+	 * to be installed.
+	 */
+	protected Collection<IInstallableUnit> findSampleIUs(URI location, SubMonitor monitor) throws ProvisionException {
+		IMetadataRepository repository = provUI.loadMetadataRepository(location, false, monitor.split(5));
+		IQueryResult<IInstallableUnit> allSamples = repository.query(getSampleFeatureQuery(), monitor.split(5));
+		if (allSamples.isEmpty()) {
+			throw new ProvisionException(NLS.bind(PDEUIMessages.ShowSampleAction_NoSamplesFound, location.toString()));
+		}
+		IInstallableUnit toInstall = null;
+		for (Iterator<IInstallableUnit> iterator = allSamples.iterator(); iterator.hasNext();) {
+			IInstallableUnit current = iterator.next();
+			if (toInstall == null || toInstall.getVersion().compareTo(current.getVersion()) < 0) {
+				toInstall = current;
+			}
+		}
+		Collection<IInstallableUnit> result = new ArrayList<>(1);
+		result.add(toInstall);
+		return result;
+	}
+
+	/**
+	 * Creates the operation that will install the sample features in the running platform.
+	 */
+	InstallOperation createInstallOperation(SubMonitor monitor) throws URISyntaxException, ProvisionException {
+		URI repositoryLocation = new URI(UPDATE_SITE);
+		Collection<IInstallableUnit> sampleIUs = findSampleIUs(repositoryLocation, monitor);
+		URI[] repos = new URI[] {repositoryLocation};
+		InstallOperation operation = provUI.getInstallOperation(sampleIUs, repos);
+		return operation;
+	}
+
+	/**
+	 * Apply the profile changes to the currently running configuration.
+	 */
+	void applyConfiguration() throws CoreException {
+		BundleContext context = PDEPlugin.getDefault().getBundle().getBundleContext();
+		ServiceReference<?> reference = context.getServiceReference(Configurator.class.getName());
+		Configurator configurator = (Configurator) context.getService(reference);
+		try {
+			configurator.applyConfiguration();
+		} catch (IOException e) {
+			throw new CoreException(new Status(IStatus.ERROR, IPDEUIConstants.PLUGIN_ID, "Unexpected failure applying configuration", e)); //$NON-NLS-1$
+		} finally {
+			context.ungetService(reference);
+		}
+	}
+
+}
diff --git a/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ShowTargetPlatformAction.java b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ShowTargetPlatformAction.java
new file mode 100644
index 0000000..98cfb09
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src_samples/org/eclipse/pde/internal/ui/samples/ShowTargetPlatformAction.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *  Copyright (c) 2000, 2015 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.pde.internal.ui.samples;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.preference.*;
+import org.eclipse.pde.internal.ui.preferences.TargetPlatformPreferenceNode;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+public class ShowTargetPlatformAction extends Action {
+
+	// Bring up Target Platform prefrences page
+	@Override
+	public void run() {
+		final IPreferenceNode targetNode = new TargetPlatformPreferenceNode();
+		PreferenceManager manager = new PreferenceManager();
+		manager.addToRoot(targetNode);
+		Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+		final PreferenceDialog dialog = new PreferenceDialog(shell, manager);
+		BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
+			@Override
+			public void run() {
+				dialog.create();
+				dialog.setMessage(targetNode.getLabelText());
+				dialog.open();
+			}
+		});
+	}
+
+}