*** empty log message ***
diff --git a/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
index 8c8097a..f06fc02 100644
--- a/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF
@@ -72,5 +72,6 @@
  org.eclipse.update.configurator,
  org.eclipse.help.base,
  org.eclipse.pde.runtime,
- org.eclipse.ltk.core.refactoring
+ org.eclipse.ltk.core.refactoring,
+ org.eclipse.core.variables
 Eclipse-AutoStart: true
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/AbstractLauncherTab.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/AbstractLauncherTab.java
index a069bcd..26b4158 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/AbstractLauncherTab.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/AbstractLauncherTab.java
@@ -18,10 +18,6 @@
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.SWT;
 
-/**
- * @version 	1.0
- * @author
- */
 public abstract class AbstractLauncherTab extends AbstractLaunchConfigurationTab {
 
 	protected void createStartingSpace(Composite parent, int span) {
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/BaseBlock.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/BaseBlock.java
new file mode 100644
index 0000000..336f041
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/BaseBlock.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.launcher;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.variables.IStringVariableManager;
+import org.eclipse.core.variables.VariablesPlugin;
+import org.eclipse.debug.ui.StringVariableSelectionDialog;
+import org.eclipse.pde.internal.ui.PDEPlugin;
+import org.eclipse.pde.internal.ui.PDEUIMessages;
+import org.eclipse.pde.internal.ui.util.SWTUtil;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ContainerSelectionDialog;
+
+public abstract class BaseBlock {
+	
+	protected AbstractLauncherTab fTab;
+
+	private Button fVariablesButton;
+	private Button fFileSystemButton;
+	private Button fWorkspaceButton;
+	
+	protected Text fLocationText;
+	
+	protected Listener fListener = new Listener();
+
+	class Listener extends SelectionAdapter implements ModifyListener {		
+		public void widgetSelected(SelectionEvent e) {
+			Object source= e.getSource();
+			if (source == fFileSystemButton) { 
+				handleBrowseFileSystem();
+			} else if (source == fWorkspaceButton) {
+				handleBrowseWorkspace();
+			} else if (source == fVariablesButton) {
+				handleInsertVariable();
+			} else {
+				fTab.updateLaunchConfigurationDialog();
+			}
+		}
+
+		public void modifyText(ModifyEvent e) {
+			fTab.updateLaunchConfigurationDialog();
+		}
+	}
+	
+	public BaseBlock(AbstractLauncherTab tab) {
+		fTab = tab;
+	}
+	
+	protected void createText(Composite parent, String text) {
+		Label label = new Label(parent, SWT.NONE);
+		label.setText(text); 
+
+		fLocationText = new Text(parent, SWT.SINGLE|SWT.BORDER);
+		fLocationText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		fLocationText.addModifyListener(fListener);
+	}
+	
+	protected void createButtons(Composite parent) {
+		fWorkspaceButton = createButton(parent, "Workspace..."); 
+		fFileSystemButton = createButton(parent, "File System..."); 
+		fVariablesButton = createButton(parent, "Variables..."); 	
+	}
+	
+	protected Button createButton(Composite parent, String text) {
+		Button button = new Button(parent, SWT.PUSH);
+		button.setText(text);
+		button.setLayoutData(new GridData());
+		button.addSelectionListener(fListener);
+		SWTUtil.setButtonDimensionHint(button);
+		return button;
+	}
+		
+	private void handleBrowseFileSystem() {
+		DirectoryDialog dialog = new DirectoryDialog(fTab.getControl().getShell());
+		dialog.setFilterPath(getLocation());
+		dialog.setText(PDEUIMessages.BasicLauncherTab_workspace_title); 
+		dialog.setMessage(PDEUIMessages.BasicLauncherTab_workspace_message); 
+		String result = dialog.open();
+		if (result != null)
+			fLocationText.setText(result);
+	}
+	
+	private void handleBrowseWorkspace() {
+		ContainerSelectionDialog dialog = 
+			new ContainerSelectionDialog(
+					PDEPlugin.getActiveWorkbenchShell(),
+					getContainer(), 
+					true,
+					"Choose a location relative to the workspace:"); 
+		if (dialog.open() == ContainerSelectionDialog.OK) {
+			IPath path = (IPath)dialog.getResult()[0];
+			fLocationText.setText("${workspace_loc:" + path.makeRelative().toString() + "}");
+		}
+	}
+	
+	protected IContainer getContainer() {
+		String path = getLocation();
+		if (path.length() > 0) {
+		    IResource res = null;
+		    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		    if (path.startsWith("${workspace_loc:")) { //$NON-NLS-1$
+		        IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
+			    try {
+                    path = manager.performStringSubstitution(path, false);
+                    IContainer[] containers = root.findContainersForLocation(new Path(path));
+                    if (containers.length > 0)
+                        res = containers[0];
+                } catch (CoreException e) {
+                }
+			} else {	    
+				res = root.findMember(path);
+			}
+			if (res instanceof IContainer) {
+				return (IContainer)res;
+			}
+		}
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+	
+	private void handleInsertVariable() {
+		StringVariableSelectionDialog dialog = 
+					new StringVariableSelectionDialog(PDEPlugin.getActiveWorkbenchShell());
+		if (dialog.open() == StringVariableSelectionDialog.OK)
+			fLocationText.insert(dialog.getVariableExpression());
+	}
+	
+	protected String getLocation() {
+		return fLocationText.getText().trim();
+	}
+	
+}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JREBlock.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JREBlock.java
new file mode 100644
index 0000000..385b0e0
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JREBlock.java
@@ -0,0 +1,221 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.launcher;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jface.preference.IPreferenceNode;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.pde.internal.ui.PDEUIMessages;
+import org.eclipse.pde.internal.ui.util.SWTUtil;
+import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class JREBlock {
+
+	private AbstractLauncherTab fTab;
+	private Listener fListener = new Listener();
+	private Button fJavawButton;
+	private Button fJavaButton;
+	private Combo fJreCombo;
+	private Text fBootstrap;
+
+	class Listener extends SelectionAdapter implements ModifyListener {		
+		public void widgetSelected(SelectionEvent e) {
+			fTab.updateLaunchConfigurationDialog();
+		}
+		public void modifyText(ModifyEvent e) {
+			fTab.updateLaunchConfigurationDialog();
+		}
+	}
+
+	public JREBlock(AbstractLauncherTab tab) {
+		fTab = tab;
+	}
+	
+	public void createControl(Composite parent) {
+		Group group = new Group(parent, SWT.NONE);
+		group.setText(PDEUIMessages.MainTab_jreSection); 
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		group.setLayout(layout);
+		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		createJavaExecutableSection(group);
+		createJRESection(group);
+		createBootstrapEntriesSection(group);
+	}
+	
+	protected void createJRESection(Composite parent) {
+		Label label = new Label(parent, SWT.NONE);
+		label.setText(PDEUIMessages.BasicLauncherTab_jre); 
+
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = layout.marginWidth = 0;
+		composite.setLayout(layout);
+		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		fJreCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
+		fJreCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		fJreCombo.addSelectionListener(fListener);
+		
+		Button button = new Button(composite, SWT.PUSH);
+		button.setText(PDEUIMessages.BasicLauncherTab_installedJREs); 
+		button.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				String currentVM = fJreCombo.getText();
+				IPreferenceNode node = new InstalledJREsPreferenceNode();
+				if (showPreferencePage(node)) {
+					fJreCombo.setItems(LauncherUtils.getVMInstallNames());
+					fJreCombo.setText(currentVM);
+					if (fJreCombo.getSelectionIndex() == -1)
+						fJreCombo.setText(LauncherUtils.getDefaultVMInstallName());
+				}
+			}
+			private boolean showPreferencePage(final IPreferenceNode targetNode) {
+				PreferenceManager manager = new PreferenceManager();
+				manager.addToRoot(targetNode);
+				final PreferenceDialog dialog =
+					new PreferenceDialog(fTab.getControl().getShell(), manager);
+				final boolean[] result = new boolean[] { false };
+				BusyIndicator.showWhile(fTab.getControl().getDisplay(), new Runnable() {
+					public void run() {
+						dialog.create();
+						dialog.setMessage(targetNode.getLabelText());
+						if (dialog.open() == PreferenceDialog.OK)
+							result[0] = true;
+					}
+				});
+				return result[0];
+			}
+		});
+		button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+		SWTUtil.setButtonDimensionHint(button);				
+	}
+	
+	protected void createJavaExecutableSection(Composite parent) {
+		Label label = new Label(parent, SWT.NONE);
+		label.setText(PDEUIMessages.BasicLauncherTab_javaExec); 
+
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = layout.marginWidth = 0;
+		layout.horizontalSpacing = 20;
+		composite.setLayout(layout);
+		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		fJavawButton = new Button(composite, SWT.RADIO);
+		fJavawButton.setText(PDEUIMessages.BasicLauncherTab_javaExecDefault); // 
+		fJavawButton.addSelectionListener(fListener);
+		
+		fJavaButton = new Button(composite, SWT.RADIO);
+		fJavaButton.setText("&java");	 //$NON-NLS-1$
+		fJavaButton.addSelectionListener(fListener);
+	}
+			
+	private void createBootstrapEntriesSection(Composite parent) {
+		Label label = new Label(parent, SWT.NONE);
+		label.setText(PDEUIMessages.BasicLauncherTab_bootstrap); 
+		
+		fBootstrap = new Text(parent, SWT.BORDER);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.widthHint = 300;
+		fBootstrap.setLayoutData(gd);
+		fBootstrap.addModifyListener(fListener);
+	}
+	
+	public void initializeFrom(ILaunchConfiguration config) throws CoreException {
+		initializeJRESection(config);
+		initializeBootstrapEntriesSection(config);
+	}
+	
+	private void initializeJRESection(ILaunchConfiguration config) throws CoreException {
+		String javaCommand = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, "javaw"); //$NON-NLS-1$
+		fJavawButton.setSelection(javaCommand.equals("javaw")); //$NON-NLS-1$
+		fJavaButton.setSelection(!fJavawButton.getSelection());
+		
+		fJreCombo.setItems(LauncherUtils.getVMInstallNames());
+		String vmInstallName =
+			config.getAttribute(IPDELauncherConstants.VMINSTALL, LauncherUtils.getDefaultVMInstallName());
+		fJreCombo.setText(vmInstallName);
+		if (fJreCombo.getSelectionIndex() == -1)
+			fJreCombo.setText(LauncherUtils.getDefaultVMInstallName());
+	}
+	
+	private void initializeBootstrapEntriesSection(ILaunchConfiguration config) throws CoreException {
+		fBootstrap.setText(config.getAttribute(IPDELauncherConstants.BOOTSTRAP_ENTRIES, "")); //$NON-NLS-1$
+	}
+	
+	public void performApply(ILaunchConfigurationWorkingCopy config) {
+		saveJRESection(config);
+		saveBootstrapEntriesSection(config);
+	}
+	
+	protected void saveJRESection(ILaunchConfigurationWorkingCopy config) {	
+		try {
+			String javaCommand = fJavawButton.getSelection() ? null : "java"; //$NON-NLS-1$
+			config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, javaCommand);
+			
+			if (fJreCombo.getSelectionIndex() == -1)
+				return;
+
+			String jre = fJreCombo.getText();
+			if (config.getAttribute(IPDELauncherConstants.VMINSTALL, (String) null) != null) {
+				config.setAttribute(IPDELauncherConstants.VMINSTALL, jre);
+			} else {
+				config.setAttribute(
+						IPDELauncherConstants.VMINSTALL,
+					jre.equals(LauncherUtils.getDefaultVMInstallName()) ? null : jre);
+			}
+		} catch (CoreException e) {
+		}
+	}
+
+	protected void saveBootstrapEntriesSection(ILaunchConfigurationWorkingCopy config) {
+		config.setAttribute(IPDELauncherConstants.BOOTSTRAP_ENTRIES, fBootstrap.getText().trim());
+	}
+	
+	public void setDefaults(ILaunchConfigurationWorkingCopy config) {		
+		config.setAttribute(IPDELauncherConstants.BOOTSTRAP_ENTRIES, ""); //$NON-NLS-1$
+	}
+	
+	protected IStatus validateJRESelection() {
+		if (fJreCombo.getSelectionIndex() == -1) {
+			return AbstractLauncherTab.createStatus(
+				IStatus.ERROR,
+				PDEUIMessages.BasicLauncherTab_noJRE); 
+		}
+		return AbstractLauncherTab.createStatus(IStatus.OK, ""); //$NON-NLS-1$
+	}
+
+
+
+}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitProgramBlock.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitProgramBlock.java
new file mode 100644
index 0000000..cea9911
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitProgramBlock.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.launcher;
+
+import java.util.TreeSet;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.pde.internal.ui.PDEUIMessages;
+import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
+
+public class JUnitProgramBlock extends ProgramBlock {
+
+	public JUnitProgramBlock(AbstractLauncherTab tab) {
+		super(tab);
+	}
+
+	protected String getApplicationAttribute() {
+		return IPDELauncherConstants.APP_TO_TEST;
+	}
+	
+	public void setDefaults(ILaunchConfigurationWorkingCopy config) {
+		if (!JUnitLaunchConfiguration.requiresUI(config))
+			config.setAttribute(IPDELauncherConstants.APPLICATION, 
+					JUnitLaunchConfiguration.CORE_APPLICATION);
+		else
+			super.setDefaults(config);
+	}
+	
+	protected String[] getApplicationNames() {
+		TreeSet result = new TreeSet();
+		result.add(PDEUIMessages.JUnitArgumentsTab_headless); 
+		String[] appNames = super.getApplicationNames();
+		for (int i = 0; i < appNames.length; i++) {
+			result.add(appNames[i]);
+		}
+		return (String[])result.toArray(new String[result.size()]);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.pde.internal.ui.launcher.BasicLauncherTab#initializeApplicationSection(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	protected void initializeApplicationSection(ILaunchConfiguration config)
+			throws CoreException {
+		String application = config.getAttribute(IPDELauncherConstants.APPLICATION, (String)null);
+		if (JUnitLaunchConfiguration.CORE_APPLICATION.equals(application)) 
+			fApplicationCombo.setText(PDEUIMessages.JUnitArgumentsTab_headless); 
+		else
+			super.initializeApplicationSection(config);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.pde.internal.ui.launcher.BasicLauncherTab#saveApplicationSection(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	protected void saveApplicationSection(ILaunchConfigurationWorkingCopy config) {
+		if (fApplicationCombo.getText().equals(PDEUIMessages.JUnitArgumentsTab_headless)) { 
+			config.setAttribute(IPDELauncherConstants.APPLICATION, JUnitLaunchConfiguration.CORE_APPLICATION);
+			config.setAttribute(IPDELauncherConstants.APP_TO_TEST, (String)null);
+		} else {
+			config.setAttribute(IPDELauncherConstants.APPLICATION, (String)null);
+			super.saveApplicationSection(config);
+		}
+	}
+	
+}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/ProgramBlock.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/ProgramBlock.java
new file mode 100644
index 0000000..f19fb65
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/ProgramBlock.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.launcher;
+
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.pde.internal.core.PDECore;
+import org.eclipse.pde.internal.core.TargetPlatform;
+import org.eclipse.pde.internal.ui.PDEUIMessages;
+import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+public class ProgramBlock {
+
+	protected Combo fApplicationCombo;
+	private Button fProductButton;
+	private Combo fProductCombo;
+	private Button fApplicationButton;
+	private AbstractLauncherTab fTab;
+	private Listener fListener = new Listener();
+
+	class Listener extends SelectionAdapter {		
+		public void widgetSelected(SelectionEvent e) {
+			fTab.updateLaunchConfigurationDialog();
+		}
+	}
+	
+	public ProgramBlock(AbstractLauncherTab tab) {
+		fTab = tab;
+	}
+	
+	public void createControl(Composite parent) {
+		Group group = new Group(parent, SWT.NONE);
+		group.setText(PDEUIMessages.BasicLauncherTab_programToRun); 
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		group.setLayout(layout);
+		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+				
+		createProductSection(group);		
+		createApplicationSection(group);
+	}
+	
+	protected void createProductSection(Composite parent) {
+		fProductButton = new Button(parent, SWT.RADIO);
+		fProductButton.setText(PDEUIMessages.BasicLauncherTab_runProduct); 
+		fProductButton.addSelectionListener(fListener);
+		
+		fProductCombo = new Combo(parent, SWT.READ_ONLY|SWT.DROP_DOWN);
+		fProductCombo.setItems(TargetPlatform.getProductNames());
+		fProductCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		fProductCombo.addSelectionListener(fListener);
+	}
+	
+	protected void createApplicationSection(Composite parent) {
+		fApplicationButton = new Button(parent, SWT.RADIO);
+		fApplicationButton.setText(PDEUIMessages.BasicLauncherTab_runApplication); 
+			
+		fApplicationCombo = new Combo(parent, SWT.READ_ONLY|SWT.DROP_DOWN);
+		fApplicationCombo.setItems(getApplicationNames());
+		fApplicationCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		fApplicationCombo.addSelectionListener(fListener);
+	}
+		
+	public void initializeFrom(ILaunchConfiguration config) throws CoreException {
+		initializeProductSection(config);
+		initializeApplicationSection(config);
+		
+		boolean useProduct = 
+					config.getAttribute(IPDELauncherConstants.USE_PRODUCT, false)
+					&& PDECore.getDefault().getModelManager().isOSGiRuntime() 
+					&& fProductCombo.getItemCount() > 0;
+		fApplicationButton.setSelection(!useProduct);
+		fApplicationCombo.setEnabled(!useProduct);
+		fProductButton.setSelection(useProduct);
+		fProductButton.setEnabled(fProductCombo.getItemCount() > 0);
+		fProductCombo.setEnabled(useProduct);
+	}
+	
+	protected void initializeProductSection(ILaunchConfiguration config) throws CoreException {
+		if (fProductCombo.getItemCount() > 0) {
+			String productName = config.getAttribute(IPDELauncherConstants.PRODUCT, (String)null);
+			int index = productName == null ? -1 : fProductCombo.indexOf(productName);
+			if (index == -1)
+				index = 0;
+			fProductCombo.setText(fProductCombo.getItem(index));
+		}
+	}
+
+	protected void initializeApplicationSection(ILaunchConfiguration config) throws CoreException {
+		
+		String attribute = getApplicationAttribute();
+		
+		// first see if the application name has been set on the launch config
+		String application = config.getAttribute(attribute, (String) null);
+		if (application == null
+			|| fApplicationCombo.indexOf(application) == -1) {
+			application = null;
+			
+			// check if the user has entered the -application arg in the program arg field
+			StringTokenizer tokenizer =
+				new StringTokenizer(config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, "")); //$NON-NLS-1$
+			while (tokenizer.hasMoreTokens()) {
+				String token = tokenizer.nextToken();
+				if (token.equals("-application") && tokenizer.hasMoreTokens()) { //$NON-NLS-1$
+					application = tokenizer.nextToken();
+					break;
+				}
+			}
+			
+			int index = -1;
+			if (application != null)
+				index = fApplicationCombo.indexOf(application);
+			
+			// use default application as specified in the install.ini of the target platform
+			if (index == -1)
+				index = fApplicationCombo.indexOf(LauncherUtils.getDefaultApplicationName());
+			
+			if (index != -1) {
+				fApplicationCombo.setText(fApplicationCombo.getItem(index));
+			} else if (fApplicationCombo.getItemCount() > 0) {
+				fApplicationCombo.setText(fApplicationCombo.getItem(0));
+			}
+		} else {
+			fApplicationCombo.setText(application);
+		}
+	}
+	
+	public void performApply(ILaunchConfigurationWorkingCopy config) {
+		saveApplicationSection(config);
+		saveProductSection(config);
+	}
+	
+	protected void saveProductSection(ILaunchConfigurationWorkingCopy config) {
+		config.setAttribute(IPDELauncherConstants.USE_PRODUCT, fProductButton.getSelection());
+		config.setAttribute(IPDELauncherConstants.PRODUCT, fProductCombo.getText());
+	}
+
+	protected void saveApplicationSection(ILaunchConfigurationWorkingCopy config) {
+		String text = fApplicationCombo.getText();
+		String attribute = getApplicationAttribute();
+		if (text.length() == 0 || text.equals(LauncherUtils.getDefaultApplicationName()))
+			config.setAttribute(attribute, (String) null);
+		else
+			config.setAttribute(attribute, text);
+	}
+	
+	public void setDefaults(ILaunchConfigurationWorkingCopy config) {		
+		String product = TargetPlatform.getDefaultProduct();
+		if (product != null) {
+			config.setAttribute(IPDELauncherConstants.USE_PRODUCT, true);
+			config.setAttribute(IPDELauncherConstants.PRODUCT, product); 
+		}
+	}
+	
+	protected String[] getApplicationNames() {
+		return TargetPlatform.getApplicationNames();
+	}
+	
+	protected String getApplicationAttribute() {
+		return IPDELauncherConstants.APPLICATION;
+	}
+		
+}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/WorkspaceDataBlock.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/WorkspaceDataBlock.java
new file mode 100644
index 0000000..15c874a
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/WorkspaceDataBlock.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.launcher;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.pde.internal.ui.PDEUIMessages;
+import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+public class WorkspaceDataBlock extends BaseBlock {
+
+	private Button fClearWorkspaceCheck;
+	private Button fAskClearCheck;
+	
+	public WorkspaceDataBlock(AbstractLauncherTab tab) {
+		super(tab);
+	}
+	
+	public void createControl(Composite parent) {
+		Group group = new Group(parent, SWT.NONE);
+		group.setText(PDEUIMessages.BasicLauncherTab_workspace); 
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		group.setLayout(layout);
+		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		createText(group, PDEUIMessages.BasicLauncherTab_location);
+		
+		Composite buttons = new Composite(group, SWT.NONE);
+		layout = new GridLayout(4, false);
+		layout.marginHeight = layout.marginWidth = 0;
+		buttons.setLayout(layout);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 2;
+		buttons.setLayoutData(gd);
+		
+		fClearWorkspaceCheck = new Button(buttons, SWT.CHECK);
+		fClearWorkspaceCheck.setText(PDEUIMessages.BasicLauncherTab_clear);	
+		fClearWorkspaceCheck.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		fClearWorkspaceCheck.addSelectionListener(fListener);
+		
+		createButtons(buttons);
+		
+		fAskClearCheck = new Button(group, SWT.CHECK);
+		fAskClearCheck.setText(PDEUIMessages.BasicLauncherTab_askClear);
+		gd = new GridData();
+		gd.horizontalSpan = 2;
+		fAskClearCheck.setLayoutData(gd);
+		fAskClearCheck.addSelectionListener(fListener);
+	}
+	
+	public void performApply(ILaunchConfigurationWorkingCopy config) {
+		config.setAttribute(IPDELauncherConstants.LOCATION, getLocation());
+		config.setAttribute(IPDELauncherConstants.DOCLEAR, fClearWorkspaceCheck.getSelection());
+		config.setAttribute(IPDELauncherConstants.ASKCLEAR, fAskClearCheck.getSelection());
+	}
+	
+	public void initializeFrom(ILaunchConfiguration configuration) throws CoreException {
+		String location = configuration.getAttribute(IPDELauncherConstants.LOCATION, (String)null);
+
+		// backward compatibility
+		if (location == null) {	
+			location = configuration.getAttribute(
+										IPDELauncherConstants.LOCATION + "0", 
+									    LauncherUtils.getDefaultWorkspace());
+		}
+		fLocationText.setText(location);
+		fClearWorkspaceCheck.setSelection(configuration.getAttribute(IPDELauncherConstants.DOCLEAR, false));
+		fAskClearCheck.setSelection(configuration.getAttribute(IPDELauncherConstants.ASKCLEAR, true));
+		fAskClearCheck.setEnabled(fClearWorkspaceCheck.getSelection());
+		validateWorkspaceSelection();
+	}
+	
+	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {		
+		configuration.setAttribute(IPDELauncherConstants.LOCATION, LauncherUtils.getDefaultWorkspace()); //$NON-NLS-1$
+		configuration.setAttribute(IPDELauncherConstants.DOCLEAR, false);
+		configuration.setAttribute(IPDELauncherConstants.ASKCLEAR, true);
+	}
+	
+	private IStatus validateWorkspaceSelection() {
+		String location = getLocation();
+		if (!Path.ROOT.isValidPath(location)) {
+			return AbstractLauncherTab.createStatus(
+				IStatus.ERROR,
+				PDEUIMessages.BasicLauncherTab_invalidWorkspace); 
+		}
+		
+		IPath curr = new Path(location);
+		if (curr.segmentCount() == 0 && curr.getDevice() == null) {
+			return AbstractLauncherTab.createStatus(
+				IStatus.ERROR,
+				PDEUIMessages.BasicLauncherTab_noWorkspace); 
+		}
+
+		return AbstractLauncherTab.createStatus(IStatus.OK, ""); //$NON-NLS-1$
+	}
+	
+}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/IPDELauncherConstants.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/IPDELauncherConstants.java
new file mode 100644
index 0000000..9893947
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/IPDELauncherConstants.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.launcher;
+
+public interface IPDELauncherConstants {
+	// Workspace data settings
+	String LOCATION = "location"; //$NON-NLS-1$
+	String DOCLEAR = "clearws"; //$NON-NLS-1$
+	String ASKCLEAR = "askclear"; //$NON-NLS-1$
+	
+	// Program to run
+	String APPLICATION = "application"; //$NON-NLS-1$
+	String PRODUCT = "product"; //$NON-NLS-1$
+	String USE_PRODUCT = "useProduct"; //$NON-NLS-1$
+	String APP_TO_TEST = "testApplication"; //$NON-NLS-1$
+	
+	// Command line settings
+	String VMINSTALL = "vminstall"; //$NON-NLS-1$
+	String BOOTSTRAP_ENTRIES = "bootstrap"; //$NON-NLS-1$
+	
+	// Plug-ins and Fragments settings
+	String USE_DEFAULT = "default"; //$NON-NLS-1$
+	String USEFEATURES = "usefeatures"; //$NON-NLS-1$
+	String WSPROJECT = "wsproject"; //$NON-NLS-1$
+	String EXTPLUGINS = "extplugins"; //$NON-NLS-1$
+	String INCLUDE_OPTIONAL = "includeOptional"; //$NON-NLS-1$
+	String INCLUDE_FRAGMENTS = "includeFragments"; //$NON-NLS-1$
+	String AUTOMATIC_ADD = "automaticAdd"; //$NON-NLS-1$
+	
+	// Tracing settings
+	String TRACING = "tracing"; //$NON-NLS-1$
+	String TRACING_OPTIONS = "tracingOptions"; //$NON-NLS-1$
+	String TRACING_SELECTED_PLUGIN = "selectedPlugin"; //$NON-NLS-1$
+	String TRACING_CHECKED = "checked"; //$NON-NLS-1$
+	String TRACING_NONE = "[NONE]"; //$NON-NLS-1$
+	
+	// Configuration tab
+	String CONFIG_USE_DEFAULT_AREA = "useDefaultConfigArea"; //$NON-NLS-1$
+	String CONFIG_LOCATION = "configLocation"; //$NON-NLS-1$
+	String CONFIG_CLEAR_AREA = "clearConfig"; //$NON-NLS-1$
+	
+	String CONFIG_GENERATE_DEFAULT = "useDefaultConfig"; //$NON-NLS-1$
+	String CONFIG_TEMPLATE_LOCATION = "templateConfig";	 //$NON-NLS-1$
+	
+	// .product-specific marker
+	String PRODUCT_FILE = "productFile"; //$NON-NLS-1$
+			
+}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/MainTab.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/MainTab.java
index 46a0470..a3b3102 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/MainTab.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/ui/launcher/MainTab.java
@@ -10,82 +10,38 @@
  *******************************************************************************/
 package org.eclipse.pde.ui.launcher;
 
