fix for 23186 - Applet viewer should be part of SDK
diff --git a/org.eclipse.jdt.debug.ui/icons/full/ctool16/java_applet.gif b/org.eclipse.jdt.debug.ui/icons/full/ctool16/java_applet.gif
new file mode 100644
index 0000000..9e784e4
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/icons/full/ctool16/java_applet.gif
Binary files differ
diff --git a/org.eclipse.jdt.debug.ui/icons/full/dtool16/java_applet.gif b/org.eclipse.jdt.debug.ui/icons/full/dtool16/java_applet.gif
new file mode 100644
index 0000000..9e784e4
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/icons/full/dtool16/java_applet.gif
Binary files differ
diff --git a/org.eclipse.jdt.debug.ui/icons/full/etool16/java_applet.gif b/org.eclipse.jdt.debug.ui/icons/full/etool16/java_applet.gif
new file mode 100644
index 0000000..9e784e4
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/icons/full/etool16/java_applet.gif
Binary files differ
diff --git a/org.eclipse.jdt.debug.ui/plugin.properties b/org.eclipse.jdt.debug.ui/plugin.properties
index a1eca16..46715ec 100644
--- a/org.eclipse.jdt.debug.ui/plugin.properties
+++ b/org.eclipse.jdt.debug.ui/plugin.properties
@@ -165,4 +165,6 @@
 MonitorView.label=Monitor View
 MonitorView.tooltip=Switch to Monitor View
 ThreadView.label=Thread View
-ThreadView.tooltip=Switch to Thread View
\ No newline at end of file
+ThreadView.tooltip=Switch to Thread View
+
+AppletShortcut.label=Applet Launcher
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.ui/plugin.xml b/org.eclipse.jdt.debug.ui/plugin.xml
index b036d34..54b92a6 100644
--- a/org.eclipse.jdt.debug.ui/plugin.xml
+++ b/org.eclipse.jdt.debug.ui/plugin.xml
@@ -1144,6 +1144,11 @@
 		configTypeID="org.eclipse.jdt.launching.remoteJavaApplication"
 		icon="icons/full/ctool16/java_attach.gif">
 	</launchConfigurationTypeImage>	
+    <launchConfigurationTypeImage
+        id="org.eclipse.jdt.debug.ui.launchConfigurationTypeImage.javaApplet"
+        configTypeID="org.eclipse.jdt.launching.javaApplet"
+        icon="icons/full/ctool16/java_applet.gif">
+    </launchConfigurationTypeImage>
 </extension>
 
 <extension point = "org.eclipse.debug.ui.launchConfigurationTabGroups">
@@ -1157,6 +1162,11 @@
 		type ="org.eclipse.jdt.launching.remoteJavaApplication"
 		class="org.eclipse.jdt.internal.debug.ui.launcher.RemoteJavaApplicationTabGroup">
 	</launchConfigurationTabGroup>
+    <launchConfigurationTabGroup
+        id="org.eclipse.jdt.debug.ui.launchConfigurationTabGroup.javaApplet"
+        type="org.eclipse.jdt.launching.javaApplet"
+        class="org.eclipse.jdt.internal.debug.ui.launcher.JavaAppletTabGroup">
+    </launchConfigurationTabGroup>
 </extension>
 
 <extension point = "org.eclipse.debug.core.statusHandlers">
@@ -1247,6 +1257,17 @@
 		<perspective id="org.eclipse.jdt.ui.JavaBrowsingPerspective"/>
 		<perspective id="org.eclipse.debug.ui.DebugPerspective"/>
 	</shortcut>
