Progress on: 108021: make monitor listen to all preference changes
https://bugs.eclipse.org/bugs/show_bug.cgi?id=108021
diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/DegreeOfInterest.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/DegreeOfInterest.java
index 6f5d8fd..5246c1f 100644
--- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/DegreeOfInterest.java
+++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/DegreeOfInterest.java
@@ -61,7 +61,7 @@
 		events.add(0, event);
 		InteractionEvent last = collapsedEvents.get(event.getKind());
 		if (last != null) {
-			InteractionEvent aggregateEvent = new InteractionEvent(event.getKind(), event.getContentType(), event
+			InteractionEvent aggregateEvent = new InteractionEvent(event.getKind(), event.getStructureKind(), event
 					.getStructureHandle(), event.getOriginId(), event.getNavigation(), event.getDelta(), last
 					.getInterestContribution()
 					+ event.getInterestContribution(), last.getDate(), event.getEndDate());
@@ -163,7 +163,7 @@
 		allCollapsed.addAll(collapsedEvents.values());
 		if (!allCollapsed.isEmpty()) {
 			allCollapsed.add(0, new InteractionEvent(InteractionEvent.Kind.MANIPULATION, allCollapsed.get(0)
-					.getContentType(), allCollapsed.get(0).getStructureHandle(), MylarContextManager.SOURCE_ID_DECAY,
+					.getStructureKind(), allCollapsed.get(0).getStructureHandle(), MylarContextManager.SOURCE_ID_DECAY,
 					-getDecayValue()));
 		}
 		return allCollapsed;
diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/MylarContext.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/MylarContext.java
index 4800b05..7137e7b 100644
--- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/MylarContext.java
+++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/MylarContext.java
@@ -76,7 +76,7 @@
 			numUserEvents++;
 		MylarContextElement node = nodes.get(event.getStructureHandle());
 		if (node == null) {
-			node = new MylarContextElement(event.getContentType(), event.getStructureHandle(), this);
+			node = new MylarContextElement(event.getStructureKind(), event.getStructureHandle(), this);
 			nodes.put(event.getStructureHandle(), node);
 		}
 
@@ -87,7 +87,7 @@
 			if (navigationSource != null) {
 				MylarContextRelation edge = lastEdgeNode.getRelation(event.getStructureHandle());
 				if (edge == null) {
-					edge = new MylarContextRelation(event.getContentType(), event.getNavigation(), lastEdgeNode, node,
+					edge = new MylarContextRelation(event.getStructureKind(), event.getNavigation(), lastEdgeNode, node,
 							this);
 					lastEdgeNode.addEdge(edge);
 				}
diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/MylarContextManager.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/MylarContextManager.java
index 3d808d5..e2ec0ab 100644
--- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/MylarContextManager.java
+++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/MylarContextManager.java
@@ -348,7 +348,7 @@
 			previouslyPropagated = previous.getInterest().isPropagated();
 		}
 		if (event.getKind().isUserEvent()) {
-			decayOffset = ensureIsInteresting(event.getContentType(), event.getStructureHandle(), previous, previousInterest);
+			decayOffset = ensureIsInteresting(event.getStructureKind(), event.getStructureHandle(), previous, previousInterest);
 		}
 		IMylarElement element = currentContext.addEvent(event);
 		List<IMylarElement> interestDelta = new ArrayList<IMylarElement>();
diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/util/SaxContextWriter.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/util/SaxContextWriter.java
index f4db8d2..0ba36e2 100644
--- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/util/SaxContextWriter.java
+++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/internal/core/util/SaxContextWriter.java
@@ -177,7 +177,7 @@
 								.getStructureHandle()));
 				ieAttributes.addAttribute("", MylarContextExternalizer.ATR_STRUCTURE_KIND,
 						MylarContextExternalizer.ATR_STRUCTURE_KIND, "", XmlStringConverter.convertToXmlString(ie
-								.getContentType()));
+								.getStructureKind()));
 
 				handler.startElement("", SaxContextContentHandler.ATTRIBUTE_INTERACTION_EVENT,
 						SaxContextContentHandler.ATTRIBUTE_INTERACTION_EVENT, ieAttributes);
diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/provisional/core/AbstractUserInteractionMonitor.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/provisional/core/AbstractUserInteractionMonitor.java
index 64836b6..51357e3 100644
--- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/provisional/core/AbstractUserInteractionMonitor.java
+++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/provisional/core/AbstractUserInteractionMonitor.java
@@ -50,48 +50,63 @@
 		if (selection == null || selection.isEmpty())
 			return;
 		if (!MylarPlugin.getContextManager().isContextActive()) {
-			return;
+			handleWorkbenchPartSelection(part, selection, false);
 		} else {
-			handleWorkbenchPartSelection(part, selection);
+			handleWorkbenchPartSelection(part, selection, true);
 		}
 	}
 
-	protected abstract void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection);
+	protected abstract void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection, boolean contributeToContext);
 
 	/**
 	 * Intended to be called back by subclasses.
 	 */
-	protected InteractionEvent handleElementSelection(IWorkbenchPart part, Object selectedElement) {
+	protected InteractionEvent handleElementSelection(IWorkbenchPart part, Object selectedElement, boolean contributeToContext) {
 		if (selectedElement == null || selectedElement.equals(lastSelectedElement))
 			return null;
 		IMylarStructureBridge bridge = MylarPlugin.getDefault().getStructureBridge(selectedElement);
-		InteractionEvent selectionEvent = new InteractionEvent(InteractionEvent.Kind.SELECTION,
-				bridge.getContentType(), bridge.getHandleIdentifier(selectedElement), part.getSite().getId());
-		MylarPlugin.getContextManager().handleInteractionEvent(selectionEvent);
+		InteractionEvent selectionEvent;
+		if (bridge.getContentType() != null) {
+			selectionEvent = new InteractionEvent(InteractionEvent.Kind.SELECTION,
+					bridge.getContentType(), bridge.getHandleIdentifier(selectedElement), part.getSite().getId());
+		} else {
+			selectionEvent = new InteractionEvent(InteractionEvent.Kind.SELECTION,
+					null, null, part.getSite().getId());			
+		}
+		if (contributeToContext) {
+			MylarPlugin.getContextManager().handleInteractionEvent(selectionEvent);
+		}
+		MylarPlugin.getDefault().notifyInteractionObserved(selectionEvent);
 		return selectionEvent;
 	}
 
 	/**
 	 * Intended to be called back by subclasses.
 	 */
-	protected void handleElementEdit(IWorkbenchPart part, Object selectedElement) {
+	protected void handleElementEdit(IWorkbenchPart part, Object selectedElement, boolean contributeToContext) {
 		if (selectedElement == null)
 			return;
 		IMylarStructureBridge bridge = MylarPlugin.getDefault().getStructureBridge(selectedElement);
-		InteractionEvent selectionEvent = new InteractionEvent(InteractionEvent.Kind.EDIT, bridge.getContentType(),
+		InteractionEvent editEvent = new InteractionEvent(InteractionEvent.Kind.EDIT, bridge.getContentType(),
 				bridge.getHandleIdentifier(selectedElement), part.getSite().getId());
-		MylarPlugin.getContextManager().handleInteractionEvent(selectionEvent);
+		if (contributeToContext) {
+			MylarPlugin.getContextManager().handleInteractionEvent(editEvent);
+		}
+		MylarPlugin.getDefault().notifyInteractionObserved(editEvent);
 	}
 
 	/**
 	 * Intended to be called back by subclasses.
 	 */
-	protected void handleNavigation(IWorkbenchPart part, Object targetElement, String kind) {
+	protected void handleNavigation(IWorkbenchPart part, Object targetElement, String kind, boolean contributeToContext) {
 		IMylarStructureBridge adapter = MylarPlugin.getDefault().getStructureBridge(targetElement);
 		if (adapter.getContentType() != null) {
-			InteractionEvent selectionEvent = new InteractionEvent(InteractionEvent.Kind.SELECTION, adapter
+			InteractionEvent navigationEvent = new InteractionEvent(InteractionEvent.Kind.SELECTION, adapter
 					.getContentType(), adapter.getHandleIdentifier(targetElement), part.getSite().getId(), kind);
-			MylarPlugin.getContextManager().handleInteractionEvent(selectionEvent);
+			if (contributeToContext) {
+				MylarPlugin.getContextManager().handleInteractionEvent(navigationEvent);
+			}
+			MylarPlugin.getDefault().notifyInteractionObserved(navigationEvent);
 		}
 	}
 
diff --git a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/provisional/core/InteractionEvent.java b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/provisional/core/InteractionEvent.java
index bfef3d4..71e9041 100644
--- a/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/provisional/core/InteractionEvent.java
+++ b/org.eclipse.mylyn.context.core/src/org/eclipse/mylyn/provisional/core/InteractionEvent.java
@@ -119,10 +119,6 @@
 		return new InteractionEvent(InteractionEvent.Kind.COMMAND, "null", "null", originId, "null", delta, 1);
 	}
 
-	public String getStructureKind() {
-		return structureKind;
-	}
-
 	/**
 	 * Factory method.
 	 */
@@ -226,7 +222,7 @@
 		return structureHandle;
 	}
 
-	public String getContentType() {
+	public String getStructureKind() {
 		return structureKind;
 	}
 
diff --git a/org.eclipse.mylyn.context.tests/src/org/eclipse/mylyn/core/tests/support/DomContextWriter.java b/org.eclipse.mylyn.context.tests/src/org/eclipse/mylyn/core/tests/support/DomContextWriter.java
index ca6e46a..1b85764 100644
--- a/org.eclipse.mylyn.context.tests/src/org/eclipse/mylyn/core/tests/support/DomContextWriter.java
+++ b/org.eclipse.mylyn.context.tests/src/org/eclipse/mylyn/core/tests/support/DomContextWriter.java
@@ -105,7 +105,7 @@
 		node.setAttribute("StartDate", format.format(e.getDate()));
 		node.setAttribute("EndDate", format.format(e.getEndDate()));
 		node.setAttribute("OriginId", XmlStringConverter.convertToXmlString(e.getOriginId()));
-		node.setAttribute("StructureKind", XmlStringConverter.convertToXmlString(e.getContentType()));
+		node.setAttribute("StructureKind", XmlStringConverter.convertToXmlString(e.getStructureKind()));
 		node.setAttribute("StructureHandle", XmlStringConverter.convertToXmlString(e.getStructureHandle()));
 		node.setAttribute("Navigation", XmlStringConverter.convertToXmlString(e.getNavigation()));
 		node.setAttribute("Delta", XmlStringConverter.convertToXmlString(e.getDelta()));
@@ -127,7 +127,7 @@
 		root.setAttribute("StartDate", format.format(e.getDate()));
 		root.setAttribute("EndDate", format.format(e.getEndDate()));
 		root.setAttribute("OriginId", XmlStringConverter.convertToXmlString(e.getOriginId()));
-		root.setAttribute("StructureKind", XmlStringConverter.convertToXmlString(e.getContentType()));
+		root.setAttribute("StructureKind", XmlStringConverter.convertToXmlString(e.getStructureKind()));
 		root.setAttribute("StructureHandle", XmlStringConverter.convertToXmlString(e.getStructureHandle()));
 		root.setAttribute("Navigation", XmlStringConverter.convertToXmlString(e.getNavigation()));
 		root.setAttribute("Delta", XmlStringConverter.convertToXmlString(e.getDelta()));
diff --git a/org.eclipse.mylyn.context.tests/src/org/eclipse/mylyn/core/tests/support/TestMonitor.java b/org.eclipse.mylyn.context.tests/src/org/eclipse/mylyn/core/tests/support/TestMonitor.java
index bff6ada..4587159 100644
--- a/org.eclipse.mylyn.context.tests/src/org/eclipse/mylyn/core/tests/support/TestMonitor.java
+++ b/org.eclipse.mylyn.context.tests/src/org/eclipse/mylyn/core/tests/support/TestMonitor.java
@@ -58,7 +58,7 @@
 	}
 
 	@Override
-	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection) {
+	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection, boolean contributeToContext) {
 		// don't need to do anything here
 
 	}
diff --git a/org.eclipse.mylyn.ide.ui/src/org/eclipse/mylyn/internal/ide/ResourceInteractionMonitor.java b/org.eclipse.mylyn.ide.ui/src/org/eclipse/mylyn/internal/ide/ResourceInteractionMonitor.java
index 3a7c0c7..af57f5c 100644
--- a/org.eclipse.mylyn.ide.ui/src/org/eclipse/mylyn/internal/ide/ResourceInteractionMonitor.java
+++ b/org.eclipse.mylyn.ide.ui/src/org/eclipse/mylyn/internal/ide/ResourceInteractionMonitor.java
@@ -31,14 +31,14 @@
 public class ResourceInteractionMonitor extends AbstractUserInteractionMonitor {
 
 	@Override
-	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection) {
+	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection, boolean contributeToContext) {
 		if (selection instanceof StructuredSelection) {
 			StructuredSelection structuredSelection = (StructuredSelection) selection;
 
 			Object selectedObject = structuredSelection.getFirstElement();
 			if (selectedObject instanceof File) {
 				File file = (File) selectedObject;
-				super.handleElementSelection(part, file);
+				super.handleElementSelection(part, file, contributeToContext);
 			}
 		} else if (selection instanceof TextSelection) {
 			if (part instanceof EditorPart) {
@@ -47,7 +47,7 @@
 					if (object instanceof IFile) {
 						IFile file = (IFile) object;
 						if (!MylarPlugin.getDefault().getKnownContentTypes().contains(file.getFileExtension())) {
-							super.handleElementEdit(part, object);
+							super.handleElementEdit(part, object, contributeToContext);
 						}
 					}
 				} catch (Throwable t) {
diff --git a/org.eclipse.mylyn.java.ui/plugin.xml b/org.eclipse.mylyn.java.ui/plugin.xml
index 4fe4169..c3a4afe 100644
--- a/org.eclipse.mylyn.java.ui/plugin.xml
+++ b/org.eclipse.mylyn.java.ui/plugin.xml
@@ -25,6 +25,13 @@
 	          contentType="java"/>
 	</extension>
 	
+	<extension
+          point="org.eclipse.mylar.tasklist.editors">
+       <hyperlinkDetector
+             class="org.eclipse.mylar.internal.java.ui.JavaStackTraceHyperlinkDetector"
+             id="org.eclipse.mylar.java.hyperlink.detector.stack"/>
+    </extension>
+	
 	<!-- Content Assist -->
 	<extension
 		point="org.eclipse.jdt.ui.javaCompletionProposalComputer"
diff --git a/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/JavaEditingMonitor.java b/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/JavaEditingMonitor.java
index 81771b8..2848930 100644
--- a/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/JavaEditingMonitor.java
+++ b/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/JavaEditingMonitor.java
@@ -50,7 +50,7 @@
 	 * Only public for testing
 	 */
 	@Override
-	public void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection) {
+	public void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection, boolean contributeToContext) {
 		try {
 			IJavaElement selectedElement = null;
 			if (selection instanceof StructuredSelection) {
@@ -70,7 +70,7 @@
 					}
 				}
 				if (selectedElement != null)
-					super.handleElementSelection(part, selectedElement);
+					super.handleElementSelection(part, selectedElement, contributeToContext);
 			} else {
 				if (selection instanceof TextSelection && part instanceof JavaEditor) {
 					currentEditor = (JavaEditor) part;
@@ -88,30 +88,30 @@
 						if (lastResolvedElement != null && lastSelectedElement != null
 								&& lastResolvedElement.equals(selectedElement)
 								&& !lastSelectedElement.equals(lastResolvedElement)) {
-							super.handleNavigation(part, selectedElement, JavaReferencesProvider.ID);
+							super.handleNavigation(part, selectedElement, JavaReferencesProvider.ID, contributeToContext);
 							selectionResolved = true;
 						} else if (lastSelectedElement != null && lastSelectedElement.equals(lastResolvedElement)
 								&& !lastSelectedElement.equals(selectedElement)) {
-							super.handleNavigation(part, selectedElement, JavaReferencesProvider.ID);
+							super.handleNavigation(part, selectedElement, JavaReferencesProvider.ID, contributeToContext);
 							selectionResolved = true;
 						}
 					} else if (selectedElement != null && lastSelectedElement != null
 							&& !lastSelectedElement.equals(selectedElement)) {
 						if (lastSelectedElement.getElementName().equals(selectedElement.getElementName())) {
 							if (selectedElement instanceof IMethod && lastSelectedElement instanceof IMethod) {
-								super.handleNavigation(part, selectedElement, JavaImplementorsProvider.ID);
+								super.handleNavigation(part, selectedElement, JavaImplementorsProvider.ID, contributeToContext);
 								selectionResolved = true;
 							} else if (selectedElement instanceof IType && lastSelectedElement instanceof IType) {
-								super.handleNavigation(part, selectedElement, JavaImplementorsProvider.ID);
+								super.handleNavigation(part, selectedElement, JavaImplementorsProvider.ID, contributeToContext);
 								selectionResolved = true;
 							}
 						}
 					}
 					if (selectedElement != null) {
 						if (!selectionResolved && selectedElement.equals(lastSelectedElement)) {
-							super.handleElementEdit(part, selectedElement);
+							super.handleElementEdit(part, selectedElement, contributeToContext);
 						} else if (!selectedElement.equals(lastSelectedElement)) {
-							super.handleElementSelection(part, selectedElement);
+							super.handleElementSelection(part, selectedElement, contributeToContext);
 						}
 					}
 
diff --git a/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/ui/JavaStackTraceFileHyperlink.java b/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/ui/JavaStackTraceFileHyperlink.java
new file mode 100644
index 0000000..e73f034
--- /dev/null
+++ b/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/ui/JavaStackTraceFileHyperlink.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2006 University Of British Columbia 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:
+ *     University Of British Columbia - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylar.internal.java.ui;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jdt.internal.debug.ui.actions.OpenTypeAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * @author Rob Elves
+ */
+public class JavaStackTraceFileHyperlink implements IHyperlink {
+
+	IRegion region;
+
+	String traceLine;
+
+	public JavaStackTraceFileHyperlink(IRegion region, String traceLine) {
+		this.region = region;
+		this.traceLine = traceLine;
+	}
+
+	public IRegion getHyperlinkRegion() {
+		return region;
+	}
+
+	public String getHyperlinkText() {
+		// ignore
+		return null;
+	}
+
+	public String getTypeLabel() {
+		// ignore
+		return null;
+	}
+
+	public void open() {
+
+		int lineNumber;
+		try {
+
+			String typeName = getTypeName();
+			lineNumber = getLineNumber();
+
+			// documents start at 0
+			if (lineNumber > 0) {
+				lineNumber--;
+			}
+			Object sourceElement = getSourceElement(typeName);
+			if (sourceElement != null) {
+				IDebugModelPresentation presentation = JDIDebugUIPlugin.getDefault().getModelPresentation();
+				IEditorInput editorInput = presentation.getEditorInput(sourceElement);
+				if (editorInput != null) {
+					String editorId = presentation.getEditorId(editorInput, sourceElement);
+					if (editorId != null) {
+						IEditorPart editorPart = JDIDebugUIPlugin.getActivePage().openEditor(editorInput, editorId);
+						if (editorPart instanceof ITextEditor && lineNumber >= 0) {
+							ITextEditor textEditor = (ITextEditor) editorPart;
+							IDocumentProvider provider = textEditor.getDocumentProvider();
+							provider.connect(editorInput);
+							IDocument document = provider.getDocument(editorInput);
+							try {
+								IRegion line = document.getLineInformation(lineNumber);
+								textEditor.selectAndReveal(line.getOffset(), line.getLength());
+							} catch (BadLocationException e1) {
+								MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+										.getShell(), "Open Type", "Line not found in type.");
+							}
+							provider.disconnect(editorInput);
+						}
+						return;
+					}
+				}
+			}
+			// did not find source
+			MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open Type",
+					"Type could not be located.");
+		} catch (CoreException e1) {
+			MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open Type",
+					"Failed to open type.");
+			return;
+		}
+
+	}
+
+	// adapted from JavaStackTraceHyperlink
+	private Object getSourceElement(String typeName) throws CoreException {
+		Object result = null;
+		result = OpenTypeAction.findTypeInWorkspace(typeName);
+		// }
+		return result;
+	}
+
+	// adapted from JavaStackTraceHyperlink
+	private String getTypeName() {
+		int start = traceLine.indexOf('(');
+		int end = traceLine.indexOf(':');
+		if (start >= 0 && end > start) {
+
+			// get File name (w/o .java)
+			String typeName = traceLine.substring(start + 1, end);
+			typeName.indexOf(".");
+			typeName = typeName.substring(0, typeName.indexOf("."));
+
+			String qualifier = traceLine.substring(0, start);
+			// remove the method name
+			start = qualifier.lastIndexOf('.');
+
+			if (start >= 0) {
+				// remove the class name
+				start = new String((String) qualifier.subSequence(0, start)).lastIndexOf('.');
+				if (start == -1) {
+					start = 0; // default package
+				}
+			}
+
+			if (start >= 0) {
+				qualifier = qualifier.substring(0, start);
+			}
+
+			if (qualifier.length() > 0) {
+				typeName = qualifier + "." + typeName; //$NON-NLS-1$
+			}
+			return typeName.trim();
+		}
+
+		return "error"; // TODO: Complain
+	}
+
+	// adapted from JavaStackTraceHyperlink
+	private int getLineNumber() throws CoreException {
+		int index = traceLine.lastIndexOf(':');
+		if (index >= 0) {
+			String numText = traceLine.substring(index + 1);
+			index = numText.indexOf(')');
+			if (index >= 0) {
+				numText = numText.substring(0, index);
+			}
+			try {
+				return Integer.parseInt(numText);
+			} catch (NumberFormatException e) {
+				throw new CoreException(null);
+			}
+		}
+
+		throw new CoreException(null);
+	}
+
+}
diff --git a/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/ui/JavaStackTraceHyperlinkAdapter.java b/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/ui/JavaStackTraceHyperlinkAdapter.java
new file mode 100644
index 0000000..bef82e1
--- /dev/null
+++ b/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/ui/JavaStackTraceHyperlinkAdapter.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2006 University Of British Columbia 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:
+ *     University Of British Columbia - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylar.internal.java.ui;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jdt.internal.debug.ui.actions.OpenTypeAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * @author Robert Elves
+ */
+public final class JavaStackTraceHyperlinkAdapter extends HyperlinkAdapter {
+	public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
+		String typeName;
+		int lineNumber;
+		try {
+			String linkText = (String) e.getHref();
+			typeName = getTypeName(linkText);
+			lineNumber = getLineNumber(linkText);
+	
+			// documents start at 0
+			if (lineNumber > 0) {
+				lineNumber--;
+			}
+			Object sourceElement = getSourceElement(typeName);
+			if (sourceElement != null) {
+				IDebugModelPresentation presentation = JDIDebugUIPlugin.getDefault()
+						.getModelPresentation();
+				IEditorInput editorInput = presentation.getEditorInput(sourceElement);
+				if (editorInput != null) {
+					String editorId = presentation.getEditorId(editorInput, sourceElement);
+					if (editorId != null) {
+						IEditorPart editorPart = JDIDebugUIPlugin.getActivePage().openEditor(
+								editorInput, editorId);
+						if (editorPart instanceof ITextEditor && lineNumber >= 0) {
+							ITextEditor textEditor = (ITextEditor) editorPart;
+							IDocumentProvider provider = textEditor.getDocumentProvider();
+							provider.connect(editorInput);
+							IDocument document = provider.getDocument(editorInput);
+							try {
+								IRegion line = document.getLineInformation(lineNumber);
+								textEditor.selectAndReveal(line.getOffset(), line.getLength());
+							} catch (BadLocationException e1) {
+								MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open Type", "Failed to open type.");
+							}
+							provider.disconnect(editorInput);
+						}
+						return;
+					}
+				}
+			}
+			// did not find source
+			MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open Type",
+					"Type could not be located.");
+		} catch (CoreException e1) {
+			MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Open Type",
+					"Failed to open type.");
+			return;
+		}
+	}
+	
+	// adapted from JavaStackTraceHyperlink
+	private Object getSourceElement(String typeName) throws CoreException {
+		Object result = null;
+		result = OpenTypeAction.findTypeInWorkspace(typeName);
+		// }
+		return result;
+	}
+
+	// adapted from JavaStackTraceHyperlink
+	private String getTypeName(String linkText) {
+		int start = linkText.indexOf('(');
+		int end = linkText.indexOf(':');
+		if (start >= 0 && end > start) {
+
+			// get File name (w/o .java)
+			String typeName = linkText.substring(start + 1, end);
+			typeName.indexOf(".");
+			typeName = typeName.substring(0, typeName.indexOf("."));
+
+			String qualifier = linkText.substring(0, start);
+			// remove the method name
+			start = qualifier.lastIndexOf('.');
+
+			if (start >= 0) {
+				// remove the class name
+				start = new String((String) qualifier.subSequence(0, start)).lastIndexOf('.');
+				if (start == -1) {
+					start = 0; // default package
+				}
+			}
+
+			if (start >= 0) {
+				qualifier = qualifier.substring(0, start);
+			}
+
+			if (qualifier.length() > 0) {
+				typeName = qualifier + "." + typeName; //$NON-NLS-1$
+			}
+			return typeName;
+		}
+
+		return "error"; // TODO: Complain
+	}
+
+	// adapted from JavaStackTraceHyperlink
+	private int getLineNumber(String linkText) throws CoreException {
+		int index = linkText.lastIndexOf(':');
+		if (index >= 0) {
+			String numText = linkText.substring(index + 1);
+			index = numText.indexOf(')');
+			if (index >= 0) {
+				numText = numText.substring(0, index);
+			}
+			try {
+				return Integer.parseInt(numText);
+			} catch (NumberFormatException e) {
+				throw new CoreException(null);
+			}
+		}
+
+		throw new CoreException(null);
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/ui/JavaStackTraceHyperlinkDetector.java b/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/ui/JavaStackTraceHyperlinkDetector.java
new file mode 100644
index 0000000..630e402
--- /dev/null
+++ b/org.eclipse.mylyn.java.ui/src/org/eclipse/mylyn/internal/java/ui/JavaStackTraceHyperlinkDetector.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2004 - 2006 University Of British Columbia 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:
+ *     University Of British Columbia - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylar.internal.java.ui;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+
+/**
+ * @author Rob Elves
+ */
+public class JavaStackTraceHyperlinkDetector implements IHyperlinkDetector {
+
+	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
+
+		if (region == null || textViewer == null)
+			return null;
+
+		IDocument document = textViewer.getDocument();
+
+		int offset = region.getOffset();
+
+		// String urlString= null;
+		if (document == null)
+			return null;
+
+		IRegion lineInfo;
+		String line;
+		try {
+			lineInfo = document.getLineInformationOfOffset(offset);
+			line = document.get(lineInfo.getOffset(), lineInfo.getLength());
+		} catch (BadLocationException ex) {
+			return null;
+		}
+
+		// int offsetInLine = offset - lineInfo.getOffset();
+
+		Pattern p = Pattern.compile("[ {1}|\\n].*({1}.*.{1}java:\\d*){1}", Pattern.CASE_INSENSITIVE);
+		Matcher m = p.matcher(line);
+
+		if (m.find()) {
+			IRegion urlRegion = new Region(lineInfo.getOffset() + m.start() + 1, m.end() - m.start());
+			return new IHyperlink[] { new JavaStackTraceFileHyperlink(urlRegion, m.group()) };
+		}
+
+		// StringMatcher javaElementMatcher = new StringMatcher("*(*.java:*)",
+		// true, false);//[\r|\n|\b|^]
+		//		
+		// Position position = javaElementMatcher.find(line, 0, line.length());
+		// if (position != null) {
+		// //String linkText = line.substring(position.getStart() + 1,
+		// position.getEnd() - 1);
+		// IRegion urlRegion= new Region(lineInfo.getOffset() +
+		// position.getStart() + 1, position.getEnd() - position.getStart() -
+		// 2);
+		// return new IHyperlink[] {new JavaStackTraceFileHyperlink(urlRegion,
+		// line)};
+		// }
+		return null;
+	}
+
+}
diff --git a/org.eclipse.mylyn.resources.ui/src/org/eclipse/mylyn/internal/xml/ant/AntEditingMonitor.java b/org.eclipse.mylyn.resources.ui/src/org/eclipse/mylyn/internal/xml/ant/AntEditingMonitor.java
index 42dcc18..6283197 100644
--- a/org.eclipse.mylyn.resources.ui/src/org/eclipse/mylyn/internal/xml/ant/AntEditingMonitor.java
+++ b/org.eclipse.mylyn.resources.ui/src/org/eclipse/mylyn/internal/xml/ant/AntEditingMonitor.java
@@ -39,7 +39,7 @@
 	}
 
 	@Override