-import java.util.ArrayList;
-import java.util.StringTokenizer;
-
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
 import org.eclipse.debug.core.ILaunchConfiguration;
 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
-import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
 import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.preference.IPreferenceNode;
-import org.eclipse.jface.preference.PreferenceDialog;
-import org.eclipse.jface.preference.PreferenceManager;
-import org.eclipse.pde.internal.core.PDECore;
-import org.eclipse.pde.internal.core.TargetPlatform;
 import org.eclipse.pde.internal.ui.IHelpContextIds;
 import org.eclipse.pde.internal.ui.PDEPlugin;
 import org.eclipse.pde.internal.ui.PDEPluginImages;
 import org.eclipse.pde.internal.ui.PDEUIMessages;
 import org.eclipse.pde.internal.ui.launcher.AbstractLauncherTab;
 import org.eclipse.pde.internal.ui.launcher.ILauncherSettings;
-import org.eclipse.pde.internal.ui.launcher.InstalledJREsPreferenceNode;
-import org.eclipse.pde.internal.ui.launcher.LauncherUtils;
-import org.eclipse.pde.internal.ui.util.SWTUtil;
+import org.eclipse.pde.internal.ui.launcher.JREBlock;
+import org.eclipse.pde.internal.ui.launcher.ProgramBlock;
+import org.eclipse.pde.internal.ui.launcher.WorkspaceDataBlock;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.BusyIndicator;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.DirectoryDialog;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.PlatformUI;
 
