Added support for breakpoint in external source.
Improved the breakpoint location verifier process.
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
index 40a4a88..d46d046 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
@@ -143,3 +143,6 @@
 
 ObjectActionDelegate.Unable_to_display_type_hierarchy._The_selected_source_element_is_not_contained_in_the_workspace._1=Unable to display type hierarchy. The selected source element is not contained in the workspace.
 ManageBreakpointRulerAction.Breakpoints_can_only_be_created_within_the_type_associated_with_the_editor__{0}._1=Breakpoints can only be created within the type associated with the editor: {0}.
+ManageBreakpointActionDelegate.breakpoint_location=Breakpoint location validation
+ManageBreakpointActionDelegate.not_valid_location=Breakpoint cannot be set at the given position
+ManageBreakpointActionDelegate.breakpoint_set=Breakpoint set
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointLocationVerifierJob.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointLocationVerifierJob.java
new file mode 100644
index 0000000..b157eb4
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointLocationVerifierJob.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are 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
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.ui.actions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+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.jdt.core.IType;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
+import org.eclipse.jdt.debug.core.JDIDebugModel;
+import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Job used to verify the position of a breakpoint
+ */
+public class BreakpointLocationVerifierJob extends Job {
+
+	/**
+	 * The document which contains the code source.
+	 */
+	private IDocument fDocument;
+	
+	/**
+	 * The offset in the document where the breakpoint has been requested
+	 */
+	private int fOffset;
+
+	/**
+	 * The temporary breakpoint that has been set. Can be <code>null</code> if the callee was not able
+	 * to check if a breakpoint was already set at this position.
+	 */	
+	private IJavaLineBreakpoint fBreakpoint;
+	
+	/**
+	 * The number of the line where the breakpoint has been requested.
+	 */
+	private int fLineNumber;
+	
+	/**
+	 * The qualified type name of the class where the temporary breakpoint as been set.
+	 * Can be <code>null</code> if fBreakpoint is null.
+	 */	
+	private String fTypeName;
+	
+	/**
+	 * The type in which should be set the breakpoint.
+	 */
+	private IType fType;
+
+	/**
+	 * The resource in which should be set the breakpoint.
+	 */
+	private IResource fResource;
+	
+	public BreakpointLocationVerifierJob(IDocument document, int offset, IJavaLineBreakpoint breakpoint, int lineNumber, String typeName, IType type, IResource resource) {
+		super(ActionMessages.getString("ManageBreakpointActionDelegate.breakpoint_location")); //$NON-NLS-1$
+		fDocument= document;
+		fOffset= offset;
+		fBreakpoint= breakpoint;
+		fLineNumber= lineNumber;
+		fTypeName= typeName;
+		fType= type;
+		fResource= resource;
+	}
+	
+	public IStatus run(IProgressMonitor monitor) {
+		CompilationUnit compilationUnit= AST.parseCompilationUnit(fDocument.get().toCharArray());
+		ValidBreakpointLocationLocator locator= new ValidBreakpointLocationLocator(compilationUnit, fOffset);
+		compilationUnit.accept(locator);
+		int lineNumber= locator.getValidLocation();		
+		String typeName= locator.getFullyQualifiedTypeName();
+		
+		try {
+			if (lineNumber == -1) {
+				// cannot found a valid line
+				Display.getCurrent().beep();
+				if (fBreakpoint != null) {
+					DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
+				}
+				return new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ActionMessages.getString("ManageBreakpointActionDelegate.not_valid_location"), null); //$NON-NLS-1$
+			}
+			boolean differentLineNumber= lineNumber != fLineNumber;
+			IJavaLineBreakpoint breakpoint= JDIDebugModel.lineBreakpointExists(typeName, lineNumber);
+			boolean breakpointExist= breakpoint != null;
+			if (fBreakpoint == null) {
+				if (breakpointExist) {
+					if (differentLineNumber) {
+						// There is already a breakpoint on the valid line.
+						beep();
+						return new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ActionMessages.getString("ManageBreakpointActionDelegate.not_valid_location"), null); //$NON-NLS-1$
+					} else {
+						// There is already a breakpoint on the valid line, but it's also the requested line.
+						// Removing the existing breakpoint.
+						DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(breakpoint, true);
+						return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, "Breakpoint removed.", null); //$NON-NLS-1$
+					}
+				}
+				createNewBreakpoint(lineNumber, typeName);
+				return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.OK, ActionMessages.getString("ManageBreakpointActionDelegate.breakpoint_set"), null); //$NON-NLS-1$
+			} else {
+				if (differentLineNumber) {
+					if (breakpointExist) {
+						// there is already a breakpoint on the valid line.
+						beep();
+						DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
+						return new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ActionMessages.getString("ManageBreakpointActionDelegate.not_valid_location"), null); //$NON-NLS-1$
+					}
+					replaceBreakpoint(lineNumber, typeName);
+					return new Status(IStatus.WARNING, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.WARNING, "The breakpoint has been moved to a valid position.", null); //$NON-NLS-1$
+				}
+				if (!typeName.equals(fTypeName)) {
+					replaceBreakpoint(lineNumber, typeName);
+					return new Status(IStatus.WARNING, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.WARNING, "The breakpoint has been set to the right type.", null); //$NON-NLS-1$
+				}
+			}
+		} catch (CoreException e) {
+			JDIDebugUIPlugin.log(e);
+		}
+		return new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.OK, ActionMessages.getString("ManageBreakpointActionDelegate.breakpoint_set"), null); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Remove the temporary breakpoint and create a new breakpoint at the right position.
+	 */
+	private void replaceBreakpoint(int lineNumber, String typeName) throws CoreException {
+		createNewBreakpoint(lineNumber, typeName);
+		DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(fBreakpoint, true);
+	}
+
+	/**
+	 * Create a new breakpoint at the right position.
+	 */
+	private void createNewBreakpoint(int lineNumber, String typeName) throws CoreException {
+		Map newAttributes = new HashMap(10);
+		if (fType != null) {
+			try {
+				IRegion line= fDocument.getLineInformation(lineNumber - 1);
+				int start= line.getOffset();
+				int end= start + line.getLength() - 1;
+				BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(newAttributes, fType, start, end);
+			} catch (BadLocationException ble) {
+				JDIDebugUIPlugin.log(ble);
+			}
+		}
+		JDIDebugModel.createLineBreakpoint(fResource, typeName, lineNumber, -1, -1, 0, true, newAttributes);
+	}
+
+	private void beep() {
+		JDIDebugUIPlugin.getStandardDisplay().asyncExec(new Runnable() {
+			public void run() {
+				Display.getCurrent().beep();
+			}
+		});
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointActionDelegate.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointActionDelegate.java
index 4b28c1c..bd244b4 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointActionDelegate.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointActionDelegate.java
@@ -11,11 +11,15 @@
 package org.eclipse.jdt.internal.debug.ui.actions;
 
 
+import java.text.MessageFormat;
 import java.util.HashMap;
 import java.util.Map;
 
+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.jdt.core.IClassFile;
 import org.eclipse.jdt.core.IMember;
 import org.eclipse.jdt.core.ISourceRange;
 import org.eclipse.jdt.core.IType;
@@ -28,14 +32,17 @@
 import org.eclipse.jdt.internal.debug.ui.snippeteditor.JavaSnippetEditor;
 import org.eclipse.jdt.ui.JavaUI;
 import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IStatusLineManager;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextSelection;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.IPartListener;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
@@ -65,7 +72,8 @@
 	 */
 	protected void manageBreakpoint(IEditorInput editorInput) {
 		ISelectionProvider sp= getTextEditor().getSelectionProvider();
-		if (sp == null || getType() == null) {
+		IType type = getType();
+		if (sp == null) {
 			report(ActionMessages.getString("ManageBreakpointActionDelegate.No_Breakpoint")); //$NON-NLS-1$
 			return;
 		}
@@ -73,28 +81,65 @@
 		ISelection selection= sp.getSelection();
 		if (selection instanceof ITextSelection) {
 			IDocument document= getTextEditor().getDocumentProvider().getDocument(editorInput);
-			BreakpointLocationVerifier bv = new BreakpointLocationVerifier();
-			int lineNumber = bv.getValidBreakpointLocation(document, ((ITextSelection)selection).getStartLine());		
-			if (lineNumber > -1) {
-				try {
-					IJavaLineBreakpoint breakpoint= JDIDebugModel.lineBreakpointExists(getType().getFullyQualifiedName(), lineNumber);
-					if (breakpoint != null) {
-						DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(breakpoint, true);
-					} else {
-						try {
-							IRegion line= document.getLineInformation(lineNumber - 1);
-							Map attributes = new HashMap(10);
-							int start= line.getOffset();
-							int end= start + line.getLength() - 1;
-							BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, getType(), start, end);
-							JDIDebugModel.createLineBreakpoint(BreakpointUtils.getBreakpointResource(getType()), getType().getFullyQualifiedName(), lineNumber, -1, -1, 0, true, attributes);
-						} catch (BadLocationException ble) {
-							JDIDebugUIPlugin.log(ble);
+			
+			int lineNumber= ((ITextSelection)selection).getStartLine() + 1;
+
+			
+			int offset= ((ITextSelection)selection).getOffset();
+			try {
+				if (type == null) {
+					IClassFile classFile= (IClassFile)editorInput.getAdapter(IClassFile.class);
+					if (classFile != null) {
+						type= classFile.getType();
+						// bug 34856 - if this is an inner type, ensure the breakpoint is not
+						// being added to the outer type
+						if (type.getDeclaringType() != null) {
+							ISourceRange sourceRange= type.getSourceRange();
+							int start= sourceRange.getOffset();
+							int end= start + sourceRange.getLength();
+							if (offset < start || offset > end) {
+								// not in the inner type
+								IStatusLineManager manager= getTextEditor().getEditorSite().getActionBars().getStatusLineManager();
+								manager.setErrorMessage(MessageFormat.format(ActionMessages.getString("ManageBreakpointRulerAction.Breakpoints_can_only_be_created_within_the_type_associated_with_the_editor__{0}._1"), new String[] { type.getTypeQualifiedName()})); //$NON-NLS-1$
+								Display.getCurrent().beep();
+								return;
+							}
 						}
 					}
-				} catch (CoreException ce) {
-					ExceptionHandler.handle(ce, ActionMessages.getString("ManageBreakpointActionDelegate.error.title1"), ActionMessages.getString("ManageBreakpointActionDelegate.error.message1")); //$NON-NLS-1$ //$NON-NLS-2$
 				}
+			
+				String typeName= null;
+				IResource resource;
+				IJavaLineBreakpoint breakpoint= null;
+				if (type == null) {
+					if (editorInput instanceof IFileEditorInput) {
+						resource= ((IFileEditorInput)editorInput).getFile();
+					} else {
+						resource= ResourcesPlugin.getWorkspace().getRoot();
+					}
+				} else {
+					typeName= type.getFullyQualifiedName();
+					IJavaLineBreakpoint existingBreakpoint= JDIDebugModel.lineBreakpointExists(typeName, lineNumber);
+					if (existingBreakpoint != null) {
+						DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(existingBreakpoint, true);
+						return;
+					}
+					resource= BreakpointUtils.getBreakpointResource(type);
+					Map attributes = new HashMap(10);
+					try {
+						IRegion line= document.getLineInformation(lineNumber - 1);
+						int start= line.getOffset();
+						int end= start + line.getLength() - 1;
+						BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, type, start, end);
+					} catch (BadLocationException ble) {
+						JDIDebugUIPlugin.log(ble);
+					}
+					breakpoint= JDIDebugModel.createLineBreakpoint(resource, typeName, lineNumber, -1, -1, 0, true, attributes);
+				}
+				new BreakpointLocationVerifierJob(document, offset, breakpoint, lineNumber, typeName, type, resource).schedule();
+			} catch (CoreException ce) {
+				ExceptionHandler.handle(ce, ActionMessages.getString("ManageBreakpointActionDelegate.error.title1"), ActionMessages.getString("ManageBreakpointActionDelegate.error.message1")); //$NON-NLS-1$ //$NON-NLS-2$
+				return;
 			}
 		}
 	}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointRulerAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointRulerAction.java
index 274a4e2..921c44f 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointRulerAction.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ManageBreakpointRulerAction.java
@@ -35,6 +35,7 @@
 import org.eclipse.jdt.core.IMember;
 import org.eclipse.jdt.core.ISourceRange;
 import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
 import org.eclipse.jdt.debug.core.JDIDebugModel;
 import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
@@ -213,64 +214,70 @@
 		
 		IEditorInput editorInput= getTextEditor().getEditorInput();
 		
-		IDocument document= getDocument();
-		int rulerLine= getVerticalRulerInfo().getLineOfLastMouseButtonActivity();
-		
 		try {
-			BreakpointLocationVerifier bv = new BreakpointLocationVerifier();
-			int lineNumber = bv.getValidBreakpointLocation(document, rulerLine);
-			if (lineNumber > 0) {
-				
-				IRegion line= document.getLineInformation(lineNumber - 1);
-				
-				IType type = null;
-				IClassFile classFile= (IClassFile) editorInput.getAdapter(IClassFile.class);
-				if (classFile != null) {
-					type= classFile.getType();
-					// bug 34856 - if this is an inner type, ensure the breakpoint is not
-					// being added to the outer type
-					if (type.getDeclaringType() != null) {
-						ISourceRange sourceRange = type.getSourceRange();
-						int offset = line.getOffset();
-						int start = sourceRange.getOffset();
-						int end = start + sourceRange.getLength();
-						if (offset < start || offset > end) {
-							// not in the inner type
-							IStatusLineManager manager  = getTextEditor().getEditorSite().getActionBars().getStatusLineManager();
-							manager.setErrorMessage(MessageFormat.format(ActionMessages.getString("ManageBreakpointRulerAction.Breakpoints_can_only_be_created_within_the_type_associated_with_the_editor__{0}._1"), new String[]{type.getTypeQualifiedName()})); //$NON-NLS-1$
-							Display.getCurrent().beep();
-							return;
-						}
-					}
-				} else if (editorInput instanceof IFileEditorInput) {
-					IWorkingCopyManager manager= JavaUI.getWorkingCopyManager();
-					ICompilationUnit unit= manager.getWorkingCopy(editorInput);
-					if (unit != null) {
-						synchronized (unit) {
-							unit.reconcile();
-						}
-						IJavaElement e = unit.getElementAt(line.getOffset());
-						if (e instanceof IType) {
-							type= (IType)e;
-						} else if (e instanceof IMember) {
-							type= ((IMember)e).getDeclaringType();
-						}
+			IDocument document= getDocument();
+			IRegion line= document.getLineInformation(getVerticalRulerInfo().getLineOfLastMouseButtonActivity());
+
+			IType type= null;
+			IClassFile classFile= (IClassFile)editorInput.getAdapter(IClassFile.class);
+			if (classFile != null) {
+				type= classFile.getType();
+				// bug 34856 - if this is an inner type, ensure the breakpoint is not
+				// being added to the outer type
+				if (type.getDeclaringType() != null) {
+					ISourceRange sourceRange = type.getSourceRange();
+					int offset = line.getOffset();
+					int start = sourceRange.getOffset();
+					int end = start + sourceRange.getLength();
+					if (offset < start || offset > end) {
+						// not in the inner type
+						IStatusLineManager manager  = getTextEditor().getEditorSite().getActionBars().getStatusLineManager();
+						manager.setErrorMessage(MessageFormat.format(ActionMessages.getString("ManageBreakpointRulerAction.Breakpoints_can_only_be_created_within_the_type_associated_with_the_editor__{0}._1"), new String[]{type.getTypeQualifiedName()})); //$NON-NLS-1$
+						Display.getCurrent().beep();
+						return;
 					}
 				}
-				
-				if (type != null) {
-					IJavaProject project= type.getJavaProject();
-					if (type.exists() && project != null && project.isOnClasspath(type)) {
-						if (JDIDebugModel.lineBreakpointExists(type.getFullyQualifiedName(),lineNumber) == null) {
-							Map attributes = new HashMap(10);
-							int start= line.getOffset();
-							int end= start + line.getLength() - 1;
-							BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, type, start, end);
-							JDIDebugModel.createLineBreakpoint(getBreakpointResource(type), type.getFullyQualifiedName(), lineNumber, -1, -1, 0, true, attributes);
-						}
+			} else if (editorInput instanceof IFileEditorInput) {
+				IWorkingCopyManager manager= JavaUI.getWorkingCopyManager();
+				ICompilationUnit unit= manager.getWorkingCopy(editorInput);
+				if (unit != null) {
+					synchronized (unit) {
+						unit.reconcile();
+					}
+					IJavaElement e= unit.getElementAt(line.getOffset());
+					if (e instanceof IType) {
+						type= (IType)e;
+					} else if (e instanceof IMember) {
+						type= ((IMember)e).getDeclaringType();
 					}
 				}
 			}
+
+			Map attributes= new HashMap(10);
+			IResource resource;
+			String typeName= null;
+			int lineNumber= getVerticalRulerInfo().getLineOfLastMouseButtonActivity();
+			IJavaLineBreakpoint breakpoint= null;
+			if (type == null) {
+				if (editorInput instanceof IFileEditorInput) {
+					resource= ((IFileEditorInput)editorInput).getFile();
+				} else {
+					resource= ResourcesPlugin.getWorkspace().getRoot();
+				}
+			} else {
+				IJavaProject project= type.getJavaProject();
+				typeName= type.getFullyQualifiedName();
+				if (type.exists() && project != null && project.isOnClasspath(type)) {
+					if (JDIDebugModel.lineBreakpointExists(typeName, lineNumber) == null) {
+						int start= line.getOffset();
+						int end= start + line.getLength() - 1;
+						BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, type, start, end);
+					}
+				}
+				resource= BreakpointUtils.getBreakpointResource(type);
+				breakpoint= JDIDebugModel.createLineBreakpoint(resource, typeName, lineNumber, -1, -1, 0, true, attributes);
+			}
+			new BreakpointLocationVerifierJob(document, line.getOffset(), breakpoint, lineNumber, typeName, type, resource).schedule();
 		} catch (DebugException e) {
 			JDIDebugUIPlugin.errorDialog(ActionMessages.getString("ManageBreakpointRulerAction.error.adding.message1"), e); //$NON-NLS-1$
 		} catch (CoreException e) {
@@ -293,27 +300,4 @@
 		}
 	}
 	
-	/**
-	 * Returns the resource on which a breakpoint marker should
-	 * be created for the given member. The resource returned is the 
-	 * associated file, or project in the case of a class file in 
-	 * a jar.
-	 * 
-	 * @param member member in which a breakpoint is being created
-	 * @return resource the resource on which a breakpoint marker
-	 *  should be created
-	 * @exception CoreException if an exception occurs accessing the
-	 *  underlying resource or Java model elements
-	 */
-	public IResource getBreakpointResource(IMember member) throws CoreException {
-		ICompilationUnit cu = member.getCompilationUnit();
-		if (cu != null && cu.isWorkingCopy()) {
-			member = (IMember)cu.getOriginal(member);
-		}
-		IResource res = member.getUnderlyingResource();
-		if (res == null) {
-			res = member.getJavaProject().getProject();
-		}
-		return res;
-	}
 }
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ValidBreakpointLocationLocator.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ValidBreakpointLocationLocator.java
new file mode 100644
index 0000000..7dd150a
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ValidBreakpointLocationLocator.java
@@ -0,0 +1,637 @@
+/*******************************************************************************
+ * Copyright (c) 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are 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
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.ui.actions;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.ArrayAccess;
+import org.eclipse.jdt.core.dom.ArrayCreation;
+import org.eclipse.jdt.core.dom.ArrayInitializer;
+import org.eclipse.jdt.core.dom.ArrayType;
+import org.eclipse.jdt.core.dom.AssertStatement;
+import org.eclipse.jdt.core.dom.Assignment;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.BooleanLiteral;
+import org.eclipse.jdt.core.dom.BreakStatement;
+import org.eclipse.jdt.core.dom.CastExpression;
+import org.eclipse.jdt.core.dom.CatchClause;
+import org.eclipse.jdt.core.dom.CharacterLiteral;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ConditionalExpression;
+import org.eclipse.jdt.core.dom.ConstructorInvocation;
+import org.eclipse.jdt.core.dom.ContinueStatement;
+import org.eclipse.jdt.core.dom.DoStatement;
+import org.eclipse.jdt.core.dom.EmptyStatement;
+import org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.eclipse.jdt.core.dom.FieldAccess;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.ForStatement;
+import org.eclipse.jdt.core.dom.IfStatement;
+import org.eclipse.jdt.core.dom.ImportDeclaration;
+import org.eclipse.jdt.core.dom.InfixExpression;
+import org.eclipse.jdt.core.dom.Initializer;
+import org.eclipse.jdt.core.dom.InstanceofExpression;
+import org.eclipse.jdt.core.dom.Javadoc;
+import org.eclipse.jdt.core.dom.LabeledStatement;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.NullLiteral;
+import org.eclipse.jdt.core.dom.NumberLiteral;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.ParenthesizedExpression;
+import org.eclipse.jdt.core.dom.PostfixExpression;
+import org.eclipse.jdt.core.dom.PrefixExpression;
+import org.eclipse.jdt.core.dom.PrimitiveType;
+import org.eclipse.jdt.core.dom.QualifiedName;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.SimpleType;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.StringLiteral;
+import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
+import org.eclipse.jdt.core.dom.SuperFieldAccess;
+import org.eclipse.jdt.core.dom.SuperMethodInvocation;
+import org.eclipse.jdt.core.dom.SwitchCase;
+import org.eclipse.jdt.core.dom.SwitchStatement;
+import org.eclipse.jdt.core.dom.SynchronizedStatement;
+import org.eclipse.jdt.core.dom.ThisExpression;
+import org.eclipse.jdt.core.dom.ThrowStatement;
+import org.eclipse.jdt.core.dom.TryStatement;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
+import org.eclipse.jdt.core.dom.TypeLiteral;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
+import org.eclipse.jdt.core.dom.WhileStatement;
+
+/**
+ * Compute a valid location where to put a breakpoint from an JDOM CompilationUnit.
+ * The result is the first valid location with a line number greater or equals than the given position.
+ */
+public class ValidBreakpointLocationLocator extends ASTVisitor {
+	
+	private CompilationUnit fCompilationUnit;
+	private int fPosition;
+	private int fPositionLine;
+
+	private int fLocation;
+	private boolean fLocationFound;
+	private String fTypeName;
+
+	/**
+	 * @param compilationUnit the JDOM CompilationUnit of the source code.
+	 * @param position the offset in the source code where to put the breakpoint.
+	 */
+	public ValidBreakpointLocationLocator(CompilationUnit compilationUnit, int position) {
+		fCompilationUnit= compilationUnit;
+		fPosition= position;
+		fPositionLine= fCompilationUnit.lineNumber(fPosition);
+		fLocationFound= false;
+	}
+	
+	/**
+	 * Return the line number of the computed valid location, or -1 if no valid location has been found.
+	 */
+	public int getValidLocation() {
+		if (fLocationFound) {
+			return fLocation;
+		} else {
+			return -1;
+		}
+	}
+	
+	/**
+	 * Return of the type where the valid location is, or null if no valid location has been found.
+	 */
+	public String getFullyQualifiedTypeName() {
+		return fTypeName;
+	}
+	
+	/**
+	 * Compute the name of the type which contains this node.
+	 * Result will be the name of the type or the inner type which contains this node, but not of the local or anonymous type.
+	 */
+	private void computeTypeName(ASTNode node) {
+		while (!(node instanceof CompilationUnit)) {
+			if (node instanceof TypeDeclaration) {
+				String identifier= ((TypeDeclaration)node).getName().getIdentifier();
+				if (fTypeName == null) {
+					fTypeName= identifier;
+				} else {
+					fTypeName= identifier + "$" + fTypeName; //$NON-NLS-1$
+				}
+			} else {
+				fTypeName= null;
+			}
+			node= node.getParent();
+		}
+		PackageDeclaration packageDecl= ((CompilationUnit)node).getPackage();
+		String packageIdentifier= ""; //$NON-NLS-1$
+		if (packageDecl != null) {
+			Name packageName= packageDecl.getName();
+			while (packageName.isQualifiedName()) {
+				QualifiedName qualifiedName= (QualifiedName) packageName;
+				packageIdentifier= qualifiedName.getName().getIdentifier() + "." + packageIdentifier; //$NON-NLS-1$
+				packageName= qualifiedName.getQualifier();
+			}
+			packageIdentifier= ((SimpleName)packageName).getIdentifier() + "." + packageIdentifier; //$NON-NLS-1$
+		}
+		fTypeName= packageIdentifier + fTypeName;
+	}
+
+	/**
+	 * @param node the node.
+	 * @param isCode true indicated that the first line of the given node always contains some executable code, even if split in multiple lines.
+	 * @return
+	 */
+	private boolean visit(ASTNode node, boolean isCode) {
+		int startPosition= node.getStartPosition();
+		int endPosition = startPosition + node.getLength();
+		// if we already found a correct location, or if the position is not in this part of the code,
+		// no need to check the element inside.
+		if (fLocationFound || endPosition < fPosition) {
+			return false;
+		}
+		int startLine = fCompilationUnit.lineNumber(startPosition);
+		// if it is a structure, or there is more than one line of code, go in
+		if (isCode && (fPositionLine == startLine || startLine == fCompilationUnit.lineNumber(endPosition))) {
+			fLocation= startLine;
+			fLocationFound= true;
+			computeTypeName(node);
+			return false;
+		}
+		return true;
+	}
+	
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnonymousClassDeclaration)
+	 */
+	public boolean visit(AnonymousClassDeclaration node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayAccess)
+	 */
+	public boolean visit(ArrayAccess node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayCreation)
+	 */
+	public boolean visit(ArrayCreation node) {
+		return visit(node, node.getInitializer() == null);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayInitializer)
+	 */
+	public boolean visit(ArrayInitializer node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayType)
+	 */
+	public boolean visit(ArrayType node) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AssertStatement)
+	 */
+	public boolean visit(AssertStatement node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Assignment)
+	 */
+	public boolean visit(Assignment node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Block)
+	 */
+	public boolean visit(Block node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BooleanLiteral)
+	 */
+	public boolean visit(BooleanLiteral node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BreakStatement)
+	 */
+	public boolean visit(BreakStatement node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CastExpression)
+	 */
+	public boolean visit(CastExpression node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CatchClause)
+	 */
+	public boolean visit(CatchClause node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CharacterLiteral)
+	 */
+	public boolean visit(CharacterLiteral node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ClassInstanceCreation)
+	 */
+	public boolean visit(ClassInstanceCreation node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CompilationUnit)
+	 */
+	public boolean visit(CompilationUnit node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConditionalExpression)
+	 */
+	public boolean visit(ConditionalExpression node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConstructorInvocation)
+	 */
+	public boolean visit(ConstructorInvocation node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ContinueStatement)
+	 */
+	public boolean visit(ContinueStatement node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.DoStatement)
+	 */
+	public boolean visit(DoStatement node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EmptyStatement)
+	 */
+	public boolean visit(EmptyStatement node) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ExpressionStatement)
+	 */
+	public boolean visit(ExpressionStatement node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldAccess)
+	 */
+	public boolean visit(FieldAccess node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldDeclaration)
+	 */
+	public boolean visit(FieldDeclaration node) {
+		if (visit(node, false)) {
+			// visit only the variable declaration fragments, no the variable names.
+			List fragments= node.fragments();
+			for (Iterator iter= fragments.iterator(); iter.hasNext();) {
+				((VariableDeclarationFragment)iter.next()).accept(this);
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ForStatement)
+	 */
+	public boolean visit(ForStatement node) {
+		// in case on a "for(;;)", the breakpoint can be set on the first token of the node.
+		return visit(node, node.initializers().isEmpty() && node.getExpression() == null && node.updaters().isEmpty());
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.IfStatement)
+	 */
+	public boolean visit(IfStatement node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ImportDeclaration)
+	 */
+	public boolean visit(ImportDeclaration node) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InfixExpression)
+	 */
+	public boolean visit(InfixExpression node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Initializer)
+	 */
+	public boolean visit(Initializer node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InstanceofExpression)
+	 */
+	public boolean visit(InstanceofExpression node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Javadoc)
+	 */
+	public boolean visit(Javadoc node) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.LabeledStatement)
+	 */
+	public boolean visit(LabeledStatement node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
+	 */
+	public boolean visit(MethodDeclaration node) {
+		if (visit(node, false)) {
+			// visit only the body
+			node.getBody().accept(this);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation)
+	 */
+	public boolean visit(MethodInvocation node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NullLiteral)
+	 */
+	public boolean visit(NullLiteral node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NumberLiteral)
+	 */
+	public boolean visit(NumberLiteral node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PackageDeclaration)
+	 */
+	public boolean visit(PackageDeclaration node) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ParenthesizedExpression)
+	 */
+	public boolean visit(ParenthesizedExpression node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PostfixExpression)
+	 */
+	public boolean visit(PostfixExpression node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PrefixExpression)
+	 */
+	public boolean visit(PrefixExpression node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PrimitiveType)
+	 */
+	public boolean visit(PrimitiveType node) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedName)
+	 */
+	public boolean visit(QualifiedName node) {
+		visit(node, true);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ReturnStatement)
+	 */
+	public boolean visit(ReturnStatement node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleName)
+	 */
+	public boolean visit(SimpleName node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleType)
+	 */
+	public boolean visit(SimpleType node) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleVariableDeclaration)
+	 */
+	public boolean visit(SingleVariableDeclaration node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.StringLiteral)
+	 */
+	public boolean visit(StringLiteral node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperConstructorInvocation)
+	 */
+	public boolean visit(SuperConstructorInvocation node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperFieldAccess)
+	 */
+	public boolean visit(SuperFieldAccess node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperMethodInvocation)
+	 */
+	public boolean visit(SuperMethodInvocation node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SwitchCase)
+	 */
+	public boolean visit(SwitchCase node) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SwitchStatement)
+	 */
+	public boolean visit(SwitchStatement node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SynchronizedStatement)
+	 */
+	public boolean visit(SynchronizedStatement node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ThisExpression)
+	 */
+	public boolean visit(ThisExpression node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ThrowStatement)
+	 */
+	public boolean visit(ThrowStatement node) {
+		return visit(node, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TryStatement)
+	 */
+	public boolean visit(TryStatement node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclaration)
+	 */
+	public boolean visit(TypeDeclaration node) {
+		if (visit(node, false)) {
+			// visit only the elements of the type declaration
+			List bodyDeclaration= node.bodyDeclarations();
+			for (Iterator iter= bodyDeclaration.iterator(); iter.hasNext();) {
+				((BodyDeclaration)iter.next()).accept(this);
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclarationStatement)
+	 */
+	public boolean visit(TypeDeclarationStatement node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeLiteral)
+	 */
+	public boolean visit(TypeLiteral node) {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationExpression)
+	 */
+	public boolean visit(VariableDeclarationExpression node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationFragment)
+	 */
+	public boolean visit(VariableDeclarationFragment node) {
+		return visit(node, node.getInitializer() != null);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationStatement)
+	 */
+	public boolean visit(VariableDeclarationStatement node) {
+		return visit(node, false);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.WhileStatement)
+	 */
+	public boolean visit(WhileStatement node) {
+		return visit(node, false);
+	}
+
+}
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/DirectorySourceLocation.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/DirectorySourceLocation.java
index f915f36..9778851 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/DirectorySourceLocation.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/DirectorySourceLocation.java
@@ -18,7 +18,10 @@
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
+
 import org.apache.xerces.dom.DocumentImpl;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
@@ -85,6 +88,10 @@
 			String typeName = pathStr;
 			do {
 				IPath filePath = root.append(new Path(typeName + ".java")); //$NON-NLS-1$
+				IFile workspaceFile= ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(filePath);
+				if (workspaceFile != null) {
+					return workspaceFile;
+				}
 				File file = filePath.toFile();
 				if (file.exists()) {
 					return new LocalFileStorage(file);