+    <shortcut
+        id="org.eclipse.jdt.debug.ui.javaAppletShortcut"
+        class="org.eclipse.jdt.internal.debug.ui.launcher.JavaAppletLaunchShortcut"
+        label="%AppletShortcut.label"
+        icon="icons/full/ctool16/java_applet.gif"
+        modes="run, debug">
+        <perspective id="org.eclipse.jdt.ui.JavaPerspective"/>
+        <perspective id="org.eclipse.jdt.ui.JavaHierarchyPerspective"/>
+        <perspective id="org.eclipse.jdt.ui.JavaBrowsingPerspective"/>
+        <perspective id="org.eclipse.debug.ui.DebugPerspective"/>
+    </shortcut>
 </extension>
 
 <extension point = "org.eclipse.jdt.ui.classpathContainerPage">
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/AppletArgumentsTab.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/AppletArgumentsTab.java
new file mode 100644
index 0000000..a0109a9
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/AppletArgumentsTab.java
@@ -0,0 +1,520 @@
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+package org.eclipse.jdt.debug.ui.launchConfigurations;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jdt.internal.debug.ui.JavaDebugImages;
+import org.eclipse.jdt.internal.debug.ui.launcher.JavaLaunchConfigurationTab;
+import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages;
+import org.eclipse.jdt.internal.debug.ui.launcher.NameValuePairDialog;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ControlEditor;
+import org.eclipse.swt.custom.TableCursor;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+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.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+ 
+/**
+ * This tab appears for local java launch configurations and allows the user to edit
+ * program arguments, VM arguments, and the working directory attributes.
+ */
+public class AppletArgumentsTab extends JavaLaunchConfigurationTab {
+	
+	private Label fWidthLabel;
+	private Text fWidthText;
+	private Label fHeightLabel;
+	private Text fHeightText;
+	private Label fNameLabel;
+	private Text fNameText;
+	private Table fParametersTable;
+	private Button fParametersAddButton;
+	private Button fParametersRemoveButton;
+	private Button fParametersEditButton;
+
+	private static final String EMPTY_STRING = "";	 //$NON-NLS-1$
+	
+	public static final int DEFAULT_APPLET_WIDTH = 200;
+	
+	public static final int DEFAULT_APPLET_HEIGHT = 200;
+
+	/**
+	 * @see ILaunchConfigurationTab#createControl(Composite)
+	 */
+	public void createControl(Composite parent) {
+		
+		Composite comp = new Composite(parent, SWT.NONE);
+		setControl(comp);
+		GridLayout topLayout = new GridLayout();
+		topLayout.numColumns = 3;
+		comp.setLayout(topLayout);		
+		GridData gd;
+		
+		createVerticalSpacer(comp);
+		
+		Composite projComp = new Composite(comp, SWT.NONE);
+		GridLayout projLayout = new GridLayout();
+		projLayout.numColumns = 3;
+		projLayout.marginHeight = 0;
+		projLayout.marginWidth = 0;
+		projComp.setLayout(projLayout);
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		projComp.setLayoutData(gd);
+		
+		this.fWidthLabel= new Label(projComp, SWT.NONE);
+		this.fWidthLabel.setText(LauncherMessages.getString("appletlauncher.argumenttab.widthlabel.text")); //$NON-NLS-1$
+		gd = new GridData();
+		this.fWidthLabel.setLayoutData(gd);
+		
+		this.fWidthText = new Text(projComp, SWT.SINGLE | SWT.BORDER);
+		gd = new GridData();
+		gd.horizontalSpan = 2;
+		this.fWidthText.setLayoutData(gd);
+		this.fWidthText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent evt) {
+				updateLaunchConfigurationDialog();
+			}
+		});
+		this.fHeightLabel= new Label(projComp, SWT.NONE);
+		this.fHeightLabel.setText(LauncherMessages.getString("appletlauncher.argumenttab.heightlabel.text")); //$NON-NLS-1$
+		gd = new GridData();
+		this.fHeightLabel.setLayoutData(gd);
+		
+		this.fHeightText = new Text(projComp, SWT.SINGLE | SWT.BORDER);
+		gd = new GridData();
+		gd.horizontalSpan = 2;
+		this.fHeightText.setLayoutData(gd);
+		this.fHeightText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent evt) {
+				updateLaunchConfigurationDialog();
+			}
+		});
+		this.fNameLabel = new Label(projComp, SWT.NONE);
+		this.fNameLabel.setText(LauncherMessages.getString("appletlauncher.argumenttab.namelabel.text")); //$NON-NLS-1$
+		gd = new GridData();
+		this.fNameLabel.setLayoutData(gd); 
+		
+		this.fNameText = new Text(projComp, SWT.SINGLE | SWT.BORDER);
+		gd = new GridData();
+		gd.horizontalSpan = 2;
+		this.fNameText.setLayoutData(gd);
+		this.fNameText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent evt) {
+				updateLaunchConfigurationDialog();
+			}
+		});	
+		
+		Label parameterLabel = new Label(comp, SWT.NONE);
+		parameterLabel.setText(LauncherMessages.getString("appletlauncher.argumenttab.parameterslabel.text")); //$NON-NLS-1$
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		parameterLabel.setLayoutData(gd);
+		
+		this.fParametersTable = new Table(comp, SWT.BORDER | SWT.MULTI);
+		this.fParametersTable.setData(IJavaLaunchConfigurationConstants.ATTR_APPLET_PARAMETERS);
+		TableLayout tableLayout = new TableLayout();
+		this.fParametersTable.setLayout(tableLayout);
+		gd = new GridData(GridData.FILL_BOTH);
+		this.fParametersTable.setLayoutData(gd);
+		TableColumn column1 = new TableColumn(this.fParametersTable, SWT.NONE);
+		column1.setText(LauncherMessages.getString("appletlauncher.argumenttab.parameterscolumn.name.text")); //$NON-NLS-1$
+		TableColumn column2 = new TableColumn(this.fParametersTable, SWT.NONE);
+		column2.setText(LauncherMessages.getString("appletlauncher.argumenttab.parameterscolumn.value.text"));		 //$NON-NLS-1$
+		tableLayout.addColumnData(new ColumnWeightData(100));
+		tableLayout.addColumnData(new ColumnWeightData(100));
+		this.fParametersTable.setHeaderVisible(true);
+		this.fParametersTable.setLinesVisible(true);
+		this.fParametersTable.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent evt) {
+				setParametersButtonsEnableState();
+			}
+		});
+		this.fParametersTable.addMouseListener(new MouseAdapter() {
+			public void mouseDoubleClick(MouseEvent e) {
+				setParametersButtonsEnableState();
+				if (fParametersEditButton.isEnabled()) {
+					handleParametersEditButtonSelected();
+				}
+			}
+		});
+	
+		Composite envButtonComp = new Composite(comp, SWT.NONE);
+		GridLayout envButtonLayout = new GridLayout();
+		envButtonLayout.marginHeight = 0;
+		envButtonLayout.marginWidth = 0;
+		envButtonComp.setLayout(envButtonLayout);
+		gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL);
+		envButtonComp.setLayoutData(gd);
+		
+		fParametersAddButton = createPushButton(envButtonComp ,LauncherMessages.getString("appletlauncher.argumenttab.parameters.button.add.text"), null); //$NON-NLS-1$
+		fParametersAddButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent evt) {
+				handleParametersAddButtonSelected();
+			}
+		});
+		
+		fParametersEditButton = createPushButton(envButtonComp, LauncherMessages.getString("appletlauncher.argumenttab.parameters.button.edit.text"), null); //$NON-NLS-1$
+		fParametersEditButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent evt) {
+				handleParametersEditButtonSelected();
+			}
+		});
+		
+		fParametersRemoveButton = createPushButton(envButtonComp, LauncherMessages.getString("appletlauncher.argumenttab.parameters.button.remove.text"), null); //$NON-NLS-1$
+		fParametersRemoveButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent evt) {
+				handleEnvRemoveButtonSelected();
+			}
+		});
+	}
+
+		
+	/**
+	 * @see ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public boolean isValid(ILaunchConfiguration launchConfig) {
+		setErrorMessage(null);
+		try {
+			Integer.parseInt(this.fWidthText.getText().trim());
+		} catch(NumberFormatException e) {
+			setErrorMessage(LauncherMessages.getString("appletlauncher.argumenttab.width.error.notaninteger")); //$NON-NLS-1$
+			return false;
+		}
+		try {
+			Integer.parseInt(this.fHeightText.getText().trim());
+		} catch(NumberFormatException e) {
+			setErrorMessage(LauncherMessages.getString("appletlauncher.argumenttab.height.error.notaninteger")); //$NON-NLS-1$
+			return false;
+		}
+		return true;
+	}
+
+	private void handleParametersAddButtonSelected() {
+		NameValuePairDialog dialog = 
+			new NameValuePairDialog(getShell(), 
+				LauncherMessages.getString("appletlauncher.argumenttab.parameters.dialog.add.title"),  //$NON-NLS-1$
+				new String[] {LauncherMessages.getString("appletlauncher.argumenttab.parameters.dialog.add.name.text"), LauncherMessages.getString("appletlauncher.argumenttab.parameters.dialog.add.value.text")},  //$NON-NLS-1$ //$NON-NLS-2$
+				new String[] {EMPTY_STRING, EMPTY_STRING}); 
+		openNewParameterDialog(dialog, null);
+		setParametersButtonsEnableState();
+	}
+
+	private void handleParametersEditButtonSelected() {
+		TableItem selectedItem = this.fParametersTable.getSelection()[0];
+		String name = selectedItem.getText(0);
+		String value = selectedItem.getText(1);
+		NameValuePairDialog dialog =
+			new NameValuePairDialog(getShell(), 
+				LauncherMessages.getString("appletlauncher.argumenttab.parameters.dialog.edit.title"),  //$NON-NLS-1$
+				new String[] {LauncherMessages.getString("appletlauncher.argumenttab.parameters.dialog.edit.name.text"), LauncherMessages.getString("appletlauncher.argumenttab.parameters.dialog.edit.value.text")},  //$NON-NLS-1$ //$NON-NLS-2$
+				new String[] {name, value});
+		openNewParameterDialog(dialog, selectedItem);		
+	}
+
+	private void handleEnvRemoveButtonSelected() {
+		int[] selectedIndices = this.fParametersTable.getSelectionIndices();
+		this.fParametersTable.remove(selectedIndices);
+		setParametersButtonsEnableState();
+	}
+
+	/**
+	 * Set the enabled state of the three environment variable-related buttons based on the
+	 * selection in the Table widget.
+	 */
+	private void setParametersButtonsEnableState() {
+		int selectCount = this.fParametersTable.getSelectionIndices().length;
+		if (selectCount < 1) {
+			fParametersEditButton.setEnabled(false);
+			fParametersRemoveButton.setEnabled(false);
+		} else {
+			fParametersRemoveButton.setEnabled(true);
+			if (selectCount == 1) {
+				fParametersEditButton.setEnabled(true);
+			} else {
+				fParametersEditButton.setEnabled(false);
+			}
+		}		
+		fParametersAddButton.setEnabled(true);
+	}
+
+	/**
+	 * Show the specified dialog and update the parameter table based on its results.
+	 * 
+	 * @param updateItem the item to update, or <code>null</code> if
+	 *  adding a new item
+	 */
+	private void openNewParameterDialog(NameValuePairDialog dialog, TableItem updateItem) {
+		if (dialog.open() != Window.OK) {
+			return;
+		}
+		String[] nameValuePair = dialog.getNameValuePair();
+		TableItem tableItem = updateItem;
+		if (tableItem == null) {
+			tableItem = getTableItemForName(nameValuePair[0]);
+			if (tableItem == null) {
+				tableItem = new TableItem(this.fParametersTable, SWT.NONE);
+			}
+		}
+		tableItem.setText(nameValuePair);
+		this.fParametersTable.setSelection(new TableItem[] {tableItem});
+		updateLaunchConfigurationDialog();	
+	}
+	
+	/**
+	 * Helper method that indicates whether the specified parameter name is already present 
+	 * in the parameters table.
+	 */
+	private TableItem getTableItemForName(String candidateName) {
+		TableItem[] items = this.fParametersTable.getItems();
+		for (int i = 0; i < items.length; i++) {
+			String name = items[i].getText(0);
+			if (name.equals(candidateName)) {
+				return items[i];
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * @see ILaunchConfigurationTab#performApply(ILaunchConfigurationWorkingCopy)
+	 */
+	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_WIDTH, Integer.parseInt(fWidthText.getText()));
+		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_HEIGHT, Integer.parseInt(fHeightText.getText()));
+		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_NAME, (String)fNameText.getText());
+		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_PARAMETERS, getMapFromParametersTable());
+	}
+	
+	private Map getMapFromParametersTable() {
+		TableItem[] items = fParametersTable.getItems();
+		if (items.length == 0) {
+			return null;
+		}
+		Map map = new HashMap(items.length);
+		for (int i = 0; i < items.length; i++) {
+			TableItem item = items[i];
+			String key = item.getText(0);
+			String value = item.getText(1);
+			map.put(key, value);
+		}		
+		return map;
+	}
+
+	/**
+	 * @see ILaunchConfigurationTab#setDefaults(ILaunchConfigurationWorkingCopy)
+	 */
+	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+	}
+	
+	private void updateParametersFromConfig(ILaunchConfiguration config) {
+		Map envVars = null;
+		try {
+			if (config != null) {
+				envVars = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_PARAMETERS, (Map)null);
+			}
+			updateTable(envVars, this.fParametersTable);
+			setParametersButtonsEnableState();
+		} catch (CoreException ce) {
+			JDIDebugUIPlugin.log(ce);
+		}
+	}
+
+	private void updateTable(Map map, Table tableWidget) {
+		tableWidget.removeAll();
+		if (map == null) {
+			return;
+		}
+		Iterator iterator = map.keySet().iterator();
+		while (iterator.hasNext()) {
+			String key = (String) iterator.next();
+			String value = (String) map.get(key);
+			TableItem tableItem = new TableItem(tableWidget, SWT.NONE);
+			tableItem.setText(new String[] {key, value});			
+		}
+	}
+		
+	/**
+	 * @see ILaunchConfigurationTab#initializeFrom(ILaunchConfiguration)
+	 */
+	public void initializeFrom(ILaunchConfiguration config) {
+		try {
+			fWidthText.setText(Integer.toString(config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_WIDTH, DEFAULT_APPLET_WIDTH))); //$NON-NLS-1$
+		} catch(CoreException ce) {
+			fWidthText.setText(Integer.toString(DEFAULT_APPLET_WIDTH)); //$NON-NLS-1$
+		}
+		try {
+			fHeightText.setText(Integer.toString(config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_HEIGHT, DEFAULT_APPLET_HEIGHT))); //$NON-NLS-1$
+		} catch(CoreException ce) {
+			fHeightText.setText(Integer.toString(DEFAULT_APPLET_HEIGHT)); //$NON-NLS-1$
+		}
+		try {
+			fNameText.setText(config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_NAME, LauncherMessages.getString("appletlauncher.argumenttab.name.defaultvalue"))); //$NON-NLS-1$
+		} catch(CoreException ce) {
+			fNameText.setText(LauncherMessages.getString("appletlauncher.argumenttab.name.defaultvalue")); //$NON-NLS-1$
+		}
+		updateParametersFromConfig(config);
+	}
+	
+	/**
+	 * Create some empty space 
+	 */
+	private void createVerticalSpacer(Composite comp) {
+		new Label(comp, SWT.NONE);
+	}	
+	
+	private Table createParameterTable(Composite comp) {
+		
+		String[][] data;
+		int count = 3;
+		data = new String[count][2];
+		for (int i = 0; i < count; i++) {
+			data[i] = new String[] { , };
+		};
+		
+		int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL;
+		final Table table = new Table(comp, style | SWT.FULL_SELECTION | SWT.HIDE_SELECTION);
+		table.setLinesVisible(true);
+		table.setHeaderVisible(true);
+		TableColumn column1 = new TableColumn(table, SWT.NONE);
+		column1.setText(LauncherMessages.getString("appletlauncher.argumenttab.parameterscolumn.name.text")); //$NON-NLS-1$
+		column1.setWidth(150);
+		TableColumn column2 = new TableColumn(table, SWT.NONE);
+		column2.setText(LauncherMessages.getString("appletlauncher.argumenttab.parameterscolumn.value.text")); //$NON-NLS-1$
+		column2.setWidth(150);
+		for (int i = 0; i < data.length; i++) {
+			TableItem item = new TableItem(table, 0);
+			item.setText(data[i]);
+		}
+		// create a TableCursor to navigate around the table
+		final TableCursor cursor = new TableCursor(table, SWT.SINGLE);
+		// create an editor to edit the cell when the user hits "ENTER" 
+		// while over a cell in the table
+		final ControlEditor editor = new ControlEditor(cursor);
+		editor.grabHorizontal = true;
+		editor.grabVertical = true;
+		cursor.addSelectionListener(new SelectionAdapter() {
+			// when the TableEditor is over a cell, select the corresponding row in 
+			// the table
+			public void widgetSelected(SelectionEvent e) {
+				table.setSelection(new TableItem[] { cursor.getRow()});
+			}
+			// when the user hits "ENTER" in the TableCursor, pop up a text editor so that 
+			// they can change the text of the cell
+			public void widgetDefaultSelected(SelectionEvent e) {
+				final Text text = new Text(cursor, SWT.NONE);
+				TableItem row = cursor.getRow();
+				int column = cursor.getColumn();
+				text.setText(row.getText(column));
+				text.addKeyListener(new KeyAdapter() {
+					public void keyPressed(KeyEvent e) {
+						// close the text editor and copy the data over 
+						// when the user hits "ENTER"
+						if (e.character == SWT.CR) {
+							TableItem row = cursor.getRow();
+							int column = cursor.getColumn();
+							row.setText(column, text.getText());
+							text.dispose();
+						}
+						// close the text editor when the user hits "ESC"
+						if (e.character == SWT.ESC) {
+							text.dispose();
+						}
+					}
+				});
+				editor.setEditor(text);
+				text.setFocus();
+			}
+		});
+		// Hide the TableCursor when the user hits the "CTRL" or "SHIFT" key.
+		// This alows the user to select multiple items in the table.
+		cursor.addKeyListener(new KeyAdapter() {
+			public void keyPressed(KeyEvent e) {
+				if (e.keyCode == SWT.CTRL
+					|| e.keyCode == SWT.SHIFT
+					|| (e.stateMask & SWT.CONTROL) != 0
+					|| (e.stateMask & SWT.SHIFT) != 0) {
+					cursor.setVisible(false);
+				}
+			}
+		});
+		// Show the TableCursor when the user releases the "SHIFT" or "CTRL" key.
+		// This signals the end of the multiple selection task.
+		table.addKeyListener(new KeyAdapter() {
+			public void keyReleased(KeyEvent e) {
+				if (e.keyCode == SWT.CONTROL && (e.stateMask & SWT.SHIFT) != 0)
+					return;
+				if (e.keyCode == SWT.SHIFT && (e.stateMask & SWT.CONTROL) != 0)
+					return;
+				if (e.keyCode != SWT.CONTROL && (e.stateMask & SWT.CONTROL) != 0)
+					return;
+				if (e.keyCode != SWT.SHIFT && (e.stateMask & SWT.SHIFT) != 0)
+					return;
+
+				TableItem[] selection = table.getSelection();
+				TableItem row =
+					(selection.length == 0) ? table.getItem(table.getTopIndex()) : selection[0];
+				table.showItem(row);
+				cursor.setSelection(row, 0);
+				cursor.setVisible(true);
+				cursor.setFocus();
+			}
+		});		
+		table.pack();
+		return table;
+	}
+
+	/**
+	 * @see ILaunchConfigurationTab#getName()
+	 */
+	public String getName() {
+		return LauncherMessages.getString("appletlauncher.argumenttab.name"); //$NON-NLS-1$
+	}	
+
+	/**
+	 * Convenience method to get the workspace root.
+	 */
+	private IWorkspaceRoot getWorkspaceRoot() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+
+	/**
+	 * @see ILaunchConfigurationTab#getImage()
+	 */
+	public Image getImage() {
+		return JavaDebugImages.get(JavaDebugImages.IMG_VIEW_ARGUMENTS_TAB);
+	}	
+
+}
+
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/AppletMainTab.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/AppletMainTab.java
new file mode 100644
index 0000000..b4d5de4
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/AppletMainTab.java
@@ -0,0 +1,465 @@
+package org.eclipse.jdt.debug.ui.launchConfigurations;
+
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+
+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.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org
+	.eclipse
+	.jdt
+	.internal
+	.debug
+	.ui
+	.launcher
+	.AppletLaunchConfigurationUtils;
+import org.eclipse.jdt.internal.debug.ui.launcher.AppletSelectionDialog;
+import org.eclipse.jdt.internal.debug.ui.launcher.JavaLaunchConfigurationTab;
+import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jdt.ui.ISharedImages;
+import org.eclipse.jdt.ui.JavaElementLabelProvider;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.viewers.ILabelProvider;
+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.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.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+/**
+ * This tab appears in the LaunchConfigurationDialog for launch configurations that
+ * require Java-specific launching information such as a main type and JRE.
+ */
+public class AppletMainTab extends JavaLaunchConfigurationTab {
+		
+	// Project UI widgets
+	private Label fProjLabel;
+	private Text fProjText;
+	private Button fProjButton;
+
+	// Main class UI widgets
+	private Label fMainLabel;
+	private Text fMainText;
+	private Button fSearchButton;
+	
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+	
+	/**
+	 * @see ILaunchConfigurationTab#createControl(Composite)
+	 */
+	public void createControl(Composite parent) {
+		
+		Composite comp = new Composite(parent, SWT.NONE);
+		setControl(comp);
+		GridLayout topLayout = new GridLayout();
+		comp.setLayout(topLayout);		
+		GridData gd;
+		
+		createVerticalSpacer(comp);
+		
+		Composite projComp = new Composite(comp, SWT.NONE);
+		GridLayout projLayout = new GridLayout();
+		projLayout.numColumns = 3;
+		projLayout.marginHeight = 0;
+		projLayout.marginWidth = 0;
+		projComp.setLayout(projLayout);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		projComp.setLayoutData(gd);
+		
+		fProjLabel = new Label(projComp, SWT.NONE);
+		fProjLabel.setText(LauncherMessages.getString("appletlauncher.maintab.projectlabel.name")); //$NON-NLS-1$
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		fProjLabel.setLayoutData(gd);
+		
+		fProjText = new Text(projComp, SWT.SINGLE | SWT.BORDER);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 2;
+		fProjText.setLayoutData(gd);
+		this.fProjText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent evt) {
+				updateLaunchConfigurationDialog();
+			}
+		});
+		
+		fProjButton = createPushButton(projComp, LauncherMessages.getString("appletlauncher.maintab.browselabel.name"), null); //$NON-NLS-1$
+		fProjButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent evt) {
+				handleProjectButtonSelected();
+			}
+		});
+		
+		Label spacer = createVerticalSpacer(projComp);
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		spacer.setLayoutData(gd);
+		
+		fMainLabel = new Label(projComp, SWT.NONE);
+		fMainLabel.setText(LauncherMessages.getString("appletlauncher.maintab.mainclasslabel.name")); //$NON-NLS-1$
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		fMainLabel.setLayoutData(gd);
+
+		fMainText = new Text(projComp, SWT.SINGLE | SWT.BORDER);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 2;
+		fMainText.setLayoutData(gd);
+		this.fMainText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent evt) {
+				updateLaunchConfigurationDialog();
+			}
+		});
+				
+		fSearchButton = createPushButton(projComp,LauncherMessages.getString("appletlauncher.maintab.searchlabel.name"), null); //$NON-NLS-1$
+		fSearchButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent evt) {
+				handleSearchButtonSelected();
+			}
+		});
+	}
+		
+	/**
+	 * @see ILaunchConfigurationTab#initializeFrom(ILaunchConfiguration)
+	 */
+	public void initializeFrom(ILaunchConfiguration config) {
+		updateProjectFromConfig(config);
+		updateMainTypeFromConfig(config);
+	}
+	
+	private void updateProjectFromConfig(ILaunchConfiguration config) {
+		String projectName = EMPTY_STRING;
+		try {
+			projectName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, EMPTY_STRING);	
+		} catch (CoreException ce) {
+			JDIDebugUIPlugin.log(ce);
+		}
+		fProjText.setText(projectName);
+	}
+	
+	private void updateMainTypeFromConfig(ILaunchConfiguration config) {
+		String mainTypeName = EMPTY_STRING;
+		try {
+			mainTypeName = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, EMPTY_STRING);
+		} catch (CoreException ce) {
+			JDIDebugUIPlugin.log(ce);	
+		}	
+		fMainText.setText(mainTypeName);
+	}
+		
+	/**
+	 * @see ILaunchConfigurationTab#performApply(ILaunchConfigurationWorkingCopy)
+	 */
+	public void performApply(ILaunchConfigurationWorkingCopy config) {
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)fProjText.getText());
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String)fMainText.getText());
+		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, getProjectOutputDirectory());		
+	}
+			
+	/**
+	 * @see ILaunchConfigurationTab#dispose()
+	 */
+	public void dispose() {
+	}
+	
+	/**
+	 * Create some empty space 
+	 */
+	private Label createVerticalSpacer(Composite comp) {
+		return new Label(comp, SWT.NONE);
+	}
+		
+	/**
+	 * Show a dialog that lists all main types
+	 */
+	private void handleSearchButtonSelected() {
+		
+		IJavaProject javaProject = getJavaProject();
+		IJavaSearchScope searchScope = null;
+		if ((javaProject == null) || !javaProject.exists()) {
+			searchScope = SearchEngine.createWorkspaceScope();
+		} else {
+			searchScope = SearchEngine.createJavaSearchScope(new IJavaElement[] {javaProject}, false);
+		}		
+		
+		Shell shell = getShell();
+		AppletSelectionDialog dialog =
+			new AppletSelectionDialog(
+				shell,
+				getLaunchConfigurationDialog(),
+				javaProject);
+		dialog.setTitle(LauncherMessages.getString("appletlauncher.maintab.selection.applet.dialog.title")); //$NON-NLS-1$
+		dialog.setMessage(LauncherMessages.getString("appletlauncher.maintab.selection.applet.dialog.message")); //$NON-NLS-1$
+		if (dialog.open() == dialog.CANCEL) {
+			return;
+		}
+		
+		Object[] results = dialog.getResult();
+		if ((results == null) || (results.length < 1)) {
+			return;
+		}		
+		IType type = (IType)results[0];
+		if (type != null) {
+			fMainText.setText(type.getFullyQualifiedName());
+			javaProject = type.getJavaProject();
+			fProjText.setText(javaProject.getElementName());
+		}
+	}
+		
+	/**
+	 * Show a dialog that lets the user select a project.  This in turn provides
+	 * context for the main type, allowing the user to key a main type name, or
+	 * constraining the search for main types to the specified project.
+	 */
+	private void handleProjectButtonSelected() {
+		IJavaProject project = chooseJavaProject();
+		if (project == null) {
+			return;
+		}
+		
+		String projectName = project.getElementName();
+		fProjText.setText(projectName);	
+	}
+	
+	/**
+	 * Realize a Java Project selection dialog and return the first selected project,
+	 * or null if there was none.
+	 */
+	private IJavaProject chooseJavaProject() {
+		IJavaProject[] projects;
+		try {
+			projects= JavaCore.create(getWorkspaceRoot()).getJavaProjects();
+		} catch (JavaModelException jme) {
+			JDIDebugUIPlugin.log(jme);
+			projects= new IJavaProject[0];
+		}
+		
+		ILabelProvider labelProvider= new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
+		ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), labelProvider);
+		dialog.setTitle(LauncherMessages.getString("appletlauncher.maintab.selection.project.dialog.title")); //$NON-NLS-1$
+		dialog.setMessage(LauncherMessages.getString("appletlauncher.maintab.selection.project.dialog.message")); //$NON-NLS-1$
+		dialog.setElements(projects);
+		
+		IJavaProject javaProject = getJavaProject();
+		if (javaProject != null) {
+			dialog.setInitialSelections(new Object[] { javaProject });
+		}
+		if (dialog.open() == dialog.OK) {			
+			return (IJavaProject) dialog.getFirstResult();
+		}			
+		return null;		
+	}
+	
+	/**
+	 * Return the IJavaProject corresponding to the project name in the project name
+	 * text field, or null if the text does not match a project name.
+	 */
+	private IJavaProject getJavaProject() {
+		String projectName = fProjText.getText().trim();
+		if (projectName.length() < 1) {
+			return null;
+		}
+		return getJavaModel().getJavaProject(projectName);		
+	}
+	
+	/**
+	 * Convenience method to get the workspace root.
+	 */
+	private IWorkspaceRoot getWorkspaceRoot() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+	
+	/**
+	 * Convenience method to get access to the java model.
+	 */
+	private IJavaModel getJavaModel() {
+		return JavaCore.create(getWorkspaceRoot());
+	}
+
+
+	/**
+	 * @see ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public boolean isValid(ILaunchConfiguration launchConfig) {
+		
+		setErrorMessage(null);
+		setMessage(null);
+		
+		String name = fProjText.getText().trim();
+		if (name.length() > 0) {
+			if (!ResourcesPlugin.getWorkspace().getRoot().getProject(name).exists()) {
+				setErrorMessage(LauncherMessages.getString("appletlauncher.maintab.project.error.doesnotexist")); //$NON-NLS-1$
+				return false;
+			}
+		}
+		name = fMainText.getText().trim();
+		if (name.length() == 0) {
+			setErrorMessage(LauncherMessages.getString("appletlauncher.maintab.type.error.doesnotexist")); //$NON-NLS-1$
+			return false;
+		}
+		IJavaProject jp = getJavaProject();
+		if (jp != null) {
+			// only verify type exists if Java project is specified
+			try {
+				IType type = AppletLaunchConfigurationUtils.getMainType(name, jp);
+			} catch (CoreException e) {
+				setErrorMessage(e.getMessage());
+				return false;
+			}
+		}	
+		
+		return true;
+	}
+	
+	/**
+	 * Initialize default attribute values based on the
+	 * given Java element.
+	 */
+	private void initializeDefaults(IJavaElement javaElement, ILaunchConfigurationWorkingCopy config) {
+		initializeJavaProject(javaElement, config);
+		initializeMainTypeAndName(javaElement, config);
+		initializeHardCodedDefaults(config);
+	}
+
+	/**
+	 * @see ILaunchConfigurationTab#setDefaults(ILaunchConfigurationWorkingCopy)
+	 */
+	public void setDefaults(ILaunchConfigurationWorkingCopy config) {
+		IJavaElement je = getContext();
+		if (je == null) {
+			initializeHardCodedDefaults(config);
+		} else {
+			initializeDefaults(je, config);
+		}
+	}
+
+	/**
+	 * Set the main type & name attributes on the working copy based on the IJavaElement
+	 */
+	private void initializeMainTypeAndName(IJavaElement javaElement, ILaunchConfigurationWorkingCopy config) {
+		String name = null;
+		if (javaElement instanceof IMember) {
+			IMember member = (IMember)javaElement;
+			if (member.isBinary()) {
+				javaElement = member.getClassFile();
+			} else {
+				javaElement = member.getCompilationUnit();
+			}
+		}
+		if (javaElement instanceof ICompilationUnit || javaElement instanceof IClassFile) {
+			if (javaElement.getElementType() == IJavaElement.COMPILATION_UNIT) {
+				ICompilationUnit cu= (ICompilationUnit) javaElement;
+				IType mainType= cu.getType(Signature.getQualifier(cu.getElementName()));
+				if (mainType.exists()) {
+					name = mainType.getFullyQualifiedName();
+				}
+			} else if (javaElement.getElementType() == IJavaElement.CLASS_FILE) {
+				try {
+					IType mainType= ((IClassFile)javaElement).getType();
+					name = mainType.getFullyQualifiedName();
+				} catch(JavaModelException e) {
+				}
+			}
+		}
+		if (name != null) {
+			config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, name);
+			if (name.length() > 0) {
+				int index = name.lastIndexOf('.');
+				if (index > 0) {
+					name = name.substring(index + 1);
+				}		
+				name = getLaunchConfigurationDialog().generateName(name);
+				config.rename(name);
+			}
+		}
+	}
+
+	/**
+	 * Set the VM attributes on the working copy based on the workbench default VM.
+	 */
+	private void initializeDefaultVM(ILaunchConfigurationWorkingCopy config) {
+		IVMInstall vmInstall = JavaRuntime.getDefaultVMInstall();
+		if (vmInstall == null) {
+			config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME, (String)null);
+			config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE, (String)null);
+		} else {
+			config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME, vmInstall.getName());
+			config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE, vmInstall.getVMInstallType().getId());
+		}
+	}
+	
+	/**
+	 * Initialize those attributes whose default values are independent of any context.
+	 */
+	private void initializeHardCodedDefaults(ILaunchConfigurationWorkingCopy config) {
+		initializeDefaultVM(config);
+	}
+
+	/**
+	 * @see ILaunchConfigurationTab#getName()
+	 */
+	public String getName() {
+		return LauncherMessages.getString("appletlauncher.maintab.name"); //$NON-NLS-1$
+	}
+			
+	/**
+	 * @see ILaunchConfigurationTab#getImage()
+	 */
+	public Image getImage() {
+		return JavaUI.getSharedImages().getImage(ISharedImages.IMG_OBJS_CLASS);
+	}
+
+	private String getProjectOutputDirectory() {
+		IJavaProject jproject = getJavaProject();
+		if (jproject == null) {
+			return EMPTY_STRING;
+		}
+		try {
+			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+			IPath outputLocation = jproject.getOutputLocation();
+			IResource resource = root.findMember(outputLocation);
+			IPath path = resource.getLocation();
+			if (path == null)  {
+				return EMPTY_STRING;
+			}
+			return path.toOSString();
+		} catch(JavaModelException e) {
+			return EMPTY_STRING;
+		}
+	}
+
+}
+
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/AppletLaunchConfigurationUtils.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/AppletLaunchConfigurationUtils.java
new file mode 100644
index 0000000..7026766
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/AppletLaunchConfigurationUtils.java
Binary files differ
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/AppletSelectionDialog.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/AppletSelectionDialog.java
new file mode 100644
index 0000000..0ff6cab
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/AppletSelectionDialog.java
@@ -0,0 +1,78 @@
+package org.eclipse.jdt.internal.debug.ui.launcher;
+
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+
+import java.util.Set;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.ui.JavaElementLabelProvider;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.TwoPaneElementSelector;
+
+/**
+ * A dialog to select a type that extends <code>java.applet.Applet</code>.
+ */
+public class AppletSelectionDialog extends TwoPaneElementSelector {
+
+	private IRunnableContext fRunnableContext;
+	private IJavaProject fProject;
+	
+	private static final String fgAppletClass = "java.applet.Applet";
+	
+	private static class PackageRenderer extends JavaElementLabelProvider {
+		public PackageRenderer() {
+			super(JavaElementLabelProvider.SHOW_PARAMETERS | JavaElementLabelProvider.SHOW_POST_QUALIFIED | JavaElementLabelProvider.SHOW_ROOT);	
+		}
+
+		public Image getImage(Object element) {
+			return super.getImage(((IType)element).getPackageFragment());
+		}
+		
+		public String getText(Object element) {
+			return super.getText(((IType)element).getPackageFragment());
+		}
+	}
+	
+	public AppletSelectionDialog(Shell shell, IRunnableContext context, IJavaProject project) {
+		super(shell, 
+				new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_BASICS | JavaElementLabelProvider.SHOW_OVERLAY_ICONS), 
+				new PackageRenderer());
+
+		Assert.isNotNull(context);
+		Assert.isNotNull(project);
+
+		fRunnableContext= context;
+		fProject= project;
+	}
+	
+	/**
+	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+	 */
+	protected void configureShell(Shell newShell) {
+		super.configureShell(newShell);
+	}
+
+	/**
+	 * @see org.eclipse.jface.window.Window#open()
+	 */
+	public int open() {
+		IType[] types = null;
+		Set result = AppletLaunchConfigurationUtils.collectAppletTypesInProject(new NullProgressMonitor(), fProject);
+		types = (IType[]) result.toArray(new IType[result.size()]);
+		if (types != null) {
+			setElements(types);
+		}
+		return super.open();
+	}
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/JavaAppletLaunchShortcut.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/JavaAppletLaunchShortcut.java
new file mode 100644
index 0000000..239e489
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/JavaAppletLaunchShortcut.java
@@ -0,0 +1,276 @@
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+package org.eclipse.jdt.internal.debug.ui.launcher;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.ILaunchShortcut;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ISourceReference;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.debug.ui.JavaUISourceLocator;
+import org.eclipse.jdt.debug.ui.launchConfigurations.AppletArgumentsTab;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.ui.JavaElementLabelProvider;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+public class JavaAppletLaunchShortcut implements ILaunchShortcut {
+
+	protected void searchAndLaunch(Object[] search, String mode) {
+		IType[] types= null;
+
+		if (search != null) {
+			try {
+				types = AppletLaunchConfigurationUtils.findApplets(new ProgressMonitorDialog(getShell()), search);
+			} catch (InterruptedException e) {
+				JDIDebugUIPlugin.log(e);
+				return;
+			} catch (InvocationTargetException e) {
+				JDIDebugUIPlugin.log(e);
+				return;
+			}
+			IType type = null;
+			if (types.length == 0) {
+				MessageDialog.openInformation(getShell(), LauncherMessages.getString("appletlauncher.search.dialog.title"), LauncherMessages.getString("appletlauncher.search.dialog.error.noapplets"));   //$NON-NLS-1$ //$NON-NLS-2$
+			} else if (types.length > 1) {
+				type = chooseType(types, mode);
+			} else {
+				type = types[0];
+			}
+			if (type != null) {
+				launch(type, mode);
+			}
+		}
+	}
+	
+	/**
+	 * @see ILaunchShortcut#launch(IEditorPart, String)
+	 */
+	public void launch(IEditorPart editor, String mode) {
+		IEditorInput input = editor.getEditorInput();
+		IJavaElement javaElement = (IJavaElement) input.getAdapter(IJavaElement.class);
+		if (javaElement != null) {
+			searchAndLaunch(new Object[] {javaElement}, mode);
+		} 
+	}
+
+	/**
+	 * @see ILaunchShortcut#launch(ISelection, String)
+	 */
+	public void launch(ISelection selection, String mode) {
+		if (selection instanceof IStructuredSelection) {
+			searchAndLaunch(((IStructuredSelection)selection).toArray(), mode);
+		} 
+	}
+	
+	/**
+	 * Prompts the user to select a type
+	 * 
+	 * @return the selected type or <code>null</code> if none.
+	 */
+	protected IType chooseType(IType[] types, String mode) {
+		ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), new JavaElementLabelProvider());
+		dialog.setElements(types);
+		dialog.setTitle(LauncherMessages.getString("appletlauncher.selection.type.dialog.title")); //$NON-NLS-1$
+		if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+			dialog.setMessage(LauncherMessages.getString("appletlauncher.selection.type.dialog.message.debug"));   //$NON-NLS-1$
+		} else {
+			dialog.setMessage(LauncherMessages.getString("appletlauncher.selection.type.dialog.message.run"));  //$NON-NLS-1$
+		}
+		dialog.setMultipleSelection(false);
+		if (dialog.open() == dialog.OK) {
+			return (IType)dialog.getFirstResult();
+		}
+		return null;
+	}
+	
+	/**
+	 * Launches a configuration for the given type
+	 */
+	protected void launch(IType type, String mode) {
+		try { 
+			ILaunchConfiguration config = findLaunchConfiguration(type, mode);
+			if (config != null) {
+				config.launch(mode, null);
+			}			
+		} catch (CoreException e) {
+			ErrorDialog.openError(getShell(), LauncherMessages.getString("appletlauncher.launching.error.failure"), e.getMessage(), e.getStatus());   //$NON-NLS-1$
+		}
+	}
+	
+	/**
+	 * Locate a configuration to relaunch for the given type.  If one cannot be found, create one.
+	 * 
+	 * @return a re-useable config or <code>null</code> if none
+	 */
+	protected ILaunchConfiguration findLaunchConfiguration(IType type, String mode) {
+		ILaunchConfigurationType configType= getAppletLaunchConfigType();
+		List candidateConfigs= Collections.EMPTY_LIST;
+		try {
+			ILaunchConfiguration[] configs= DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations(configType);
+			candidateConfigs= new ArrayList(configs.length);
+			for (int i= 0; i < configs.length; i++) {
+				ILaunchConfiguration config= configs[i];
+				if (config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, "").equals(type.getFullyQualifiedName())) {  //$NON-NLS-1$
+					if (config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, "").equals(type.getJavaProject().getElementName())) {  //$NON-NLS-1$
+						candidateConfigs.add(config);
+					}
+				}
+			}
+		} catch (CoreException e) {
+			JDIDebugUIPlugin.log(e);
+		}
+		
+		// If there are no existing configs associated with the IType, create one.
+		// If there is exactly one config associated with the IType, return it.
+		// Otherwise, if there is more than one config associated with the IType, prompt the
+		// user to choose one.
+		int candidateCount= candidateConfigs.size();
+		if (candidateCount < 1) {
+			return createConfiguration(type);
+		} else if (candidateCount == 1) {
+			return (ILaunchConfiguration) candidateConfigs.get(0);
+		} else {
+			// Prompt the user to choose a config.  A null result means the user
+			// cancelled the dialog, in which case this method returns null,
+			// since cancelling the dialog should also cancel launching anything.
+			ILaunchConfiguration config= chooseConfiguration(candidateConfigs, mode);
+			if (config != null) {
+				return config;
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * Create & return a new configuration based on the specified <code>IType</code>.
+	 */
+	protected ILaunchConfiguration createConfiguration(IType type) {
+		ILaunchConfiguration config = null;
+		try {
+			ILaunchConfigurationType configType = getAppletLaunchConfigType();
+			ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, DebugPlugin.getDefault().getLaunchManager().generateUniqueLaunchConfigurationNameFrom(type.getElementName())); 
+			wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, type.getFullyQualifiedName());
+			wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, type.getJavaProject().getElementName());
+			wc.setAttribute(IDebugUIConstants.ATTR_TARGET_DEBUG_PERSPECTIVE, IDebugUIConstants.PERSPECTIVE_DEFAULT);
+			wc.setAttribute(IDebugUIConstants.ATTR_TARGET_RUN_PERSPECTIVE, IDebugUIConstants.PERSPECTIVE_DEFAULT);
+			wc.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, JavaUISourceLocator.ID_PROMPTING_JAVA_SOURCE_LOCATOR);
+			wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_WIDTH, AppletArgumentsTab.DEFAULT_APPLET_WIDTH);
+			wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_HEIGHT, AppletArgumentsTab.DEFAULT_APPLET_HEIGHT);
+			config = wc.doSave();		
+		} catch (CoreException ce) {
+			JDIDebugUIPlugin.log(ce);			
+		}
+		return config;
+	}
+		
+	/**
+	 * Show a selection dialog that allows the user to choose one of the specified
+	 * launch configurations.  Return the chosen config, or <code>null</code> if the
+	 * user cancelled the dialog.
+	 */
+	protected ILaunchConfiguration chooseConfiguration(List configList, String mode) {
+		IDebugModelPresentation labelProvider = DebugUITools.newDebugModelPresentation();
+		ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), labelProvider);
+		dialog.setElements(configList.toArray());
+		dialog.setTitle(LauncherMessages.getString("appletlauncher.selection.configuration.dialog.title"));  //$NON-NLS-1$
+		if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+			dialog.setMessage(LauncherMessages.getString("appletlauncher.selection.configuration.dialog.message.debug"));  //$NON-NLS-1$
+		} else {
+			dialog.setMessage(LauncherMessages.getString("appletlauncher.selection.configuration.dialog.message.run"));  //$NON-NLS-1$
+		}
+		dialog.setMultipleSelection(false);
+		int result= dialog.open();
+		labelProvider.dispose();
+		if (result == dialog.OK) {
+			return (ILaunchConfiguration)dialog.getFirstResult();
+		}
+		return null;		
+	}
+	
+	/**
+	 * Returns the local java launch config type
+	 */
+	protected ILaunchConfigurationType getAppletLaunchConfigType() {
+		ILaunchManager lm= DebugPlugin.getDefault().getLaunchManager();
+		return lm.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLET);		
+	}	
+	
+	/**
+	 * Convenience method to get the window that owns this action's Shell.
+	 */
+	protected Shell getShell() {
+		return JDIDebugUIPlugin.getActiveWorkbenchShell();
+	}
+	
+	/**
+	 * Determines and returns the selection that provides context for the launch,
+	 * or <code>null</code> if there is no selection.
+	 */
+	protected IStructuredSelection resolveSelection(IWorkbenchWindow window) {
+		if (window == null) {
+			return null;
+		}
+		ISelection selection= window.getSelectionService().getSelection();
+		if (selection == null || selection.isEmpty() || !(selection instanceof IStructuredSelection)) {
+			// there is no obvious selection - go fishing
+			selection = null;
+			IWorkbenchPage page = window.getActivePage();
+			if (page == null) {
+				//workspace is closed
+				return null;
+			}
+
+			// first, see if there is an active editor, and try its input element
+			IEditorPart editor= page.getActiveEditor();
+			Object element = null;
+			if (editor != null) {
+				element = editor.getEditorInput();
+			}
+
+			if (selection == null && element != null) {
+				selection = new StructuredSelection(element);
+			}
+		}
+		return (IStructuredSelection)selection;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/JavaAppletTabGroup.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/JavaAppletTabGroup.java
new file mode 100644
index 0000000..2478fee
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/JavaAppletTabGroup.java
@@ -0,0 +1,42 @@
+package org.eclipse.jdt.internal.debug.ui.launcher;
+
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.AppletArgumentsTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.AppletMainTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaArgumentsTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab;
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaJRETab;
+
+public class JavaAppletTabGroup extends AbstractLaunchConfigurationTabGroup {
+	
+	/**
+	 * Constructs a new tab group for the given type.
+	 */
+	public JavaAppletTabGroup() {
+	}
+	
+	/**
+	 * @see ILaunchConfigurationTabGroup#createTabs(ILaunchConfigurationDialog, String)
+	 */
+	public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+		ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
+			new AppletMainTab(),
+			new AppletArgumentsTab(),
+			new JavaArgumentsTab(),
+			new JavaJRETab(),
+			new JavaClasspathTab(),			
+			new CommonTab()
+		};
+		setTabs(tabs);
+	}
+}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
index 61f858f..ca84f10 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
@@ -139,6 +139,8 @@
 MainTypeSelectionDialog.Qualifier=&Qualifier:
 
 VMLibraryBlock.Use_default_system_libraries_1=&Use default system libraries