-public class MainTab
-	extends AbstractLauncherTab
-	implements ILauncherSettings {
-
-	private Combo fWorkspaceCombo;
-	private Button fFileSystemButton;
-	private Button fClearWorkspaceCheck;
-	private Button fAskClearCheck;
-	private Combo fJreCombo;
-	private Image fImage;
-	private Button fJavawButton;
-	private Button fJavaButton;
-
-	private IStatus fJreSelectionStatus;
-	private IStatus fWorkspaceSelectionStatus;
+public class MainTab extends AbstractLauncherTab implements ILauncherSettings {
 	
-	private boolean fBlockChanges = false;
-
-	protected Combo fApplicationCombo;
-
-	private Text fBootstrap;
-
-	private Combo fProductCombo;
-
-	private Button fProductButton;
-
-	private Button fApplicationButton;
-	private Button fWorkspaceButton;
-	private Button fVariablesButton;
+	private WorkspaceDataBlock fDataBlock;
+	private ProgramBlock fProgramBlock;
+	private JREBlock fJreBlock;
+	
+	private Image fImage;
 
 	public MainTab() {
-		fJreSelectionStatus = createStatus(IStatus.OK, ""); //$NON-NLS-1$
-		fWorkspaceSelectionStatus = createStatus(IStatus.OK, ""); //$NON-NLS-1$
+		fDataBlock = new WorkspaceDataBlock(this);
+		fProgramBlock = new ProgramBlock(this);
+		fJreBlock = new JREBlock(this);
 		fImage = PDEPluginImages.DESC_MAIN_TAB.createImage();
 	}
 
@@ -101,534 +57,38 @@
 		composite.setLayout(layout);
 		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 		
-		createWorkspaceDataSection(composite);
-		createProgramSection(composite);
-		createCommandLineSettingsSection(composite);
+		fDataBlock.createControl(composite);		
+		fProgramBlock.createControl(composite);
+		fJreBlock.createControl(composite);
 		
 		setControl(composite);
 		Dialog.applyDialogFont(composite);
 		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IHelpContextIds.LAUNCHER_BASIC);
 	}
 	
