applying #209495
diff --git a/core/plugins/org.eclipse.dltk.debug.ui/plugin.xml b/core/plugins/org.eclipse.dltk.debug.ui/plugin.xml
index db46021..d80156a 100644
--- a/core/plugins/org.eclipse.dltk.debug.ui/plugin.xml
+++ b/core/plugins/org.eclipse.dltk.debug.ui/plugin.xml
@@ -128,14 +128,6 @@
 				id="org.eclipse.ui.run">
 				<separator name="scriptGroup"></separator>
 			</menu>
-			<!--action
-				definitionId="org.eclipse.jdt.debug.ui.commands.AddExceptionBreakpoint"
-				label="%exceptionAction.accel.label"
-				icon="$nl$/icons/full/elcl16/exc_catch.gif"
-				class="org.eclipse.jdt.internal.debug.ui.breakpoints.AddExceptionAction"
-				menubarPath="org.eclipse.ui.run/breakpointGroup"
-				id="org.eclipse.jdt.debug.ui.actions.AddExceptionBreakpoint">
-				</action-->
 
 			<!--action
 				definitionId="org.eclipse.jdt.debug.ui.commands.StepIntoSelection"
@@ -348,6 +340,21 @@
 				</or>
 			</enabledWhen>
 		</page>
+		<page
+			class="org.eclipse.dltk.debug.ui.breakpoints.ScriptExceptionBreakpointPropertyPage"
+			id="org.eclipse.dltk.debug.ui.breakpoints.ScriptExceptionBreakpointPropertyPage"
+			name="Script Exception Breakpoint">
+			<enabledWhen>
+				<or>
+					<instanceof
+						value="org.eclipse.dltk.debug.core.model.IScriptExceptionBreakpoint">
+					</instanceof>
+					<adapt
+						type="org.eclipse.dltk.debug.core.model.IScriptExceptionBreakpoint">
+					</adapt>
+				</or>
+			</enabledWhen>
+		</page>
 	</extension>
 
 	<extension point="org.eclipse.ui.contexts">
@@ -388,12 +395,6 @@
 	</extension>
 	<extension point="org.eclipse.ui.commands">
 		<!--command
-			name="%ActionDefinition.addException.name"
-			description="%ActionDefinition.addException.description"
-			categoryId="org.eclipse.debug.ui.category.run"
-			id="org.eclipse.jdt.debug.ui.commands.AddExceptionBreakpoint">
-			</command-->
-		<!--command
 			name="%ActionDefinition.stepIntoSelection.name"
 			description="%ActionDefinition.stepIntoSelection.description"
 			categoryId="org.eclipse.debug.ui.category.run"
@@ -462,7 +463,6 @@
 	</extension>
 
 	<extension point="org.eclipse.ui.viewActions">
-
 		<viewContribution targetID="org.eclipse.debug.ui.VariableView"
 			id="org.eclipse.dltk.debug.ui.VariableViewActions">
 			<action
@@ -485,6 +485,6 @@
 				<groupMarker
 					name="org.eclipse.dltk.debug.ui.scriptPart" />
 			</menu>
-		</viewContribution>
+		</viewContribution>		
 	</extension>
 </plugin>
diff --git a/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/ScriptDebugModelPresentation.java b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/ScriptDebugModelPresentation.java
index dfe4bb3..5c750a5 100644
--- a/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/ScriptDebugModelPresentation.java
+++ b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/ScriptDebugModelPresentation.java
@@ -35,6 +35,7 @@
 import org.eclipse.debug.ui.IValueDetailListener;
 import org.eclipse.dltk.debug.core.model.IScriptBreakpoint;
 import org.eclipse.dltk.debug.core.model.IScriptDebugTarget;
+import org.eclipse.dltk.debug.core.model.IScriptExceptionBreakpoint;
 import org.eclipse.dltk.debug.core.model.IScriptLineBreakpoint;
 import org.eclipse.dltk.debug.core.model.IScriptStackFrame;
 import org.eclipse.dltk.debug.core.model.IScriptThread;
