/*******************************************************************************
 *  Copyright (c) 2000, 2016 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *     Freescale - Teodor Madan - Show IP for active frame only (Bug 49730)
 *     RedHat - Andrew Ferrazzutti - Source lookup ignores ISourceLocator if artifact was cached (Bug 436411)
 *******************************************************************************/
package org.eclipse.debug.internal.ui.sourcelookup;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

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.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.InstructionPointerManager;
import org.eclipse.debug.internal.ui.views.DebugUIViewsMessages;
import org.eclipse.debug.internal.ui.views.launch.Decoration;
import org.eclipse.debug.internal.ui.views.launch.DecorationManager;
import org.eclipse.debug.internal.ui.views.launch.SourceNotFoundEditorInput;
import org.eclipse.debug.internal.ui.views.launch.StandardDecoration;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugEditorPresentation;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IInstructionPointerPresentation;
import org.eclipse.debug.ui.ISourcePresentation;
import org.eclipse.debug.ui.sourcelookup.CommonSourceNotFoundEditorInput;
import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPageListener;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * Utility methods for looking up and displaying source.
 *
 * @since 3.1
 */
public class SourceLookupFacility implements IPageListener, IPartListener2, IPropertyChangeListener, IDebugEventSetListener {

	/**
	 * Provides an LRU cache with a given max size
	 *
	 * @since 3.10
	 */
	static class LRU extends HashMap<Object, SourceLookupResult> {
		private static final long serialVersionUID = 1L;

		ArrayList<Object> fEntryStack = null;
		int fSize;

		/**
		 * Constructor
		 *
		 * @param size The desired size
		 */
		LRU(int size) {
			fSize = size;
			fEntryStack = new ArrayList<>();
		}

		/*
		 * (non-Javadoc)
		 * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
		 */
		@Override
		public SourceLookupResult put(Object key, SourceLookupResult value) {
			shuffle(key);
			return super.put(key, value);
		}

		/*
		 * (non-Javadoc)
		 * @see java.util.HashMap#remove(java.lang.Object)
		 */
		@Override
		public SourceLookupResult remove(Object key) {
			SourceLookupResult oldResult = super.remove(key);
			fEntryStack.remove(key);
			return oldResult;
		}

		/**
		 * Shuffles the entry stack and removes mapped results as needed
		 *
		 * @param key
		 */
		void shuffle(Object key) {
			int index = fEntryStack.indexOf(key);
			if (index < 0) {
				if (fEntryStack.size() >= fSize) {
					remove(fEntryStack.get(fEntryStack.size() - 1));
				}
			} else {
				fEntryStack.remove(index);
			}
			fEntryStack.add(0, key);
		}

		@Override
		public void clear() {
			fEntryStack.clear();
			super.clear();
		}
	}

	/**
	 * Singleton source lookup facility
	 */
	private static SourceLookupFacility fgDefault;

	/**
	 * Contains a map of the editor to use for each workbench page, when the
	 * 'reuse editor' preference is on.
	 */
	private Map<IWorkbenchPage, IEditorPart> fEditorsByPage;

	/**
	 * Contains a mapping of artifacts to the source element that was computed
	 * for them.
	 *
	 * @since 3.10
	 */
	private static LRU fLookupResults = new LRU(10);

	/**
	 * Used to generate annotations for stack frames
	 */
	private IInstructionPointerPresentation fPresentation = (IInstructionPointerPresentation) DebugUITools.newDebugModelPresentation();