-	private void createProgramSection(Composite composite) {
-		Group group = new Group(composite, SWT.NONE);
-		group.setText(PDEUIMessages.BasicLauncherTab_programToRun); 
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 2;
-		group.setLayout(layout);
-		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-				
-		createProductSection(group);		
-		createApplicationSection(group);
-	}
-
-	protected void createWorkspaceDataSection(Composite composite) {
-		Group group = new Group(composite, SWT.NONE);
-		group.setText(PDEUIMessages.BasicLauncherTab_workspace); 
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 2;
-		group.setLayout(layout);
-		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-		Label label = new Label(group, SWT.NULL);
-		label.setText(PDEUIMessages.BasicLauncherTab_location); 
-
-		fWorkspaceCombo = new Combo(group, SWT.DROP_DOWN);
-		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-		fWorkspaceCombo.setLayoutData(gd);
-		fWorkspaceCombo.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				fWorkspaceSelectionStatus = validateWorkspaceSelection();
-				if (!fBlockChanges) 
-					updateStatus();
-			}
-		});
-		fWorkspaceCombo.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				fWorkspaceSelectionStatus = validateWorkspaceSelection();				
-				if (!fBlockChanges)
-					updateStatus();
-			}
-		});
-		
-		Composite buttons = new Composite(group, SWT.NONE);
-		layout = new GridLayout(4, false);
-		layout.marginHeight = layout.marginWidth = 0;
-		buttons.setLayout(layout);
-		gd = new GridData(GridData.FILL_HORIZONTAL);
-		gd.horizontalSpan = 2;
-		buttons.setLayoutData(gd);
-		
-		fClearWorkspaceCheck = new Button(buttons, SWT.CHECK);
-		fClearWorkspaceCheck.setText(PDEUIMessages.BasicLauncherTab_clear);
-		fClearWorkspaceCheck.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		fClearWorkspaceCheck.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				fAskClearCheck.setEnabled(fClearWorkspaceCheck.getSelection());
-				updateLaunchConfigurationDialog();
-			}
-		});
-
-		fWorkspaceButton = new Button(buttons, SWT.PUSH);
-		fWorkspaceButton.setText("Workspace..."); 
-		fWorkspaceButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-		fWorkspaceButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IPath chosen = chooseWorkspaceLocation();
-				if (chosen != null) {
-					String destination = chosen.toOSString();
-					if (fWorkspaceCombo.indexOf(destination) == -1)
-						fWorkspaceCombo.add(destination, 0);
-					fWorkspaceCombo.setText(destination);
-					if (fClearWorkspaceCheck.getSelection())
-						fClearWorkspaceCheck.setSelection(false);
-					updateStatus();
-				}
-			}
-		});
-		SWTUtil.setButtonDimensionHint(fWorkspaceButton);
-
-		fFileSystemButton = new Button(buttons, SWT.PUSH);
-		fFileSystemButton.setText("File System..."); 
-		fFileSystemButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-		fFileSystemButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IPath chosen = chooseWorkspaceLocation();
-				if (chosen != null) {
-					String destination = chosen.toOSString();
-					if (fWorkspaceCombo.indexOf(destination) == -1)
-						fWorkspaceCombo.add(destination, 0);
-					fWorkspaceCombo.setText(destination);
-					if (fClearWorkspaceCheck.getSelection())
-						fClearWorkspaceCheck.setSelection(false);
-					updateStatus();
-				}
-			}
-		});
-		SWTUtil.setButtonDimensionHint(fFileSystemButton);
-
-		fVariablesButton = new Button(buttons, SWT.PUSH);
-		fVariablesButton.setText("Variables..."); 
-		fVariablesButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-		fVariablesButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				IPath chosen = chooseWorkspaceLocation();
-				if (chosen != null) {
-					String destination = chosen.toOSString();
-					if (fWorkspaceCombo.indexOf(destination) == -1)
-						fWorkspaceCombo.add(destination, 0);
-					fWorkspaceCombo.setText(destination);
-					if (fClearWorkspaceCheck.getSelection())
-						fClearWorkspaceCheck.setSelection(false);
-					updateStatus();
-				}
-			}
-		});
-		SWTUtil.setButtonDimensionHint(fVariablesButton);
-
-		
-		fAskClearCheck = new Button(group, SWT.CHECK);
-		fAskClearCheck.setText(PDEUIMessages.BasicLauncherTab_askClear); 
-		gd = new GridData();
-		gd.horizontalSpan = 2;
-		fAskClearCheck.setLayoutData(gd);
-		fAskClearCheck.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				updateLaunchConfigurationDialog();
-			}
-		});	
-	}
-	
-	protected void createCommandLineSettingsSection(Composite composite) {
-		Group group = new Group(composite, SWT.NONE);
-		group.setText(PDEUIMessages.MainTab_jreSection); 
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 2;
-		group.setLayout(layout);
-		group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		
-		createJavaExecutableSection(group);
-		createJRESection(group);
-		createBootstrapEntriesSection(group);
-	}
-	
-	protected void createProductSection(Composite parent) {
-		fProductButton = new Button(parent, SWT.RADIO);
-		fProductButton.setText(PDEUIMessages.BasicLauncherTab_runProduct); 
-		fProductButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				boolean selected = fProductButton.getSelection();
-				fApplicationCombo.setEnabled(!selected);
-				fProductCombo.setEnabled(selected);
-				updateLaunchConfigurationDialog();
-			}
-		});
-		
-		fProductCombo = new Combo(parent, SWT.READ_ONLY|SWT.DROP_DOWN);
-		fProductCombo.setItems(TargetPlatform.getProductNames());
-		fProductCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		fProductCombo.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				updateLaunchConfigurationDialog();
-			}
-		});		
-	}
-	
-	protected void createApplicationSection(Composite parent) {
-		fApplicationButton = new Button(parent, SWT.RADIO);
-		fApplicationButton.setText(PDEUIMessages.BasicLauncherTab_runApplication); 
-			
-		fApplicationCombo = new Combo(parent, SWT.READ_ONLY|SWT.DROP_DOWN);
-		fApplicationCombo.setItems(getApplicationNames());
-		fApplicationCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		fApplicationCombo.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				updateLaunchConfigurationDialog();
-			}
-		});		
-	}
-	
-	protected String[] getApplicationNames() {
-		return TargetPlatform.getApplicationNames();
-	}
-	
-	protected String getApplicationAttribute() {
-		return APPLICATION;
-	}
-		
-	protected void createJRESection(Composite parent) {
-		Label label = new Label(parent, SWT.NONE);
-		label.setText(PDEUIMessages.BasicLauncherTab_jre); 
-
-		Composite composite = new Composite(parent, SWT.NONE);
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 2;
-		layout.marginHeight = layout.marginWidth = 0;
-		composite.setLayout(layout);
-		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		
-		fJreCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
-		fJreCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		fJreCombo.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				fJreSelectionStatus = validateJRESelection();
-				updateStatus();
-			}
-		});
-		
-		Button button = new Button(composite, SWT.PUSH);
-		button.setText(PDEUIMessages.BasicLauncherTab_installedJREs); 
-		button.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				String currentVM = fJreCombo.getText();
-				IPreferenceNode node = new InstalledJREsPreferenceNode();
-				if (showPreferencePage(node)) {
-					fJreCombo.setItems(LauncherUtils.getVMInstallNames());
-					fJreCombo.setText(currentVM);
-					if (fJreCombo.getSelectionIndex() == -1)
-						fJreCombo.setText(LauncherUtils.getDefaultVMInstallName());
-				}
-			}
-			private boolean showPreferencePage(final IPreferenceNode targetNode) {
-				PreferenceManager manager = new PreferenceManager();
-				manager.addToRoot(targetNode);
-				final PreferenceDialog dialog =
-					new PreferenceDialog(getControl().getShell(), manager);
-				final boolean[] result = new boolean[] { false };
-				BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
-					public void run() {
-						dialog.create();
-						dialog.setMessage(targetNode.getLabelText());
-						if (dialog.open() == PreferenceDialog.OK)
-							result[0] = true;
-					}
-				});
-				return result[0];
-			}
-		});
-		button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-		SWTUtil.setButtonDimensionHint(button);				
-	}
-	
-	protected void createJavaExecutableSection(Composite parent) {
-		Label label = new Label(parent, SWT.NONE);
-		label.setText(PDEUIMessages.BasicLauncherTab_javaExec); 
-
-		Composite composite = new Composite(parent, SWT.NONE);
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 2;
-		layout.marginHeight = layout.marginWidth = 0;
-		layout.horizontalSpacing = 20;
-		composite.setLayout(layout);
-		composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-		
-		fJavawButton = new Button(composite, SWT.RADIO);
-		fJavawButton.setText(PDEUIMessages.BasicLauncherTab_javaExecDefault); // 
-		fJavawButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				updateLaunchConfigurationDialog();
-			}
-		});
-		
-		fJavaButton = new Button(composite, SWT.RADIO);
-		fJavaButton.setText("&java");	 //$NON-NLS-1$
-		fJavaButton.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				updateLaunchConfigurationDialog();
-			}
-		});
-	}
-			
-	private void createBootstrapEntriesSection(Composite parent) {
-		Label label = new Label(parent, SWT.NONE);
-		label.setText(PDEUIMessages.BasicLauncherTab_bootstrap); 
-		
-		fBootstrap = new Text(parent, SWT.BORDER);
-		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
-		gd.widthHint = 300;
-		fBootstrap.setLayoutData(gd);
-		fBootstrap.addModifyListener(new ModifyListener() {
-			public void modifyText(ModifyEvent e) {
-				if (!fBlockChanges)	
-					updateLaunchConfigurationDialog();
-			}
-		});		
-	}
-
 	public void initializeFrom(ILaunchConfiguration config) {
 		try {
-			fBlockChanges = true;			
-			initializeWorkspaceDataSection(config);
-			initializeJRESection(config);
-			initializeProgramToRunSection(config);
-			initializeBootstrapEntriesSection(config);	
-			fWorkspaceSelectionStatus = validateWorkspaceSelection();
-			fJreSelectionStatus = validateJRESelection();
-			updateStatus();
+			fDataBlock.initializeFrom(config);
+			fProgramBlock.initializeFrom(config);
+			fJreBlock.initializeFrom(config);
 		} catch (CoreException e) {
 			PDEPlugin.logException(e);
 		} finally {
-			fBlockChanges = false;
 		}
 	}
 	