@@ -289,6 +290,37 @@
 				sb.append(MessageFormat
 						.format("{0}: {1}: [line: {2}]", new Object[] {
 								language, file, new Integer(lineNumber) }));
+			} else if (breakpoint instanceof IScriptExceptionBreakpoint) {
+				IScriptExceptionBreakpoint b = (IScriptExceptionBreakpoint) breakpoint;
+				String typeName = b.getTypeName();
+				if(b.isSuspendOnSubclasses()) {
+					typeName += " [Include Subclasses]";
+				}
+
+				sb.append(MessageFormat
+						.format("{0}: {1}", new Object[] {
+								language, typeName}));
+
+				
+				/* TODO: Uncomment this comment when add support for
+				 * caught and uncaught exceptions
+				   
+				String state;
+				boolean c= b.isCaught();
+				boolean u= b.isUncaught();
+				if (c && u) {
+					state= "caught and uncaught"; 
+				} else if (c) {
+					state= "caught"; 
+				} else if (u) {
+					state= "uncaught"; 
+				} else {
+					state= ": must specify caught or uncaught exception";
+				}
+				sb.append(MessageFormat
+						.format("{0}: {1}: {2}", new Object[] {
+								language, typeName, state}));
+				*/
 			}
 
 			if (hitCount != -1) {
diff --git a/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/actions/AddExceptionAction.java b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/actions/AddExceptionAction.java
new file mode 100644
index 0000000..d86a0b1
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/actions/AddExceptionAction.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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.dltk.debug.ui.actions;
+
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.dltk.core.IType;
+import org.eclipse.dltk.core.search.IDLTKSearchConstants;
+import org.eclipse.dltk.core.search.SearchEngine;
+import org.eclipse.dltk.debug.core.ScriptDebugManager;
+import org.eclipse.dltk.debug.core.model.IScriptBreakpoint;
+import org.eclipse.dltk.debug.core.model.IScriptExceptionBreakpoint;
+import org.eclipse.dltk.debug.ui.DLTKDebugUIPlugin;
+import org.eclipse.dltk.debug.ui.breakpoints.BreakpointUtils;
+import org.eclipse.dltk.internal.ui.dialogs.TypeSelectionDialog2;
+import org.eclipse.dltk.ui.DLTKUILanguageManager;
+import org.eclipse.dltk.ui.DLTKUIPlugin;
+import org.eclipse.dltk.ui.IDLTKUILanguageToolkit;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IViewActionDelegate;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * The workbench menu action for adding an exception breakpoint
+ */
+public abstract class AddExceptionAction implements IViewActionDelegate, IWorkbenchWindowActionDelegate {
+	
+	public static final String CAUGHT_CHECKED = "caughtChecked"; //$NON-NLS-1$
+	public static final String UNCAUGHT_CHECKED = "uncaughtChecked"; //$NON-NLS-1$
+	public static final String DIALOG_SETTINGS = "AddExceptionDialog"; //$NON-NLS-1$	
+	private IDLTKUILanguageToolkit fToolkit;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+	 */
+	public void run(IAction action) {
+		String natureId = ScriptDebugManager.getInstance().getNatureByDebugModel(getDebugModelId());
+		fToolkit = DLTKUILanguageManager.getLanguageToolkit(natureId);
+		IDialogSettings settings = getDialogSettings();
+		AddExceptionTypeDialogExtension ext = new AddExceptionTypeDialogExtension(null,
+				settings.getBoolean(CAUGHT_CHECKED), settings
+						.getBoolean(UNCAUGHT_CHECKED));
+		
+		TypeSelectionDialog2 dialog = new TypeSelectionDialog2(
+				DLTKUIPlugin.getActiveWorkbenchShell(), false, 
+				PlatformUI.getWorkbench().getProgressService(), 
+				SearchEngine.createWorkspaceScope(fToolkit.getCoreToolkit()),
+				IDLTKSearchConstants.TYPE, ext, fToolkit);
+		
+		dialog.setMessage("Search");
+		dialog.setTitle("Add exception breakpoint");
+		if (dialog.open() == IDialogConstants.OK_ID) {
+			Object[] types = dialog.getResult();
+			if (types != null && types.length > 0) {
+				boolean caught = ext.shouldHandleCaughtExceptions();
+				boolean uncaught = ext.shouldHandleUncaughtExceptions();
+				Object[] results = dialog.getResult(); 
+				if(results != null && results.length > 0) {
+					try {
+						createBreakpoint(caught, uncaught, (IType)results[0]);
+						settings.put(CAUGHT_CHECKED, caught);
+						settings.put(UNCAUGHT_CHECKED, uncaught);
+					}
+					catch (CoreException e) {
+						DLTKDebugUIPlugin.errorDialog("Unable to create breakpoint", e.getStatus());
+					}
+				}
+
+			}
+		}
+	}
+	
+	/**
+	 * Returns the existing dialog settings for the persisted state of the caught and uncaught check boxes.
+	 * If no section exists then a new one is created
+	 * 
+	 * @return the dialog settings section for the type dialog extension
+	 * 
+	 * @since 3.4
+	 */
+	private IDialogSettings getDialogSettings() {
+        IDialogSettings allSetttings = DLTKDebugUIPlugin.getDefault().getDialogSettings();
+        IDialogSettings section = allSetttings.getSection(DIALOG_SETTINGS);
+        if (section == null) {
+            section = allSetttings.addNewSection(DIALOG_SETTINGS);
+            section.put(CAUGHT_CHECKED, true);
+            section.put(UNCAUGHT_CHECKED, true);
+        }
+        return section;
+    }
+	
+	/**
+	 * creates a single breakpoint of the specified type
+	 * @param caught if the exception is caught
+	 * @param uncaught if the exception is uncaught
+	 * @param type the type of the exception
+	 * @since 3.2
+	 */
+	private void createBreakpoint(final boolean caught, final boolean uncaught, final IType type) throws CoreException {
+		IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(
+						getDebugModelId());
+		boolean exists = false;
+		for (int j = 0; j < breakpoints.length; j++) {
+			IScriptBreakpoint breakpoint = (IScriptBreakpoint) breakpoints[j];
+			if (breakpoint instanceof IScriptExceptionBreakpoint) {
+				IScriptExceptionBreakpoint exceptBreak = (IScriptExceptionBreakpoint) breakpoint;
+				if (exceptBreak.getTypeName().equals(type.getFullyQualifiedName())) {
+					exists = true;
+					break;
+				}
+			}
+		}
+		if (!exists) {
+			new Job("Script Toggle Exception Breakpoint") {
+				protected IStatus run(IProgressMonitor monitor) {
+					try {
+						BreakpointUtils.addExceptionBreakpoint(getDebugModelId(), caught, uncaught, type);
+						return Status.OK_STATUS;
+					} catch (CoreException e) {
+						return e.getStatus();
+					}
+				}
+
+			}.schedule();
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart)
+	 */
+	public void init(IViewPart view) {}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
+	 */
+	public void dispose() {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
+	 */
+	public void init(IWorkbenchWindow window) {
+	}
+	
+	protected abstract String getDebugModelId();
+}
diff --git a/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/actions/AddExceptionTypeDialogExtension.java b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/actions/AddExceptionTypeDialogExtension.java
new file mode 100644
index 0000000..f1c450d
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/actions/AddExceptionTypeDialogExtension.java
@@ -0,0 +1,128 @@
+package org.eclipse.dltk.debug.ui.actions;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dltk.core.IType;
+import org.eclipse.dltk.core.ITypeHierarchy;
+import org.eclipse.dltk.core.ModelException;
+import org.eclipse.dltk.debug.ui.DLTKDebugUIPlugin;
+import org.eclipse.dltk.ui.dialogs.TypeSelectionExtension;
+import org.eclipse.dltk.ui.util.SWTFactory;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+
+/**
+ * Provides a type dialog extension for the JDT type selection dialog
+ * 
+ * @since 3.4
+ */
+public class AddExceptionTypeDialogExtension extends TypeSelectionExtension {
+	
+	/**
+	  * widgets
+	  */
+	 private Button fCaughtButton;
+	 private Button fUncaughtButton;
+	 private boolean fCaught = false;
+	 private boolean fUncaught = false;
+	protected Object fExceptionBaseClassName;
+	
+	 /**
+	 * Constructor
+	 * @param caught
+	 * @param uncaught
+	 */
+	public AddExceptionTypeDialogExtension(String fExceptionBaseClassName, boolean caught, boolean uncaught) {
+		 fCaught = caught;
+		 fUncaught = uncaught;
+	 }
+	 
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.ui.dialogs.TypeSelectionExtension#createContentArea(org.eclipse.swt.widgets.Composite)
+	 */
+	public Control createContentArea(Composite parent) {
+		Composite comp = SWTFactory.createComposite(parent, parent.getFont(), 1, 1, GridData.FILL_HORIZONTAL);
+		fCaughtButton = SWTFactory.createCheckButton(comp, "Suspend on caught", null, fCaught, 1);
+		fCaughtButton.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				fCaught = fCaughtButton.getSelection();
+			}
+		});
+		fUncaughtButton = SWTFactory.createCheckButton(comp, "Suspend on uncaught", null, fUncaught, 1);
+		fUncaughtButton.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {}
+			public void widgetSelected(SelectionEvent e) {
+				fUncaught = fUncaughtButton.getSelection();
+			}
+		});
+		return comp;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.ui.dialogs.TypeSelectionExtension#getSelectionValidator()
+	 */
+	public ISelectionStatusValidator getSelectionValidator() {
+		return new ISelectionStatusValidator() {
+			public IStatus validate(Object[] selection) {
+				if(selection.length == 1) {
+					// if any class can be thrown return OK
+					if (fExceptionBaseClassName == null) {
+						return Status.OK_STATUS;
+					}
+
+					// else check that selected class was enherited from exception base class
+					try {
+		 	    		LinkedList queue = new LinkedList();
+						IType type = (IType) selection[0];
+			            ITypeHierarchy hierarchy = type.newSupertypeHierarchy(new NullProgressMonitor());
+			            IType curr = type;
+			            while (curr != null) {
+			                if (fExceptionBaseClassName.equals(curr.getFullyQualifiedName("."))) { //$NON-NLS-1$
+			                    return Status.OK_STATUS;
+			                }
+		 	                IType[] superclasses = hierarchy.getSuperclass(curr);
+		 	                if (superclasses != null) 	                	
+		 	                	queue.addAll(Arrays.asList(superclasses));
+		 	                
+		 	                if (queue.size() > 0)
+		 	                	curr = (IType) queue.removeFirst();
+		 	                else 
+		 	                	curr = null;
+			            }
+			        } 
+			        catch (ModelException e) {
+			        	DLTKDebugUIPlugin.log(e);
+			        	return Status.CANCEL_STATUS;
+			        }
+				}
+				return new Status(IStatus.ERROR, DLTKDebugUIPlugin.getUniqueIdentifier(), "Selected item is not an exception");
+			}
+			
+		};
+	}
+	
+	/**
+	 * Returns if the breakpoint should be set to suspend when the associated exception is thrown, but caught
+	 * @return if the breakpoint should be set to suspend when the associated exception is thrown, but caught
+	 */
+	public boolean shouldHandleCaughtExceptions() {
+		return fCaught;
+	}
+	
+	/**Returns if the breakpoint should be set to suspend when the associated exception is thrown, but not caught
+	 * @return if the breakpoint should be set to suspend when the associated exception is thrown, but not caught
+	 */
+	public boolean shouldHandleUncaughtExceptions() {
+		return fUncaught;
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/breakpoints/BreakpointUtils.java b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/breakpoints/BreakpointUtils.java
index 05cc951..a91e93c 100644
--- a/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/breakpoints/BreakpointUtils.java
+++ b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/breakpoints/BreakpointUtils.java
@@ -10,10 +10,12 @@
 package org.eclipse.dltk.debug.ui.breakpoints;
 
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.dltk.core.DLTKLanguageManager;
 import org.eclipse.dltk.core.IDLTKLanguageToolkit;
+import org.eclipse.dltk.core.IType;
 import org.eclipse.dltk.debug.core.DLTKDebugPlugin;
 import org.eclipse.dltk.debug.core.ScriptDebugManager;
 import org.eclipse.dltk.debug.core.model.IScriptBreakpoint;
@@ -109,4 +111,18 @@
 			}
 		}
 	}