	/**
	 * Whether to re-use editors when displaying source.
	 */
	private boolean fReuseEditor = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR);

	/**
	 * Constructs singleton source display adapter for stack frames.
	 */
	/**
	 * Returns the source lookup facility
	 *
	 * @return
	 */
	public static SourceLookupFacility getDefault() {
		if (fgDefault == null) {
			fgDefault = new SourceLookupFacility();
		}
		return fgDefault;
	}

	/**
	 * Performs cleanup
	 */
	public static void shutdown() {
		if (fgDefault != null) {
			fgDefault.dispose();
		}
	}

	/**
	 * Constructs a source lookup facility.
	 */
	private SourceLookupFacility() {
		fEditorsByPage = new HashMap<>();
		DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
		DebugPlugin.getDefault().addDebugEventListener(this);
	}

	@Override
	public void handleDebugEvents(DebugEvent[] events) {
		IStackFrame frame = null;
		for (int i = 0; i < events.length; i++) {
			final DebugEvent event = events[i];
			switch (event.getKind()) {
				case DebugEvent.TERMINATE:
				case DebugEvent.RESUME:
					if (!event.isEvaluation()) {
						Job uijob = new UIJob("clear source selection") { //$NON-NLS-1$
							@Override
							public IStatus runInUIThread(IProgressMonitor monitor) {
								clearSourceSelection(event.getSource());
								return Status.OK_STATUS;
							}

						};
						uijob.setSystem(true);
						uijob.schedule();
					}
					break;
				case DebugEvent.CHANGE:
					if (event.getSource() instanceof IStackFrame) {
						if (event.getDetail() == DebugEvent.CONTENT) {
							frame = (IStackFrame) event.getSource();
							fLookupResults.remove(new ArtifactWithLocator(frame, frame.getLaunch().getSourceLocator()));
						}
					}
					break;
				default:
					break;
			}
		}
	}

	private class ArtifactWithLocator {
		public final Object artifact;
		public final ISourceLocator locator;
		public ArtifactWithLocator(Object artifact, ISourceLocator locator) {
			this.artifact = artifact;
			this.locator = locator;
		}

		/*
		 * (non-Javadoc)
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + getOuterType().hashCode();
			result = prime * result + ((artifact == null) ? 0 : artifact.hashCode());
			result = prime * result + ((locator == null) ? 0 : locator.hashCode());
			return result;
		}

		/*
		 * (non-Javadoc)
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object obj) {
			if (this == obj) {
				return true;
			}
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			ArtifactWithLocator other = (ArtifactWithLocator) obj;
			if (!getOuterType().equals(other.getOuterType())) {
				return false;
			}
			if (artifact == null) {
				if (other.artifact != null) {
					return false;
				}
			} else if (!artifact.equals(other.artifact)) {
				return false;
			}
			if (locator == null) {
				if (other.locator != null) {
					return false;
				}
			} else if (!locator.equals(other.locator)) {
				return false;
			}
			return true;
		}

		private SourceLookupFacility getOuterType() {
			return SourceLookupFacility.this;
		}
	}

	/**
	 * Performs source lookup for the given artifact and returns the result.
	 *
	 * @param artifact object for which source is to be resolved
	 * @param locator the source locator to use, or <code>null</code>. When
	 *            <code>null</code> a source locator is determined from the
	 *            artifact, if possible. If the artifact is a debug element, the
	 *            source locator from its associated launch is used.
	 * @param force If we should ignore the cached value and re-look up
	 * @return a source lookup result
	 */
	public SourceLookupResult lookup(Object artifact, ISourceLocator locator, boolean force) {
		SourceLookupResult result = null;
		synchronized (fLookupResults) {
			ArtifactWithLocator key = new ArtifactWithLocator(artifact, locator);
			if (!force) {
				result = fLookupResults.get(key);
				if (result != null) {
					return result;
				}
			}
			result = new SourceLookupResult(artifact, null, null, null);
			IDebugElement debugElement = null;
			if (artifact instanceof IDebugElement) {
				debugElement = (IDebugElement) artifact;
			}
			ISourceLocator localLocator = locator;
			if (localLocator == null) {
				ILaunch launch = null;
				if (debugElement != null) {
					launch = debugElement.getLaunch();
				}
				if (launch != null) {
					localLocator = launch.getSourceLocator();
				}
			}
			if (localLocator != null) {
				String editorId = null;
				IEditorInput editorInput = null;
				Object sourceElement = null;
				if (localLocator instanceof ISourceLookupDirector) {
					ISourceLookupDirector director = (ISourceLookupDirector) localLocator;
					sourceElement = director.getSourceElement(artifact);
				} else {
					if (artifact instanceof IStackFrame) {
						sourceElement = localLocator.getSourceElement((IStackFrame) artifact);
					}
				}
				if (sourceElement == null) {
					if (localLocator instanceof AbstractSourceLookupDirector) {
						editorInput = new CommonSourceNotFoundEditorInput(artifact);
						editorId = IDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR;
					} else {
						if (artifact instanceof IStackFrame) {
							IStackFrame frame = (IStackFrame) artifact;
							editorInput = new SourceNotFoundEditorInput(frame);
							editorId = IInternalDebugUIConstants.ID_SOURCE_NOT_FOUND_EDITOR;
						}
					}
				} else {
					ISourcePresentation presentation = null;
					if (localLocator instanceof ISourcePresentation) {
						presentation = (ISourcePresentation) localLocator;
					} else {
						if (debugElement != null) {
							presentation = getPresentation(debugElement.getModelIdentifier());
						}
					}
					if (presentation != null) {
						editorInput = presentation.getEditorInput(sourceElement);
					}
					if (editorInput != null && presentation != null) {
						editorId = presentation.getEditorId(editorInput, sourceElement);
					}
				}
				result.setEditorInput(editorInput);
				result.setEditorId(editorId);
				result.setSourceElement(sourceElement);
				fLookupResults.put(key, result);
			}
		}
		return result;
    }

    /**
     * Returns the model presentation for the given debug model, or <code>null</code>
     * if none.
     *
     * @param id debug model id
     * @return presentation for the model, or <code>null</code> if none.
     */
	protected IDebugModelPresentation getPresentation(String id) {
		return ((DelegatingModelPresentation)DebugUIPlugin.getModelPresentation()).getPresentation(id);
	}

	/**
	 * Returns an editor presentation.
	 *
	 * @return an editor presentation
	 */
	protected IDebugEditorPresentation getEditorPresentation() {
	    return (DelegatingModelPresentation)DebugUIPlugin.getModelPresentation();
	}

    /**
     * Opens an editor in the given workbench page for the given source lookup
     * result. Has no effect if the result has an unknown editor id or editor input.
     * The editor is opened, positioned, and annotated.
     * <p>
     * Honor's the user preference of whether to re-use editors when displaying source.
     * </p>
     * @param result source lookup result to display
     * @param page the page to display the result in
     */
    public void display(ISourceLookupResult result, IWorkbenchPage page) {
		IEditorPart editor= openEditor(result, page);
		if (editor == null) {
			return;
		}
		IStackFrame frame = null;
        if (result.getArtifact() instanceof IStackFrame) {
            frame = (IStackFrame) result.getArtifact();
        }
		// position and annotate editor for stack frame
        if (frame != null) {
			IDebugEditorPresentation editorPresentation = getEditorPresentation();
            if (editorPresentation.addAnnotations(editor, frame)) {
				Decoration decoration = new StandardDecoration(editorPresentation, editor, frame.getThread());
				DecorationManager.addDecoration(decoration);
			} else {
				// perform standard positioning and annotations
				ITextEditor textEditor = null;
				if (editor instanceof ITextEditor) {
					textEditor = (ITextEditor)editor;
				} else {
					textEditor = editor.getAdapter(ITextEditor.class);
				}
				if (textEditor != null) {
					positionEditor(textEditor, frame);
					InstructionPointerManager.getDefault().removeAnnotations(textEditor);
					Annotation annotation = fPresentation.getInstructionPointerAnnotation(textEditor, frame);
					if (annotation != null) {
						InstructionPointerManager.getDefault().addAnnotation(textEditor, frame, annotation);
					}
				}
			}
		}
    }

	/**
	 * Opens the editor used to display the source for an element selected in
	 * this view and returns the editor that was opened or <code>null</code> if
	 * no editor could be opened.
	 */
	private IEditorPart openEditor(ISourceLookupResult result, IWorkbenchPage page) {
		IEditorPart editor = null;
		IEditorInput input= result.getEditorInput();
		String id= result.getEditorId();
		if (input == null || id == null) {
			return null;
		}

		if (fReuseEditor) {
			IEditorReference[] references = page.findEditors(input, id, IWorkbenchPage.MATCH_ID | IWorkbenchPage.MATCH_INPUT);
			if (references.length > 0) {
				// activate the editor we want to reuse
				IEditorPart refEditor= references[0].getEditor(false);
				editor = refEditor;
				page.bringToTop(editor);
			}
			if (editor == null) {
			    IEditorPart editorForPage = getEditor(page);
				if (editorForPage == null || editorForPage.isDirty() || page.isEditorPinned(editorForPage)) {
				    // open a new editor
					editor = openEditor(page, input, id);
					editorForPage = editor;
				} else if (editorForPage instanceof IReusableEditor && editorForPage.getSite().getId().equals(id)) {
				    // re-use editor
					page.reuseEditor((IReusableEditor)editorForPage, input);
					editor = editorForPage;
                    if(!page.isPartVisible(editor)) {
                        page.bringToTop(editor);
                    }
				} else {
				    // close editor, open a new one
					editor = openEditor(page, input, id);
					page.closeEditor(editorForPage, false);
					editorForPage = editor;
				}
				setEditor(page, editorForPage);
			}
		} else {
			// Open a new editor
			editor = openEditor(page, input, id);
		}
		return editor;
	}

	/**
	 * Positions the text editor for the given stack frame
	 */
	private void positionEditor(ITextEditor editor, IStackFrame frame) {
		try {
			int charStart = frame.getCharStart();
			if (charStart >= 0) {
				editor.selectAndReveal(charStart, 0);
				return;
			}
			int lineNumber = frame.getLineNumber();
			lineNumber--; // Document line numbers are 0-based. Debug line numbers are 1-based.
			IRegion region= getLineInformation(editor, lineNumber);
			if (region != null) {
				editor.selectAndReveal(region.getOffset(), 0);
			}
		} catch (DebugException e) {
		}
	}

	/**
	 * Returns the line information for the given line in the given editor
	 */
	private IRegion getLineInformation(ITextEditor editor, int lineNumber) {
		IDocumentProvider provider= editor.getDocumentProvider();
		IEditorInput input= editor.getEditorInput();
		try {
			provider.connect(input);
		} catch (CoreException e) {
			return null;
		}
		try {
			IDocument document= provider.getDocument(input);
			if (document != null) {
				return document.getLineInformation(lineNumber);
			}
		} catch (BadLocationException e) {
		} finally {
			provider.disconnect(input);
		}
		return null;
	}
	/**
	 * Opens an editor in the workbench and returns the editor that was opened
	 * or <code>null</code> if an error occurred while attempting to open the
	 * editor.
	 */
	private IEditorPart openEditor(final IWorkbenchPage page, final IEditorInput input, final String id) {
		final IEditorPart[] editor = new IEditorPart[] {null};
		Runnable r = new Runnable() {
			@Override
			public void run() {
				if (!page.getWorkbenchWindow().getWorkbench().isClosing()) {
					try {
						editor[0] = page.openEditor(input, id, false, IWorkbenchPage.MATCH_ID|IWorkbenchPage.MATCH_INPUT);
					} catch (PartInitException e) {
						DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(),
							DebugUIViewsMessages.LaunchView_Error_1,
							DebugUIViewsMessages.LaunchView_Exception_occurred_opening_editor_for_debugger__2,
							e);
					}
				}
			}
		};
		BusyIndicator.showWhile(DebugUIPlugin.getStandardDisplay(), r);
		return editor[0];
	}

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPageListener#pageActivated(org.eclipse.ui.IWorkbenchPage)
     */
    @Override
	public void pageActivated(IWorkbenchPage page) {
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPageListener#pageClosed(org.eclipse.ui.IWorkbenchPage)
     */
    @Override
	public void pageClosed(IWorkbenchPage page) {
        fEditorsByPage.remove(page);
        page.removePartListener(this);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPageListener#pageOpened(org.eclipse.ui.IWorkbenchPage)
     */
    @Override
	public void pageOpened(IWorkbenchPage page) {
    	page.addPartListener(this);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference)
     */
    @Override
	public void partActivated(IWorkbenchPartReference partRef) {
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPartListener2#partBroughtToTop(org.eclipse.ui.IWorkbenchPartReference)
     */
    @Override
	public void partBroughtToTop(IWorkbenchPartReference partRef) {
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference)
     */
    @Override
	public void partClosed(IWorkbenchPartReference partRef) {
        // clear the cached editor for the page if it has been closed
        IWorkbenchPage page = partRef.getPage();
        IEditorPart editor = getEditor(page);
        IWorkbenchPart part = partRef.getPart(false);
		if (part != null && part.equals(editor)) {
			fEditorsByPage.remove(page);
		}
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.IWorkbenchPartReference)
     */
    @Override
	public void partDeactivated(IWorkbenchPartReference partRef) {
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.IWorkbenchPartReference)
     */
    @Override
	public void partOpened(IWorkbenchPartReference partRef) {
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.IWorkbenchPartReference)
     */
    @Override
	public void partHidden(IWorkbenchPartReference partRef) {
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference)
     */
    @Override
	public void partVisible(IWorkbenchPartReference partRef) {
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference)
     */
    @Override
	public void partInputChanged(IWorkbenchPartReference partRef) {
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
     */
    @Override
	public void propertyChange(PropertyChangeEvent event) {
        String property = event.getProperty();
		if (property.equals(IDebugUIConstants.PREF_REUSE_EDITOR)) {
			fReuseEditor = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR);
		}
    }

    /**
     * Returns the editor to use to display source in the given page, or
     * <code>null</code> if a new editor should be opened.
     *
     * @param page workbench page
     * @return the editor to use to display source in the given page, or
     * <code>null</code> if a new editor should be opened
     */
    protected IEditorPart getEditor(IWorkbenchPage page) {
        return fEditorsByPage.get(page);
    }

    /**
     * Sets the editor to use to display source in the given page, or
     * <code>null</code> if a new editor should be opened.
     *
     * @param page workbench page
     * @return the editor to use to display source in the given page, or
     * <code>null</code> if a new editor should be opened
     */
    protected void setEditor(IWorkbenchPage page, IEditorPart editorPart) {
        if (editorPart == null) {
            fEditorsByPage.remove(page);
        } else {
            fEditorsByPage.put(page, editorPart);
        }
        page.addPartListener(this);
        page.getWorkbenchWindow().addPageListener(this);
    }

    /**
     * Performs cleanup.
     */
    protected void dispose() {
        DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
		DebugPlugin.getDefault().removeDebugEventListener(this);
        fEditorsByPage.clear();
        fPresentation.dispose();
		fLookupResults.clear();
    }

	/**
	 * A job to perform source lookup on the currently selected stack frame.
	 */
	class SourceLookupJob extends Job {

		private IStackFrame fTarget;
		private ISourceLocator fLocator;
		private IWorkbenchPage fPage;
		private boolean fForce = false;

		/**
		 * Constructs a new source lookup job.
		 */
		public SourceLookupJob(IStackFrame frame, ISourceLocator locator, IWorkbenchPage page, boolean force) {
			super("Debug Source Lookup"); //$NON-NLS-1$
			setPriority(Job.INTERACTIVE);
			setSystem(true);
			fTarget = frame;
			fLocator = locator;
			fPage = page;
			fForce = force;
			// Note: Be careful when trying to use scheduling rules with this
			// job, in order to avoid blocking nested jobs (bug 339542).
		}

		/*
		 * (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.
		 * IProgressMonitor)
		 */
		@Override
		protected IStatus run(IProgressMonitor monitor) {
			if (!monitor.isCanceled()) {
				if (!fTarget.isTerminated()) {
					ISourceLookupResult result = lookup(fTarget, fLocator, fForce);
					if (!monitor.isCanceled() && !fTarget.isTerminated() && fPage != null) {
						new SourceDisplayJob(result, fPage).schedule();
					}
				}
			}
			return Status.OK_STATUS;
		}

		/*
		 * (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object)
		 */
		@Override
		public boolean belongsTo(Object family) {
			// source lookup jobs are a family per workbench page
			if (family instanceof SourceLookupJob) {
				SourceLookupJob slj = (SourceLookupJob) family;
				return slj.fPage.equals(fPage);
			}
			return false;
		}

	}

	class SourceDisplayJob extends UIJob {

		private ISourceLookupResult fResult;
		private IWorkbenchPage fPage;

		public SourceDisplayJob(ISourceLookupResult result, IWorkbenchPage page) {
			super("Debug Source Display"); //$NON-NLS-1$
			setSystem(true);
			setPriority(Job.INTERACTIVE);
			fResult = result;
			fPage = page;
		}

		/*
		 * (non-Javadoc)
		 * @see
		 * org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime
		 * .IProgressMonitor)
		 */
		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) {
			if (!monitor.isCanceled() && fResult != null) {
				display(fResult, fPage);
				// termination may have occurred while displaying source
				if (monitor.isCanceled()) {
					Object artifact = fResult.getArtifact();
					if (artifact instanceof IStackFrame) {
						clearSourceSelection(((IStackFrame) artifact).getThread());
					}
				}
			}

			return Status.OK_STATUS;
		}

		/*
		 * (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object)
		 */
		@Override
		public boolean belongsTo(Object family) {
			// source display jobs are a family per workbench page
			if (family instanceof SourceDisplayJob) {
				SourceDisplayJob sdj = (SourceDisplayJob) family;
				return sdj.fPage.equals(fPage);
			}
			return false;
		}

	}

	/*
	 * (non-Javadoc)
	 * @see
	 * org.eclipse.debug.ui.contexts.ISourceDisplayAdapter#displaySource(java
	 * .lang.Object, org.eclipse.ui.IWorkbenchPage, boolean)
	 */
	public synchronized void displaySource(Object context, IWorkbenchPage page, boolean force) {
		IStackFrame frame = (IStackFrame) context;
		SourceLookupJob slj = new SourceLookupJob(frame, frame.getLaunch().getSourceLocator(), page, force);
		// cancel any existing source lookup jobs for this page
		Job.getJobManager().cancel(slj);
		slj.schedule();
	}

	/**
	 * Clears any source decorations associated with the given thread or debug
	 * target.
	 *
	 * @param source thread or debug target
	 */
	private void clearSourceSelection(Object source) {
		if (source instanceof IThread) {
			IThread thread = (IThread) source;
			DecorationManager.removeDecorations(thread);
			InstructionPointerManager.getDefault().removeAnnotations(thread);
		} else if (source instanceof IDebugTarget) {
			IDebugTarget target = (IDebugTarget) source;
			DecorationManager.removeDecorations(target);
			InstructionPointerManager.getDefault().removeAnnotations(target);
		}
	}
}