-	protected void initializeProgramToRunSection(ILaunchConfiguration config) throws CoreException {
-		initializeApplicationSection(config);
-		initializeProductSection(config);
-		
-		boolean useProduct = config.getAttribute(USE_PRODUCT, false)
-			&& PDECore.getDefault().getModelManager().isOSGiRuntime() 
-			&& fProductCombo.getItemCount() > 0;
-		fApplicationButton.setSelection(!useProduct);
-		fApplicationCombo.setEnabled(!useProduct);
-		fProductButton.setSelection(useProduct);
-		fProductButton.setEnabled(fProductCombo.getItemCount() > 0);
-		fProductCombo.setEnabled(useProduct);
-	}
-	
-	protected void initializeProductSection(ILaunchConfiguration config) throws CoreException {
-		if (fProductCombo.getItemCount() > 0) {
-			String productName = config.getAttribute(PRODUCT, (String)null);
-			int index = productName == null ? -1 : fProductCombo.indexOf(productName);
-			if (index == -1)
-				index = 0;
-			fProductCombo.setText(fProductCombo.getItem(index));
-		}
-	}
-
-	protected void initializeApplicationSection(ILaunchConfiguration config)
-		throws CoreException {
-		
-		String attribute = getApplicationAttribute();
-		
-		// first see if the application name has been set on the launch config
-		String application = config.getAttribute(attribute, (String) null);
-		if (application == null
-			|| fApplicationCombo.indexOf(application) == -1) {
-			application = null;
-			
-			// check if the user has entered the -application arg in the program arg field
-			StringTokenizer tokenizer =
-				new StringTokenizer(config.getAttribute(PROGARGS, "")); //$NON-NLS-1$
-			while (tokenizer.hasMoreTokens()) {
-				String token = tokenizer.nextToken();
-				if (token.equals("-application") && tokenizer.hasMoreTokens()) { //$NON-NLS-1$
-					application = tokenizer.nextToken();
-					break;
-				}
-			}
-			
-			int index = -1;
-			if (application != null)
-				index = fApplicationCombo.indexOf(application);
-			
-			// use default application as specified in the install.ini of the target platform
-			if (index == -1)
-				index = fApplicationCombo.indexOf(LauncherUtils.getDefaultApplicationName());
-			
-			if (index != -1) {
-				fApplicationCombo.setText(fApplicationCombo.getItem(index));
-			} else if (fApplicationCombo.getItemCount() > 0) {
-				fApplicationCombo.setText(fApplicationCombo.getItem(0));
-			}
-		} else {
-			fApplicationCombo.setText(application);
-		}
-	}
-
-	protected void initializeWorkspaceDataSection(ILaunchConfiguration config)
-		throws CoreException {
-		ArrayList items = new ArrayList();
-		for (int i = 0; i < 6; i++) {
-			String curr =
-				config.getAttribute(LOCATION + String.valueOf(i), (String) null);
-			if (curr != null && !items.contains(curr)) {
-				items.add(curr);
-			}
-		}
-
-		fWorkspaceCombo.setItems((String[]) items.toArray(new String[items.size()]));
-		if (fWorkspaceCombo.getItemCount() > 0)
-			fWorkspaceCombo.setText(items.get(0).toString());
-
-		fClearWorkspaceCheck.setSelection(config.getAttribute(DOCLEAR, false));
-		fAskClearCheck.setSelection(config.getAttribute(ASKCLEAR, true));
-		fAskClearCheck.setEnabled(fClearWorkspaceCheck.getSelection());
-	}
-	
-	protected void initializeJRESection(ILaunchConfiguration config) throws CoreException {
-		String javaCommand = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, "javaw"); //$NON-NLS-1$
-		fJavawButton.setSelection(javaCommand.equals("javaw")); //$NON-NLS-1$
-		fJavaButton.setSelection(!fJavawButton.getSelection());
-		
-		fJreCombo.setItems(LauncherUtils.getVMInstallNames());
-		String vmInstallName =
-			config.getAttribute(VMINSTALL, LauncherUtils.getDefaultVMInstallName());
-		fJreCombo.setText(vmInstallName);
-		if (fJreCombo.getSelectionIndex() == -1)
-			fJreCombo.setText(LauncherUtils.getDefaultVMInstallName());
-	}
-	
-	private void initializeBootstrapEntriesSection(ILaunchConfiguration config) throws CoreException {
-		fBootstrap.setText(config.getAttribute(BOOTSTRAP_ENTRIES, "")); //$NON-NLS-1$
-	}
-
 	public void setDefaults(ILaunchConfigurationWorkingCopy config) {
-		config.setAttribute(LOCATION + "0", LauncherUtils.getDefaultWorkspace()); //$NON-NLS-1$
-		config.setAttribute(DOCLEAR, false);
-		config.setAttribute(ASKCLEAR, true);
-		config.setAttribute(PROGARGS, ""); //$NON-NLS-1$
-		config.setAttribute(VMARGS,""); //$NON-NLS-1$
-		config.setAttribute(BOOTSTRAP_ENTRIES, ""); //$NON-NLS-1$
-		String product = TargetPlatform.getDefaultProduct();
-		if (product != null) {
-			config.setAttribute(USE_PRODUCT, true);
-			config.setAttribute(PRODUCT, product); 
-		}
+		fDataBlock.setDefaults(config);
+		fProgramBlock.setDefaults(config);
+		fJreBlock.setDefaults(config);
 	}
 	