+VMLibraryBlock.Libraries_cannot_be_empty._1=Libraries cannot be empty.
+VMLibraryBlock.Default_libraries_do_not_exist._1=Default libraries do not exist.
 
 WorkingDirectoryBlock.&Local_directory__1=&Local directory:
 WorkingDirectoryBlock.Works&pace__2=Works&pace:
@@ -171,6 +173,9 @@
 SourceAttachmentBlock.Package_Structure_Root_Selection_29=Package Structure Root Selection
 SourceAttachmentBlock.Problem_While_Opening_31=Problem While Opening
 
+SourceLookupBlock.Source_1=Source
+SourceLookupBlock.&Source_Lookup_Path__1=S&ource Lookup Path:
+
 JREContainerWizardPage.JRE_System_Library_1=JRE System Library
 JREContainerWizardPage.Unable_to_set_JRE_for_project._2=Unable to set JRE for project.
 JREContainerWizardPage.Select_the_JRE_used_to_build_this_project._4=Select a JRE to add to the classpath.
@@ -185,17 +190,62 @@
 RuntimeClasspathAdvancedDialog.Unable_to_create_new_entry._3=Unable to create new entry.
 RuntimeClasspathAdvancedDialog.Select_an_advanced_option__1=Select an advanced option:
 
-SourceLookupBlock.Source_1=Source
-SourceLookupBlock.&Source_Lookup_Path__1=S&ource Lookup Path:
-
 AbstractJavaCommandTab.Name_of_Java_e&xecutable__1=Name of Java e&xecutable:
 AbstractJavaCommandTab.Use_de&fault_Java_executable_2=U&se default Java executable
 AbstractJavaCommandTab.Standard_VM_Java_Command_3=Standard VM Java Command
 AbstractJavaCommandTab._4=
 AbstractJavaCommandTab.Java_executable_must_be_specified_5=Java executable must be specified
 