+	
+	public static void addExceptionBreakpoint(String debugModelId, boolean caught,
+			final boolean uncaught, final IType type) throws CoreException {
+		// TODO: Resource should refer to valid script type, so debug model id 
+		// can be calculated from it
+		IResource resource = type.getResource();
+		if (resource == null || !resource.getProject().exists()) {
+			resource = ResourcesPlugin.getWorkspace().getRoot();
+		}
+		if (resource != null) {
+			ScriptDebugModel.createExceptionBreakpoint(debugModelId, resource, type
+					.getFullyQualifiedName(), caught, uncaught, true, null);
+		}
+	}
 }
diff --git a/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/breakpoints/ScriptExceptionBreakpointPropertyPage.java b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/breakpoints/ScriptExceptionBreakpointPropertyPage.java
new file mode 100644
index 0000000..0a61514
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.debug.ui/src/org/eclipse/dltk/debug/ui/breakpoints/ScriptExceptionBreakpointPropertyPage.java
@@ -0,0 +1,44 @@
+package org.eclipse.dltk.debug.ui.breakpoints;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.widgets.Composite;
+
+public class ScriptExceptionBreakpointPropertyPage extends
+		ScriptBreakpointPropertyPage {
+
+//	private Button fSuspendOnCaught;
+//	private Button fSuspendOnUncaught;
+//	private Button fSuspendOnSubclasses;
+
+	protected void createTypeSpecificButtons(Composite parent) {
+//		fSuspendOnCaught = SWTFactory.createCheckButton(parent,
+//				"Caught Exception", null, false, 1);
+//
+//		fSuspendOnUncaught = SWTFactory.createCheckButton(parent,
+//				"Uncaught Exception", null, false, 1);
+//
+//		fSuspendOnSubclasses = SWTFactory.createCheckButton(parent,
+//				"Suspend on Subclasses of this Exception", null, false, 1);
+	}
+
+	protected void loadValues() throws CoreException {
+		super.loadValues();
+//
+//		IScriptExceptionBreakpoint breakpoint = (IScriptExceptionBreakpoint) getBreakpoint();
+//
+//		fSuspendOnCaught.setSelection(breakpoint.isCaught());
+//		fSuspendOnUncaught.setSelection(breakpoint.isUncaught());
+//		fSuspendOnSubclasses.setSelection(breakpoint.isSuspendOnSubclasses());
+	}
+
+	protected void saveValues() throws CoreException {
+		super.saveValues();
+//
+//		IScriptExceptionBreakpoint breakpoint = (IScriptExceptionBreakpoint) getBreakpoint();
+//
+//		breakpoint.setCaught(fSuspendOnCaught.getSelection());
+//		breakpoint.setUncaught(fSuspendOnUncaught.getSelection());
+//		breakpoint.setSuspendOnSubclasses(fSuspendOnUncaught.getSelection());
+	}
+
+}