-	private void updateStatus() {
-		updateStatus(getMoreSevere(fWorkspaceSelectionStatus, fJreSelectionStatus));
-	}
-
 	public void performApply(ILaunchConfigurationWorkingCopy config) {
-		try {
-			saveWorkspaceDataSection(config);
-			saveApplicationSection(config);
-			saveProductSection(config);
-			saveJRESection(config);
-			saveBootstrapEntriesSection(config);
-		} catch (CoreException e) {
-			PDEPlugin.logException(e);
-		}
+		fDataBlock.performApply(config);
+		fProgramBlock.performApply(config);
+		fJreBlock.performApply(config);
 	}
 	
-	protected void saveWorkspaceDataSection(ILaunchConfigurationWorkingCopy config)
-		throws CoreException {
-		config.setAttribute(LOCATION + String.valueOf(0), fWorkspaceCombo.getText());
-		String[] items = fWorkspaceCombo.getItems();
-		int nEntries = Math.min(items.length, 5);
-		for (int i = 0; i < nEntries; i++) {
-			config.setAttribute(LOCATION + String.valueOf(i+1), items[i]);
-		}
-	
-		config.setAttribute(DOCLEAR, fClearWorkspaceCheck.getSelection());
-		config.setAttribute(ASKCLEAR, fAskClearCheck.getSelection());
-	}
-	
-	protected void saveJRESection(ILaunchConfigurationWorkingCopy config)
-		throws CoreException {
-		
-		String javaCommand = fJavawButton.getSelection() ? null : "java"; //$NON-NLS-1$
-		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, javaCommand);
-		
-		if (fJreCombo.getSelectionIndex() == -1)
-			return;
-
-		String jre = fJreCombo.getText();
-		if (config.getAttribute(VMINSTALL, (String) null) != null) {
-			config.setAttribute(VMINSTALL, jre);
-		} else {
-			config.setAttribute(
-				VMINSTALL,
-				jre.equals(LauncherUtils.getDefaultVMInstallName()) ? null : jre);
-		}
-	}
-	
-	protected void saveBootstrapEntriesSection(ILaunchConfigurationWorkingCopy config) {
-		config.setAttribute(BOOTSTRAP_ENTRIES, fBootstrap.getText().trim());
-	}
-	
-	protected void saveProductSection(ILaunchConfigurationWorkingCopy config) {
-		config.setAttribute(USE_PRODUCT, fProductButton.getSelection());
-		config.setAttribute(PRODUCT, fProductCombo.getText());
-	}
-
-	protected void saveApplicationSection(ILaunchConfigurationWorkingCopy config) {
-		String text = fApplicationCombo.getText();
-		String attribute = getApplicationAttribute();
-		if (text.length() == 0 || text.equals(LauncherUtils.getDefaultApplicationName()))
-			config.setAttribute(attribute, (String) null);
-		else
-			config.setAttribute(attribute, text);
-	}
-
-	private IPath chooseWorkspaceLocation() {
-		DirectoryDialog dialog = new DirectoryDialog(getControl().getShell());
-		dialog.setFilterPath(fWorkspaceCombo.getText());
-		dialog.setText(PDEUIMessages.BasicLauncherTab_workspace_title); 
-		dialog.setMessage(PDEUIMessages.BasicLauncherTab_workspace_message); 
-		String res = dialog.open();
-		return res != null ? new Path(res) : null;
-	}
-
-	private IStatus validateJRESelection() {
-		if (fJreCombo.getSelectionIndex() == -1) {
-			return createStatus(
-				IStatus.ERROR,
-				PDEUIMessages.BasicLauncherTab_noJRE); 
-		}
-		return createStatus(IStatus.OK, ""); //$NON-NLS-1$
-	}
-
-	private IStatus validateWorkspaceSelection() {
-		String location = fWorkspaceCombo.getText().trim();
-		if (!Path.ROOT.isValidPath(location)) {
-			return createStatus(
-				IStatus.ERROR,
-				PDEUIMessages.BasicLauncherTab_invalidWorkspace); 
-		}
-		
-		IPath curr = new Path(location);
-		if (curr.segmentCount() == 0 && curr.getDevice() == null) {
-			return createStatus(
-				IStatus.ERROR,
-				PDEUIMessages.BasicLauncherTab_noWorkspace); 
-		}
-
-		return createStatus(IStatus.OK, ""); //$NON-NLS-1$
-	}
-
 	public String getName() {
 		return PDEUIMessages.BasicLauncherTab_name;
 	}