-VMLibraryBlock.Libraries_cannot_be_empty._1=Libraries cannot be empty.
-VMLibraryBlock.Default_libraries_do_not_exist._1=Default libraries do not exist.
-
 RuntimeClasspathEntryLabelProvider.JRE_System_Library_[{0}]_2=JRE System Library [{0}]
 
+appletlauncher.argumenttab.widthlabel.text=&Width:
+appletlauncher.argumenttab.widthlabel.text=&Width:
+appletlauncher.argumenttab.heightlabel.text=&Height:
+appletlauncher.argumenttab.namelabel.text=&Name: 
+appletlauncher.argumenttab.parameterslabel.text=Parameters:
+appletlauncher.argumenttab.parameters.button.add.text=A&dd...
+appletlauncher.argumenttab.parameters.button.edit.text=Ed&it...
+appletlauncher.argumenttab.parameters.button.remove.text=Rem&ove
+appletlauncher.argumenttab.width.error.notaninteger=Width is not an integer
+appletlauncher.argumenttab.height.error.notaninteger=Height is not an integer
+appletlauncher.argumenttab.parameters.dialog.add.title=Add Parameter Variable
+appletlauncher.argumenttab.parameters.dialog.add.name.text=&Name:
+appletlauncher.argumenttab.parameters.dialog.add.value.text=&Value:
+appletlauncher.argumenttab.parameters.dialog.edit.title=Edit Parameter Variable
+appletlauncher.argumenttab.parameters.dialog.edit.name.text=&Name
+appletlauncher.argumenttab.parameters.dialog.edit.value.text=&Value
+appletlauncher.argumenttab.name.defaultvalue=
+appletlauncher.argumenttab.parameterscolumn.name.text=Name
+appletlauncher.argumenttab.parameterscolumn.value.text=Value
+appletlauncher.argumenttab.name=&Parameters
+
+appletlauncher.maintab.projectlabel.name=P&roject:
+appletlauncher.maintab.browselabel.name=&Browse...
+appletlauncher.maintab.mainclasslabel.name=Applet cla&ss:
+appletlauncher.maintab.searchlabel.name=Searc&h...
+appletlauncher.maintab.selection.applet.dialog.title=Choose Applet
+appletlauncher.maintab.selection.applet.dialog.message=Choose an applet to launch:
+appletlauncher.maintab.selection.project.dialog.title=Project Selection
+appletlauncher.maintab.selection.project.dialog.message=Choose a &project to constrain the search for applet types:
+appletlauncher.maintab.project.error.doesnotexist=Project does not exist.
+appletlauncher.maintab.type.error.doesnotexist=Applet type not specified.
+appletlauncher.maintab.name=&Main
+
+appletlauncher.utils.error.main_type_not_specified=Applet type not specified
+appletlauncher.utils.error.main_type_does_not_exist=Applet type does not exist
+appletlauncher.appletconfiguration.error.not_an_applet=The applet type is not a subclass of java.applet.Applet.
+appletlauncher.appletconfiguration.error.no_vm_runner=Internal error: JRE {0} does not specify a VM Runner.
+
+appletlauncher.search.dialog.title=Applet Launch
+appletlauncher.search.dialog.error.noapplets=No applets found.
+appletlauncher.search.task.inprogress=Searching applets...
+
+appletlauncher.launching.error.failure=Java applet launch failed
+
+appletlauncher.selection.type.dialog.title=Applet selection
+appletlauncher.selection.type.dialog.message.debug=Select applet to debug
+appletlauncher.selection.type.dialog.message.run=Select applet to run
+appletlauncher.selection.configuration.dialog.title=Select an applet Configuration
+appletlauncher.selection.configuration.dialog.message.debug=Select an Applet configuration to debug
+appletlauncher.selection.configuration.dialog.message.run=Select an Applet configuration to run
+
diff --git a/org.eclipse.jdt.launching/java.policy.applet b/org.eclipse.jdt.launching/java.policy.applet
new file mode 100644
index 0000000..35527af
--- /dev/null
+++ b/org.eclipse.jdt.launching/java.policy.applet
@@ -0,0 +1,7 @@
+/* AUTOMATICALLY GENERATED ON Tue Apr 16 17:20:59 EDT 2002*/