-	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection) {
+	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection, boolean contributeToContext) {
 		if (part instanceof AntEditor) {
 
 			TextSelection textSelection = null;
@@ -74,7 +74,7 @@
 						return;
 					}
 					XmlNodeHelper xnode = new XmlNodeHelper(fei.getFile().getFullPath().toString(), path);
-					super.handleElementSelection(part, xnode);
+					super.handleElementSelection(part, xnode, contributeToContext);
 				} catch (Exception e) {
 					MylarStatusHandler.log(e, "selection resolve failed");
 				}
diff --git a/org.eclipse.mylyn.resources.ui/src/org/eclipse/mylyn/internal/xml/pde/PdeEditingMonitor.java b/org.eclipse.mylyn.resources.ui/src/org/eclipse/mylyn/internal/xml/pde/PdeEditingMonitor.java
index 5613a51..05b4b5a 100644
--- a/org.eclipse.mylyn.resources.ui/src/org/eclipse/mylyn/internal/xml/pde/PdeEditingMonitor.java
+++ b/org.eclipse.mylyn.resources.ui/src/org/eclipse/mylyn/internal/xml/pde/PdeEditingMonitor.java
@@ -42,7 +42,7 @@
 	}
 
 	@Override
-	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection) {
+	protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection, boolean contributeToContext) {
 		if (part instanceof ManifestEditor) {
 			TextSelection textSelection = null;
 			IEditorInput in = null;
@@ -111,7 +111,7 @@
 						String name = node.getXMLAttributeValue("name");
 						if (name == null)
 							name = node.getXMLTagName();
-						super.handleElementSelection(part, xnode);
+						super.handleElementSelection(part, xnode, contributeToContext);
 					}
 				} catch (Exception e) {
 					MylarStatusHandler.log(e, "couldn't resolve selection");