+/* DO NOT EDIT */

+

+grant {

+  permission java.security.AllPermission;

+};

+

diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaAppletLaunchConfigurationDelegate.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaAppletLaunchConfigurationDelegate.java
new file mode 100644
index 0000000..2b6772c
--- /dev/null
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaAppletLaunchConfigurationDelegate.java
@@ -0,0 +1,342 @@
+package org.eclipse.jdt.internal.launching;
+
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IDebugEventSetListener;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.ISourceLocator;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate;
+import org.eclipse.jdt.launching.ExecutionArguments;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMRunner;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jdt.launching.VMRunnerConfiguration;
+import org.eclipse.jdt.launching.sourcelookup.JavaSourceLocator;
+
+public class JavaAppletLaunchConfigurationDelegate extends AbstractJavaLaunchConfigurationDelegate
+													implements IDebugEventSetListener {
+		
+	private static int fLaunchesCounter = 0;
+	private static HashMap fEventSources = new HashMap();
+
+	private File fTempFile;
+	private ILaunchConfiguration fCurrentLaunchConfiguration;
+	
+	/**
+	 * @see ILaunchConfigurationDelegate#launch(ILaunchConfiguration, String, ILaunch, IProgressMonitor)
+	 */
+	public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor)
+													throws CoreException {
+			
+		String mainTypeName = verifyMainTypeName(configuration);
+
+		IJavaProject javaProject = getJavaProject(configuration);
+		IType type = JavaLaunchConfigurationUtils.getMainType(mainTypeName, javaProject);
+		ITypeHierarchy hierarchy = type.newSupertypeHierarchy(new NullProgressMonitor());
+		IType javaLangApplet = JavaLaunchConfigurationUtils.getMainType("java.applet.Applet", javaProject); //$NON-NLS-1$
+		if (!hierarchy.contains(javaLangApplet)) {
+			abort(LaunchingMessages.getString("JavaAppletLaunchConfigurationDelegate.error.not_an_applet"), null, IJavaLaunchConfigurationConstants.ERR_NOT_AN_APPLET); //$NON-NLS-1$
+		}
+
+		IVMInstall vm = verifyVMInstall(configuration);
+
+		IVMRunner runner = vm.getVMRunner(mode);
+		if (runner == null) {
+			if (mode == ILaunchManager.DEBUG_MODE) {
+				abort(MessageFormat.format(LaunchingMessages.getString("JavaLocalApplicationLaunchConfigurationDelegate.JRE_{0}_does_not_support_debug_mode._1"), new String[]{vm.getName()}), null, IJavaLaunchConfigurationConstants.ERR_VM_RUNNER_DOES_NOT_EXIST);  //$NON-NLS-1$
+			} else {
+				abort(MessageFormat.format(LaunchingMessages.getString("JavaLocalApplicationLaunchConfigurationDelegate.JRE_{0}_does_not_support_run_mode._2"), new String[]{vm.getName()}), null, IJavaLaunchConfigurationConstants.ERR_VM_RUNNER_DOES_NOT_EXIST);  //$NON-NLS-1$
+			}
+		}
+
+		File workingDir = verifyWorkingDirectory(configuration);
+		String workingDirName = null;
+		if (workingDir != null) {
+			workingDirName = workingDir.getAbsolutePath();
+		}
+		
+		if (fLaunchesCounter == 0) {
+			DebugPlugin.getDefault().addDebugEventListener(this);
+		}
+	
+		// Program & VM args
+		String javaPolicy = getJavaPolicyFile(configuration);
+		ExecutionArguments execArgs = new ExecutionArguments(getVMArguments(configuration), ""); //$NON-NLS-1$
+		// Classpath
+		String[] classpath = getClasspath(configuration);
+		
+		// Create VM config
+		VMRunnerConfiguration runConfig = new VMRunnerConfiguration("sun.applet.AppletViewer", classpath); //$NON-NLS-1$
+		runConfig.setProgramArguments(new String[] {buildHTMLFile(configuration)});
+		String[] vmArgs = execArgs.getVMArgumentsArray();
+		String[] realArgs = new String[vmArgs.length+1];
+		System.arraycopy(vmArgs, 0, realArgs, 1, vmArgs.length);
+		realArgs[0] = javaPolicy;
+		runConfig.setVMArguments(realArgs);
+		
+		runConfig.setWorkingDirectory(workingDirName);
+
+		// Bootpath
+		String[] bootpath = getBootpath(configuration);
+		runConfig.setBootClassPath(bootpath);
+		
+		// Launch the configuration
+		this.fCurrentLaunchConfiguration = configuration;
+		runner.run(runConfig, launch, monitor);		
+		
+		// Set default source locator if none specified
+		if (launch.getSourceLocator() == null) {
+			String id = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null);
+			if (id == null) {
+				javaProject = JavaRuntime.getJavaProject(configuration);
+				ISourceLocator sourceLocator = new JavaSourceLocator(javaProject);
+				launch.setSourceLocator(sourceLocator);
+			}
+		}
+	}
+
+	/**
+	 * Returns the VM arguments specified by the given launch
+	 * configuration, as a string. The returned string is empty if
+	 * no VM arguments are specified.
+	 * 
+	 * @param configuration launch configuration
+	 * @return the VM arguments specified by the given 
+	 *  launch configuration, possibly an empty string
+	 * @exception CoreException if unable to retrieve the attribute
+	 */
+	public String getJavaPolicyFile(ILaunchConfiguration configuration)
+		throws CoreException {
+			String fileName = getWorkingDirectory(configuration).getAbsolutePath() + File.separator + "java.policy.applet";//$NON-NLS-1$
+			File file = new File(fileName);
+			if (!file.exists()) {
+				// copy it to the working directory
+				File test = LaunchingPlugin.getFileInPlugin(new Path("java.policy.applet")); //$NON-NLS-1$
+				try {
+					byte[] bytes = getFileByteContent(test);
+					BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file));
+					outputStream.write(bytes);
+					outputStream.close();
+				} catch (IOException e) {
+					return "";//$NON-NLS-1$
+				}
+			}
+		return "-Djava.security.policy=java.policy.applet";//$NON-NLS-1$
+	}
+
+	/**
+	 * Using the specified launch configuration, build an HTML file that specifies the
+	 * applet to launch.  Return the name of the HTML file.
+	 */
+	private String buildHTMLFile(ILaunchConfiguration configuration) {
+		FileWriter writer = null;
+		try {
+			String name = getMainTypeName(configuration);
+			fTempFile = new File(getWorkingDirectory(configuration).toString(), name + System.currentTimeMillis() + ".html"); //$NON-NLS-1$ //$NON-NLS-2$
+			writer = new FileWriter(fTempFile);
+			writer.write("<html>\n"); //$NON-NLS-1$
+			writer.write("<body>\n"); //$NON-NLS-1$
+			writer.write("<applet code="); //$NON-NLS-1$
+			writer.write(name);
+			writer.write(".class "); //$NON-NLS-1$
+			String appletName = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_NAME, ""); //$NON-NLS-1$
+			if (appletName.length() != 0) {
+				writer.write("NAME =\"" + appletName + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			writer.write("width=\""); //$NON-NLS-1$
+			writer.write(Integer.toString(configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_WIDTH, 200))); //$NON-NLS-1$
+			writer.write("\" height=\""); //$NON-NLS-1$
+			writer.write(Integer.toString(configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_HEIGHT, 200))); //$NON-NLS-1$
+			writer.write("\" >\n"); //$NON-NLS-1$
+			Map parameters = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_APPLET_PARAMETERS, new HashMap());
+			if (parameters.size() != 0) {
+				Iterator iterator = parameters.keySet().iterator();
+				while(iterator.hasNext()) {
+		 			String next = (String) iterator.next();
+					writer.write("<param name="); //$NON-NLS-1$
+					writer.write(next);
+					writer.write(" value="); //$NON-NLS-1$
+					writer.write((String) parameters.get(next));
+					writer.write(">\n"); //$NON-NLS-1$
+				}
+			}
+			writer.write("</applet>\n"); //$NON-NLS-1$
+			writer.write("</body>\n"); //$NON-NLS-1$
+			writer.write("</html>\n"); //$NON-NLS-1$
+		} catch(IOException e) {
+		} catch(CoreException e) {
+		} finally {
+			if (writer != null) {
+				try {
+					writer.close();
+				} catch(IOException e) {
+				}
+			}
+		}
+		if (fTempFile == null) {
+			return null;
+		}
+		return fTempFile.getName();
+	}
+	
+	/**
+	 * @see IDebugEventSetListener#handleDebugEvents(DebugEvent[])
+	 */
+	public void handleDebugEvents(DebugEvent[] events) {
+		for (int i = 0; i < events.length; i++) {
+			DebugEvent event = events[i];
+			Object eventSource = event.getSource();
+			switch(event.getKind()) {
+				
+				// Delete the HTML file used for the launch
+				case DebugEvent.TERMINATE :
+					if (eventSource != null) {
+						File temp = (File) fEventSources.get(eventSource);
+						if (temp != null) {
+							try {
+								fEventSources.remove(eventSource);
+								fLaunchesCounter--;
+								temp.delete();
+							} finally {
+								if (fLaunchesCounter == 0) {
+									DebugPlugin.getDefault().removeDebugEventListener(this);
+								}
+							}
+						}
+					}
+					break;
+					
+				// Track the HTML file used for the launch
+				case DebugEvent.CREATE :
+					if (eventSource != null) {
+						if (eventSource instanceof IProcess) {
+							IProcess runtimeProcess = (IProcess) eventSource;
+							if (runtimeProcess.getLaunch().getLaunchConfiguration().equals(fCurrentLaunchConfiguration)) {
+								fEventSources.put(eventSource, fTempFile);
+								fLaunchesCounter++;
+							}
+						} else if (eventSource instanceof IDebugTarget) {
+							IDebugTarget debugTarget = (IDebugTarget) eventSource;
+							if (debugTarget.getLaunch().getLaunchConfiguration().equals(fCurrentLaunchConfiguration)) {
+								fEventSources.put(eventSource, fTempFile);
+								fLaunchesCounter++;
+							}
+						}
+					}
+					break;
+			}
+		}
+	}
+
+	/**
+	 * Returns the contents of the given file as a byte array.
+	 * @throws IOException if a problem occured reading the file.
+	 */
+	protected static byte[] getFileByteContent(File file) throws IOException {
+		InputStream stream = null;
+		try {
+			stream = new BufferedInputStream(new FileInputStream(file));
+			return getInputStreamAsByteArray(stream, (int) file.length());
+		} finally {
+			if (stream != null) {
+				try {
+					stream.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Returns the given input stream's contents as a byte array.
+	 * If a length is specified (ie. if length != -1), only length bytes
+	 * are returned. Otherwise all bytes in the stream are returned.
+	 * Note this doesn't close the stream.
+	 * @throws IOException if a problem occured reading the stream.
+	 */
+	protected static byte[] getInputStreamAsByteArray(InputStream stream, int length)
+		throws IOException {
+		byte[] contents;
+		if (length == -1) {
+			contents = new byte[0];
+			int contentsLength = 0;
+			int bytesRead = -1;
+			do {
+				int available = stream.available();
+
+				// resize contents if needed
+				if (contentsLength + available > contents.length) {
+					System.arraycopy(
+						contents,
+						0,
+						contents = new byte[contentsLength + available],
+						0,
+						contentsLength);
+				}
+
+				// read as many bytes as possible
+				bytesRead = stream.read(contents, contentsLength, available);
+
+				if (bytesRead > 0) {
+					// remember length of contents
+					contentsLength += bytesRead;
+				}
+			} while (bytesRead > 0);
+
+			// resize contents if necessary
+			if (contentsLength < contents.length) {
+				System.arraycopy(
+					contents,
+					0,
+					contents = new byte[contentsLength],
+					0,
+					contentsLength);
+			}
+		} else {
+			contents = new byte[length];
+			int len = 0;
+			int readSize = 0;
+			while ((readSize != -1) && (len != length)) {
+				// See PR 1FMS89U
+				// We record first the read size. In this case len is the actual read size.
+				len += readSize;
+				readSize = stream.read(contents, len, length - len);
+			}
+		}
+
+		return contents;
+	}
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.properties b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.properties
index 51185bf..1347e78 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.properties
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.properties
@@ -30,6 +30,8 @@
 
 JavaRemoteApplicationLaunchConfigurationDelegate.Connector_not_specified_2=Connector not specified
 
+JavaAppletLaunchConfigurationDelegate.error.not_an_applet=The applet type is not a subclass of java.applet.Applet.
+
 JavaRuntime.badFormat=bad format
 JavaRuntime.exceptionOccurred=Exceptions occurred
 JavaRuntime.ioExceptionOccurred=An IOException occurred while saving vm's
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java
index 716061e..6040865 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java
Binary files differ
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
index 53bbd19..54155a2 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
Binary files differ
diff --git a/org.eclipse.jdt.launching/plugin.properties b/org.eclipse.jdt.launching/plugin.properties
index 03c5848..5d39480 100644
--- a/org.eclipse.jdt.launching/plugin.properties
+++ b/org.eclipse.jdt.launching/plugin.properties
@@ -19,3 +19,4 @@
 javaSourceLocatorName = Basic Java Source Locator
 
 providerName=Eclipse.org
+appletLabel= Java Applet
diff --git a/org.eclipse.jdt.launching/plugin.xml b/org.eclipse.jdt.launching/plugin.xml
index 852bed3..e8fc807 100644
--- a/org.eclipse.jdt.launching/plugin.xml
+++ b/org.eclipse.jdt.launching/plugin.xml
@@ -55,6 +55,12 @@
 	   delegate="org.eclipse.jdt.internal.launching.JavaRemoteApplicationLaunchConfigurationDelegate"
 	   modes= "debug">
    </launchConfigurationType>
+   <launchConfigurationType
+       id="org.eclipse.jdt.launching.javaApplet"
+       name="%appletLabel"
+       delegate="org.eclipse.jdt.internal.launching.JavaAppletLaunchConfigurationDelegate"
+       modes="run, debug">
+   </launchConfigurationType>
 </extension>
 
 <extension point = "org.eclipse.debug.core.sourceLocators">