[177387] use base hyperlinking extension points
diff --git a/bundles/org.eclipse.jst.jsp.ui/plugin.properties b/bundles/org.eclipse.jst.jsp.ui/plugin.properties
index 6f658e9..7192646 100644
--- a/bundles/org.eclipse.jst.jsp.ui/plugin.properties
+++ b/bundles/org.eclipse.jst.jsp.ui/plugin.properties
@@ -7,6 +7,7 @@
 # 
 # Contributors:
 #     IBM Corporation - initial API and implementation
+#     Matthias Fuessel, mat.fuessel@gmx.net - [177387] use base hyperlinking extension points
 ###############################################################################
 providerName=Eclipse.org
 pluginName=SSE JSP Source Editor
@@ -17,6 +18,7 @@
 JSP_Templates.name=Templates
 JSP_Styles.name=Styles
 JSP_Syntax_Coloring=Syntax Coloring
+JSP_Source_target_name=JSP Source
 
 # Snippets contributions for helping with JSP syntax
 jsp_scriptlet=<%..%> scriptlet
@@ -88,3 +90,6 @@
 preferenceKeywords.templates=editor jsp templates snippet macros
 preferenceKeywords.styles=editor jsp style customize syntax highlighting type text content foreground background bold color
 preferenceKeywords.fragments=editor jsp fragment language content type validate
+##
+JSPJava_hyperlink=Java Content In JSP
+Taglib_hyperlink=Taglib Directive
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.ui/plugin.xml b/bundles/org.eclipse.jst.jsp.ui/plugin.xml
index 4cf90ea..8350e7f 100644
--- a/bundles/org.eclipse.jst.jsp.ui/plugin.xml
+++ b/bundles/org.eclipse.jst.jsp.ui/plugin.xml
@@ -747,4 +747,26 @@
 			<contentType id="org.eclipse.jst.jsp.core.cssjspsource" />
 		</adapterFactoryDescription>
 	</extension>
+	<extension
+		point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectorTargets">
+		<target
+			id="org.eclipse.jst.jsp.core.jspsource"
+			name="%JSP_Source_target_name">
+		</target>
+	</extension>
+	<extension
+		point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">
+		<hyperlinkDetector
+			class="org.eclipse.jst.jsp.ui.internal.hyperlink.JSPJavaHyperlinkDetector"
+			id="org.eclipse.jst.jsp.ui.internal.hyperlink.JSPJavaHyperlinkDetector"
+			name="%JSPJava_hyperlink"
+			targetId="org.eclipse.jst.jsp.core.jspsource">
+		</hyperlinkDetector>
+		<hyperlinkDetector
+			class="org.eclipse.jst.jsp.ui.internal.hyperlink.TaglibHyperlinkDetector"
+			id="org.eclipse.jst.jsp.ui.internal.hyperlink.TaglibHyperlinkDetector"
+			name="%Taglib_hyperlink"
+			targetId="org.eclipse.jst.jsp.core.jspsource">
+		</hyperlinkDetector>
+   </extension>
 </plugin>
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/StructuredTextViewerConfigurationJSP.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/StructuredTextViewerConfigurationJSP.java
index dade5bc..59e0d28 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/StructuredTextViewerConfigurationJSP.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/StructuredTextViewerConfigurationJSP.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,11 +7,13 @@
  * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Matthias Fuessel, mat.fuessel@gmx.net - [177387] use base hyperlinking extension points     
  *******************************************************************************/
 package org.eclipse.jst.jsp.ui;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.jdt.ui.JavaUI;
@@ -26,11 +28,11 @@
 import org.eclipse.jface.text.contentassist.IContentAssistant;
 import org.eclipse.jface.text.formatter.IContentFormatter;
 import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
-import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
 import org.eclipse.jface.text.information.IInformationPresenter;
 import org.eclipse.jface.text.information.IInformationProvider;
 import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jst.jsp.core.internal.provisional.contenttype.ContentTypeIdForJSP;
 import org.eclipse.jst.jsp.core.internal.text.StructuredTextPartitionerForJSP;
 import org.eclipse.jst.jsp.core.text.IJSPPartitions;
 import org.eclipse.jst.jsp.ui.internal.autoedit.AutoEditStrategyForTabs;
@@ -40,9 +42,6 @@
 import org.eclipse.jst.jsp.ui.internal.contentassist.JSPJavaContentAssistProcessor;
 import org.eclipse.jst.jsp.ui.internal.contentassist.NoRegionContentAssistProcessorForJSP;
 import org.eclipse.jst.jsp.ui.internal.format.FormattingStrategyJSPJava;
-import org.eclipse.jst.jsp.ui.internal.hyperlink.JSPJavaHyperlinkDetector;
-import org.eclipse.jst.jsp.ui.internal.hyperlink.TaglibHyperlinkDetector;
-import org.eclipse.jst.jsp.ui.internal.hyperlink.XMLHyperlinkDetector;
 import org.eclipse.jst.jsp.ui.internal.style.LineStyleProviderForJSP;
 import org.eclipse.jst.jsp.ui.internal.style.java.LineStyleProviderForJava;
 import org.eclipse.jst.jsp.ui.internal.style.jspel.LineStyleProviderForJSPEL;
@@ -50,9 +49,9 @@
 import org.eclipse.jst.jsp.ui.internal.taginfo.JSPJavaJavadocHoverProcessor;
 import org.eclipse.jst.jsp.ui.internal.taginfo.JSPJavaJavadocInformationProvider;
 import org.eclipse.jst.jsp.ui.internal.taginfo.JSPTagInfoHoverProcessor;
-import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
 import org.eclipse.wst.css.core.text.ICSSPartitions;
 import org.eclipse.wst.html.core.internal.format.HTMLFormatProcessorImpl;
+import org.eclipse.wst.html.core.internal.provisional.contenttype.ContentTypeIdForHTML;
 import org.eclipse.wst.html.core.text.IHTMLPartitions;
 import org.eclipse.wst.html.ui.StructuredTextViewerConfigurationHTML;
 import org.eclipse.wst.sse.core.text.IStructuredPartitions;
@@ -62,6 +61,7 @@
 import org.eclipse.wst.sse.ui.internal.provisional.style.LineStyleProvider;
 import org.eclipse.wst.sse.ui.internal.taginfo.TextHoverManager;
 import org.eclipse.wst.sse.ui.internal.util.EditorUtility;
+import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;
 import org.eclipse.wst.xml.core.text.IXMLPartitions;
 import org.eclipse.wst.xml.ui.StructuredTextViewerConfigurationXML;
 import org.eclipse.wst.xml.ui.internal.contentoutline.JFaceNodeLabelProvider;
@@ -264,27 +264,6 @@
 		return fHTMLSourceViewerConfiguration;
 	}
 
-	public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
-		if (fPreferenceStore == null)
-			return null;
-		if (sourceViewer == null || !fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINKS_ENABLED))
-			return null;
-
-		List allDetectors = new ArrayList(0);
-		allDetectors.add(new JSPJavaHyperlinkDetector());
-		allDetectors.add(new TaglibHyperlinkDetector());
-		allDetectors.add(new XMLHyperlinkDetector());
-
-		IHyperlinkDetector[] superDetectors = super.getHyperlinkDetectors(sourceViewer);
-		for (int m = 0; m < superDetectors.length; m++) {
-			IHyperlinkDetector detector = superDetectors[m];
-			if (!allDetectors.contains(detector)) {
-				allDetectors.add(detector);
-			}
-		}
-		return (IHyperlinkDetector[]) allDetectors.toArray(new IHyperlinkDetector[0]);
-	}
-
 	public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
 		String[] indentations = null;
 
@@ -469,4 +448,15 @@
 		}
 		return fXMLSourceViewerConfiguration;
 	}
+
+	protected Map getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
+		Map targets = super.getHyperlinkDetectorTargets(sourceViewer);
+		targets.put(ContentTypeIdForJSP.ContentTypeID_JSP, null);
+
+		// also add html & xml since there could be html/xml content in jsp
+		// (just hope the hyperlink detectors will do additional checking)
+		targets.put(ContentTypeIdForHTML.ContentTypeID_HTML, null);
+		targets.put(ContentTypeIdForXML.ContentTypeID_XML, null);
+		return targets;
+	}
 }
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/JSPJavaHyperlinkDetector.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/JSPJavaHyperlinkDetector.java
index 2b041d0..883c9d8 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/JSPJavaHyperlinkDetector.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/JSPJavaHyperlinkDetector.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jst.jsp.ui.internal.hyperlink;
 
 import java.util.ArrayList;
@@ -18,8 +28,8 @@
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
 import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
 import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
 import org.eclipse.jst.jsp.core.internal.java.IJSPTranslation;
 import org.eclipse.jst.jsp.core.internal.java.JSPTranslation;
 import org.eclipse.jst.jsp.core.internal.java.JSPTranslationAdapter;
@@ -33,7 +43,7 @@
 /**
  * Detects hyperlinks in JSP Java content
  */
-public class JSPJavaHyperlinkDetector implements IHyperlinkDetector {
+public class JSPJavaHyperlinkDetector extends AbstractHyperlinkDetector {
 
 	private IHyperlink createHyperlink(IJavaElement element, IRegion region, IDocument document) {
 		IHyperlink link = null;
@@ -49,7 +59,7 @@
 					sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document);
 					if (sModel != null) {
 						URIResolver resolver = sModel.getResolver();
-						if(resolver != null) {
+						if (resolver != null) {
 							String uriString = resolver.getFileBaseLocation();
 							file = getFile(uriString);
 						}
@@ -168,6 +178,7 @@
 
 		return file;
 	}
+
 	/**
 	 * Get JSP translation object
 	 * 
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/TaglibHyperlinkDetector.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/TaglibHyperlinkDetector.java
index ae634a7..4e76e6d 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/TaglibHyperlinkDetector.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/TaglibHyperlinkDetector.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jst.jsp.ui.internal.hyperlink;
 
 import java.io.File;
@@ -12,8 +22,8 @@
 import org.eclipse.jface.text.ITypedRegion;
 import org.eclipse.jface.text.Region;
 import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
 import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
 import org.eclipse.jface.text.hyperlink.URLHyperlink;
 import org.eclipse.jst.jsp.core.internal.provisional.JSP11Namespace;
 import org.eclipse.jst.jsp.core.taglib.ITLDRecord;
@@ -36,7 +46,7 @@
 /**
  * Detects hyperlinks for taglibs.
  */
-public class TaglibHyperlinkDetector implements IHyperlinkDetector {
+public class TaglibHyperlinkDetector extends AbstractHyperlinkDetector {
 	private final String HTTP_PROTOCOL = "http://";//$NON-NLS-1$
 
 	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/XMLHyperlinkDetector.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/XMLHyperlinkDetector.java
deleted file mode 100644
index 3bee897..0000000
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/hyperlink/XMLHyperlinkDetector.java
+++ /dev/null
@@ -1,503 +0,0 @@
-package org.eclipse.jst.jsp.ui.internal.hyperlink;
-
-import java.io.File;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import com.ibm.icu.util.StringTokenizer;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-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;
-import org.eclipse.jface.text.hyperlink.URLHyperlink;
-import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
-import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
-import org.eclipse.wst.sse.core.utils.StringUtils;
-import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
-import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
-import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
-import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
-import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceHelper;
-import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
-import org.w3c.dom.Attr;
-import org.w3c.dom.DocumentType;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-/**
- * Detects hyperlinks in XML tags. Includes detection in DOCTYPE and attribute
- * values. Resolves references to schemas, dtds, etc using the Common URI
- * Resolver.
- * 
- */
-public class XMLHyperlinkDetector implements IHyperlinkDetector {
-	// copies of this class exist in:
-	// org.eclipse.wst.xml.ui.internal.hyperlink
-	// org.eclipse.wst.html.ui.internal.hyperlink
-	// org.eclipse.jst.jsp.ui.internal.hyperlink
-
-	private final String HTTP_PROTOCOL = "http://";//$NON-NLS-1$
-	private final String NO_NAMESPACE_SCHEMA_LOCATION = "noNamespaceSchemaLocation"; //$NON-NLS-1$
-	private final String SCHEMA_LOCATION = "schemaLocation"; //$NON-NLS-1$
-	private final String XMLNS = "xmlns"; //$NON-NLS-1$
-	private final String XSI_NAMESPACE_URI = "http://www.w3.org/2001/XMLSchema-instance"; //$NON-NLS-1$
-
-	/**
-	 * Create the appropriate hyperlink
-	 * 
-	 * @param uriString
-	 * @param hyperlinkRegion
-	 * @return IHyperlink
-	 */
-	private IHyperlink createHyperlink(String uriString, IRegion hyperlinkRegion, IDocument document, Node node) {
-		IHyperlink link = null;
-
-		if (isHttp(uriString)) {
-			link = new URLHyperlink(hyperlinkRegion, uriString);
-		}
-		else {
-			// try to locate the file in the workspace
-			File systemFile = getFileFromUriString(uriString);
-			if (systemFile != null) {
-				String systemPath = systemFile.getPath();
-				IFile file = getFile(systemPath);
-				if (file != null) {
-					// this is a WorkspaceFileHyperlink since file exists in
-					// workspace
-					link = new WorkspaceFileHyperlink(hyperlinkRegion, file);
-				}
-				else {
-					// this is an ExternalFileHyperlink since file does not
-					// exist in workspace
-					link = new ExternalFileHyperlink(hyperlinkRegion, systemFile);
-				}
-			}
-		}
-		return link;
-	}
-
-	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
-		// for now, only capable of creating 1 hyperlink
-		List hyperlinks = new ArrayList(0);
-
-		if (region != null && textViewer != null) {
-			IDocument document = textViewer.getDocument();
-			Node currentNode = getCurrentNode(document, region.getOffset());
-			if (currentNode != null) {
-				String uriString = null;
-				if (currentNode.getNodeType() == Node.DOCUMENT_TYPE_NODE) {
-					// doctype nodes
-					uriString = getURIString(currentNode, document);
-				}
-				else if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
-					// element nodes
-					Attr currentAttr = getCurrentAttrNode(currentNode, region.getOffset());
-					if (currentAttr != null) {
-						// try to find link for current attribute
-						// resolve attribute value
-						uriString = getURIString(currentAttr, document);
-						// verify validity of uri string
-						if (uriString == null || !isValidURI(uriString))
-							// reset current attribute
-							currentAttr = null;
-					}
-					if (currentAttr == null) {
-						// try to find a linkable attribute within element
-						currentAttr = getLinkableAttr((Element) currentNode);
-						if (currentAttr != null) {
-							uriString = getURIString(currentAttr, document);
-						}
-					}
-					currentNode = currentAttr;
-				}
-				// try to create hyperlink from information gathered
-				if (uriString != null && currentNode != null && isValidURI(uriString)) {
-					IRegion hyperlinkRegion = getHyperlinkRegion(currentNode);
-					IHyperlink hyperlink = createHyperlink(uriString, hyperlinkRegion, document, currentNode);
-					if (hyperlink != null) {
-						hyperlinks.add(hyperlink);
-					}
-				}
-			}
-		}
-		if (hyperlinks.size() == 0)
-			return null;
-		return (IHyperlink[]) hyperlinks.toArray(new IHyperlink[0]);
-	}
-
-	/**
-	 * Get the base location from the current model (local file system)
-	 */
-	private String getBaseLocation(IDocument document) {
-		String baseLoc = null;
-
-		// get the base location from the current model
-		IStructuredModel sModel = null;
-		try {
-			sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document);
-			if (sModel != null) {
-				IPath location = new Path(sModel.getBaseLocation());
-				if (location.toFile().exists()) {
-					baseLoc = location.toString();
-				}
-				else {
-					if (location.segmentCount() > 1)
-						baseLoc = ResourcesPlugin.getWorkspace().getRoot().getFile(location).getLocation().toString();
-					else
-						baseLoc = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(location).toString();
-				}
-			}
-		}
-		finally {
-			if (sModel != null) {
-				sModel.releaseFromRead();
-			}
-		}
-		return baseLoc;
-	}
-
-	/**
-	 * Get the CMElementDeclaration for an element
-	 * 
-	 * @param element
-	 * @return CMElementDeclaration
-	 */
-	private CMElementDeclaration getCMElementDeclaration(Element element) {
-		CMElementDeclaration ed = null;
-
-		ModelQuery mq = ModelQueryUtil.getModelQuery(element.getOwnerDocument());
-		if (mq != null) {
-			ed = mq.getCMElementDeclaration(element);
-		}
-		return ed;
-	}
-
-	/**
-	 * Returns the attribute node within node at offset
-	 * 
-	 * @param node
-	 * @param offset
-	 * @return Attr
-	 */
-	private Attr getCurrentAttrNode(Node node, int offset) {
-		if ((node instanceof IndexedRegion) && ((IndexedRegion) node).contains(offset) && (node.hasAttributes())) {
-			NamedNodeMap attrs = node.getAttributes();
-			// go through each attribute in node and if attribute contains
-			// offset, return that attribute
-			for (int i = 0; i < attrs.getLength(); ++i) {
-				// assumption that if parent node is of type IndexedRegion,
-				// then its attributes will also be of type IndexedRegion
-				IndexedRegion attRegion = (IndexedRegion) attrs.item(i);
-				if (attRegion.contains(offset)) {
-					return (Attr) attrs.item(i);
-				}
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the node the cursor is currently on in the document. null if no
-	 * node is selected
-	 * 
-	 * @param offset
-	 * @return Node either element, doctype, text, or null
-	 */
-	private Node getCurrentNode(IDocument document, int offset) {
-		// get the current node at the offset (returns either: element,
-		// doctype, text)
-		IndexedRegion inode = null;
-		IStructuredModel sModel = null;
-		try {
-			sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document);
-			inode = sModel.getIndexedRegion(offset);
-			if (inode == null)
-				inode = sModel.getIndexedRegion(offset - 1);
-		}
-		finally {
-			if (sModel != null)
-				sModel.releaseFromRead();
-		}
-
-		if (inode instanceof Node) {
-			return (Node) inode;
-		}
-		return null;
-	}
-
-	/**
-	 * Returns an IFile from the given uri if possible, null if cannot find
-	 * file from uri.
-	 * 
-	 * @param fileString
-	 *            file system path
-	 * @return returns IFile if fileString exists in the workspace
-	 */
-	private IFile getFile(String fileString) {
-		IFile file = null;
-
-		if (fileString != null) {
-			IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(fileString));
-			for (int i = 0; i < files.length && file == null; i++)
-				if (files[i].exists())
-					file = files[i];
-		}
-
-		return file;
-	}
-
-	/**
-	 * Create a file from the given uri string
-	 * 
-	 * @param uriString -
-	 *            assumes uriString is not http://
-	 * @return File created from uriString if possible, null otherwise
-	 */
-	private File getFileFromUriString(String uriString) {
-		File file = null;
-		try {
-			// first just try to create a file directly from uriString as
-			// default in case create file from uri does not work
-			file = new File(uriString);
-
-			// try to create file from uri
-			URI uri = new URI(uriString);
-			file = new File(uri);
-		}
-		catch (Exception e) {
-			// if exception is thrown while trying to create File just ignore
-			// and file will be null
-		}
-		return file;
-	}
-
-	private IRegion getHyperlinkRegion(Node node) {
-		IRegion hyperRegion = null;
-
-		if (node != null) {
-			short nodeType = node.getNodeType();
-			if (nodeType == Node.DOCUMENT_TYPE_NODE) {
-				// handle doc type node
-				IDOMNode docNode = (IDOMNode) node;
-				hyperRegion = new Region(docNode.getStartOffset(), docNode.getEndOffset() - docNode.getStartOffset());
-			}
-			else if (nodeType == Node.ATTRIBUTE_NODE) {
-				// handle attribute nodes
-				IDOMAttr att = (IDOMAttr) node;
-				// do not include quotes in attribute value region
-				int regOffset = att.getValueRegionStartOffset();
-				ITextRegion valueRegion = att.getValueRegion();
-				if (valueRegion != null) {
-					int regLength = valueRegion.getTextLength();
-					String attValue = att.getValueRegionText();
-					if (StringUtils.isQuoted(attValue)) {
-						++regOffset;
-						regLength = regLength - 2;
-					}
-					hyperRegion = new Region(regOffset, regLength);
-				}
-			}
-		}
-		return hyperRegion;
-	}
-
-	/**
-	 * Attempts to find an attribute within element that is openable.
-	 * 
-	 * @param element -
-	 *            cannot be null
-	 * @return Attr attribute that can be used for open on, null if no
-	 *         attribute could be found
-	 */
-	private Attr getLinkableAttr(Element element) {
-		CMElementDeclaration ed = getCMElementDeclaration(element);
-		// get the list of attributes for this node
-		NamedNodeMap attrs = element.getAttributes();
-		for (int i = 0; i < attrs.getLength(); ++i) {
-			// check if this attribute is "openOn-able"
-			Attr att = (Attr) attrs.item(i);
-			if (isLinkableAttr(att, ed)) {
-				return att;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Find the location hint for the given namespaceURI if it exists
-	 * 
-	 * @param elementNode -
-	 *            cannot be null
-	 * @param namespaceURI -
-	 *            cannot be null
-	 * @return location hint (systemId) if it was found, null otherwise
-	 */
-	private String getLocationHint(Element elementNode, String namespaceURI) {
-		Attr schemaLocNode = elementNode.getAttributeNodeNS(XSI_NAMESPACE_URI, SCHEMA_LOCATION);
-		if (schemaLocNode != null) {
-			StringTokenizer st = new StringTokenizer(schemaLocNode.getValue());
-			while (st.hasMoreTokens()) {
-				String publicId = st.hasMoreTokens() ? st.nextToken() : null;
-				String systemId = st.hasMoreTokens() ? st.nextToken() : null;
-				// found location hint
-				if (namespaceURI.equalsIgnoreCase(publicId))
-					return systemId;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the URI string
-	 * 
-	 * @param node -
-	 *            assumes not null
-	 */
-	private String getURIString(Node node, IDocument document) {
-		String resolvedURI = null;
-		// need the base location, publicId, and systemId for URIResolver
-		String baseLoc = null;
-		String publicId = null;
-		String systemId = null;
-
-		short nodeType = node.getNodeType();
-		// handle doc type node
-		if (nodeType == Node.DOCUMENT_TYPE_NODE) {
-			baseLoc = getBaseLocation(document);
-			publicId = ((DocumentType) node).getPublicId();
-			systemId = ((DocumentType) node).getSystemId();
-		}
-		else if (nodeType == Node.ATTRIBUTE_NODE) {
-			// handle attribute node
-			Attr attrNode = (Attr) node;
-			String attrName = attrNode.getName();
-			String attrValue = attrNode.getValue();
-			attrValue = StringUtils.strip(attrValue);
-			if (attrValue != null && attrValue.length() > 0) {
-				baseLoc = getBaseLocation(document);
-
-				// handle schemaLocation attribute
-				String prefix = DOMNamespaceHelper.getPrefix(attrName);
-				String unprefixedName = DOMNamespaceHelper.getUnprefixedName(attrName);
-				if ((XMLNS.equals(prefix)) || (XMLNS.equals(unprefixedName))) {
-					publicId = attrValue;
-					systemId = getLocationHint(attrNode.getOwnerElement(), publicId);
-					if (systemId == null) {
-						systemId = attrValue;
-					}
-				}
-				else if ((XSI_NAMESPACE_URI.equals(DOMNamespaceHelper.getNamespaceURI(attrNode))) && (SCHEMA_LOCATION.equals(unprefixedName))) {
-					// for now just use the first pair
-					// need to look into being more precise
-					StringTokenizer st = new StringTokenizer(attrValue);
-					publicId = st.hasMoreTokens() ? st.nextToken() : null;
-					systemId = st.hasMoreTokens() ? st.nextToken() : null;
-					// else check if xmlns publicId = value
-				}
-				else {
-					systemId = attrValue;
-				}
-			}
-		}
-
-		resolvedURI = resolveURI(baseLoc, publicId, systemId);
-		return resolvedURI;
-	}
-
-	/**
-	 * Returns true if this uriString is an http string
-	 * 
-	 * @param uriString
-	 * @return true if uriString is http string, false otherwise
-	 */
-	private boolean isHttp(String uriString) {
-		boolean isHttp = false;
-		if (uriString != null) {
-			String tempString = uriString.toLowerCase();
-			if (tempString.startsWith(HTTP_PROTOCOL))
-				isHttp = true;
-		}
-		return isHttp;
-	}
-
-	/**
-	 * Checks to see if the given attribute is openable. Attribute is openable
-	 * if it is a namespace declaration attribute or if the attribute value is
-	 * of type URI.
-	 * 
-	 * @param attr
-	 *            cannot be null
-	 * @param cmElement
-	 *            CMElementDeclaration associated with the attribute (can be
-	 *            null)
-	 * @return true if this attribute is "openOn-able" false otherwise
-	 */
-	private boolean isLinkableAttr(Attr attr, CMElementDeclaration cmElement) {
-		String attrName = attr.getName();
-		String prefix = DOMNamespaceHelper.getPrefix(attrName);
-		String unprefixedName = DOMNamespaceHelper.getUnprefixedName(attrName);
-		// determine if attribute is namespace declaration
-		if ((XMLNS.equals(prefix)) || (XMLNS.equals(unprefixedName)))
-			return true;
-
-		// determine if attribute contains schema location
-		if ((XSI_NAMESPACE_URI.equals(DOMNamespaceHelper.getNamespaceURI(attr))) && ((SCHEMA_LOCATION.equals(unprefixedName)) || (NO_NAMESPACE_SCHEMA_LOCATION.equals(unprefixedName))))
-			return true;
-
-		// determine if attribute value is of type URI
-		if (cmElement != null) {
-			CMAttributeDeclaration attrDecl = (CMAttributeDeclaration) cmElement.getAttributes().getNamedItem(attrName);
-			if ((attrDecl != null) && (attrDecl.getAttrType() != null) && (CMDataType.URI.equals(attrDecl.getAttrType().getDataTypeName()))) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Checks whether the given uriString is really pointing to a file
-	 * 
-	 * @param uriString
-	 * @return boolean
-	 */
-	private boolean isValidURI(String uriString) {
-		boolean isValid = false;
-
-		if (isHttp(uriString))
-			isValid = true;
-		else {
-			File file = getFileFromUriString(uriString);
-			if (file != null)
-				isValid = file.isFile();
-		}
-		return isValid;
-	}
-
-	/**
-	 * Resolves the given URI information
-	 * 
-	 * @param baseLocation
-	 * @param publicId
-	 * @param systemId
-	 * @return String resolved uri.
-	 */
-	private String resolveURI(String baseLocation, String publicId, String systemId) {
-		// dont resolve if there's nothing to resolve
-		if ((baseLocation == null) && (publicId == null) && (systemId == null))
-			return null;
-		return URIResolverPlugin.createResolver().resolve(baseLocation, publicId, systemId);
-	}
-}
diff --git a/bundles/org.eclipse.wst.html.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.html.ui/META-INF/MANIFEST.MF
index a82c3be..82b20e3 100644
--- a/bundles/org.eclipse.wst.html.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.html.ui/META-INF/MANIFEST.MF
@@ -17,7 +17,6 @@
  org.eclipse.wst.html.ui.internal.derived;x-internal:=true,
  org.eclipse.wst.html.ui.internal.edit.ui;x-internal:=true,
  org.eclipse.wst.html.ui.internal.editor;x-internal:=true,
- org.eclipse.wst.html.ui.internal.hyperlink;x-internal:=true,
  org.eclipse.wst.html.ui.internal.preferences;x-internal:=true,
  org.eclipse.wst.html.ui.internal.preferences.ui;x-internal:=true,
  org.eclipse.wst.html.ui.internal.projection;x-internal:=true,
diff --git a/bundles/org.eclipse.wst.html.ui/plugin.properties b/bundles/org.eclipse.wst.html.ui/plugin.properties
index 0dd079f..694f43d 100644
--- a/bundles/org.eclipse.wst.html.ui/plugin.properties
+++ b/bundles/org.eclipse.wst.html.ui/plugin.properties
@@ -58,3 +58,5 @@
 preferenceKeywords.templates=editor html templates snippet macros
 preferenceKeywords.styles=editor html style customize syntax highlighting type text content foreground background bold color
 preferenceKeywords.webcontent=editor html web content settings profile style document type doctype public system css
+##
+HTML_Source_target_name=HTML Source
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.html.ui/plugin.xml b/bundles/org.eclipse.wst.html.ui/plugin.xml
index 43c70c5..1fb0b31 100644
--- a/bundles/org.eclipse.wst.html.ui/plugin.xml
+++ b/bundles/org.eclipse.wst.html.ui/plugin.xml
@@ -464,4 +464,11 @@
                id="org.eclipse.ui.texteditor.SelectRulerAction"/>
         </editorContribution>
 	</extension>
+	<extension
+		point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectorTargets">
+		<target
+			id="org.eclipse.wst.html.core.htmlsource"
+			name="%HTML_Source_target_name">
+		</target>
+	</extension>
 </plugin>
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/StructuredTextViewerConfigurationHTML.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/StructuredTextViewerConfigurationHTML.java
index 70eafe8..4c14ea5 100644
--- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/StructuredTextViewerConfigurationHTML.java
+++ b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/StructuredTextViewerConfigurationHTML.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -12,6 +12,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Vector;
 
 import org.eclipse.core.runtime.IPath;
@@ -22,24 +23,22 @@
 import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
 import org.eclipse.jface.text.formatter.IContentFormatter;
 import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
-import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
 import org.eclipse.jface.text.information.IInformationProvider;
 import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
 import org.eclipse.wst.css.core.text.ICSSPartitions;
 import org.eclipse.wst.css.ui.internal.contentassist.CSSContentAssistProcessor;
 import org.eclipse.wst.css.ui.internal.style.LineStyleProviderForEmbeddedCSS;
 import org.eclipse.wst.html.core.internal.HTMLCorePlugin;
 import org.eclipse.wst.html.core.internal.format.HTMLFormatProcessorImpl;
 import org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceNames;
+import org.eclipse.wst.html.core.internal.provisional.contenttype.ContentTypeIdForHTML;
 import org.eclipse.wst.html.core.internal.text.StructuredTextPartitionerForHTML;
 import org.eclipse.wst.html.core.text.IHTMLPartitions;
 import org.eclipse.wst.html.ui.internal.autoedit.AutoEditStrategyForTabs;
 import org.eclipse.wst.html.ui.internal.autoedit.StructuredAutoEditStrategyHTML;
 import org.eclipse.wst.html.ui.internal.contentassist.HTMLContentAssistProcessor;
 import org.eclipse.wst.html.ui.internal.contentassist.NoRegionContentAssistProcessorForHTML;
-import org.eclipse.wst.html.ui.internal.hyperlink.XMLHyperlinkDetector;
 import org.eclipse.wst.html.ui.internal.style.LineStyleProviderForHTML;
 import org.eclipse.wst.html.ui.internal.taginfo.HTMLInformationProvider;
 import org.eclipse.wst.html.ui.internal.taginfo.HTMLTagInfoHoverProcessor;
@@ -54,6 +53,7 @@
 import org.eclipse.wst.sse.ui.internal.provisional.style.LineStyleProvider;
 import org.eclipse.wst.sse.ui.internal.taginfo.TextHoverManager;
 import org.eclipse.wst.sse.ui.internal.util.EditorUtility;
+import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;
 import org.eclipse.wst.xml.core.internal.text.rules.StructuredTextPartitionerForXML;
 import org.eclipse.wst.xml.core.text.IXMLPartitions;
 import org.eclipse.wst.xml.ui.StructuredTextViewerConfigurationXML;
@@ -175,23 +175,6 @@
 			return super.getDoubleClickStrategy(sourceViewer, contentType);
 	}
 
-	public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
-		if (sourceViewer == null || !fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINKS_ENABLED))
-			return null;
-
-		List allDetectors = new ArrayList(0);
-		allDetectors.add(new XMLHyperlinkDetector());
-
-		IHyperlinkDetector[] superDetectors = super.getHyperlinkDetectors(sourceViewer);
-		for (int m = 0; m < superDetectors.length; m++) {
-			IHyperlinkDetector detector = superDetectors[m];
-			if (!allDetectors.contains(detector)) {
-				allDetectors.add(detector);
-			}
-		}
-		return (IHyperlinkDetector[]) allDetectors.toArray(new IHyperlinkDetector[0]);
-	}
-
 	public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
 		Vector vector = new Vector();
 
@@ -356,4 +339,14 @@
 		}
 		return fXMLSourceViewerConfiguration;
 	}
+
+	protected Map getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
+		Map targets = super.getHyperlinkDetectorTargets(sourceViewer);
+		targets.put(ContentTypeIdForHTML.ContentTypeID_HTML, null);
+
+		// also add xml since there could be xml content in html
+		// (just hope the hyperlink detectors will do additional checking)
+		targets.put(ContentTypeIdForXML.ContentTypeID_XML, null);
+		return targets;
+	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/ExternalFileEditorInput.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/ExternalFileEditorInput.java
deleted file mode 100644
index 4bc2468..0000000
--- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/ExternalFileEditorInput.java
+++ /dev/null
@@ -1,159 +0,0 @@
-package org.eclipse.wst.html.ui.internal.hyperlink;
-
-import java.io.File;
-
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.ui.IPathEditorInput;
-import org.eclipse.ui.IPersistableElement;
-import org.eclipse.ui.editors.text.ILocationProvider;
-import org.eclipse.ui.model.IWorkbenchAdapter;
-
-/**
- * EditorInput for external files. Copied from
- * org.eclipse.ui.internal.editors.text.JavaFileEditorInput
- */
-class ExternalFileEditorInput implements IPathEditorInput, ILocationProvider {
-	// copies of this class exist in:
-	// org.eclipse.wst.xml.ui.internal.hyperlink
-	// org.eclipse.wst.html.ui.internal.hyperlink
-	// org.eclipse.jst.jsp.ui.internal.hyperlink
-	
-	/**
-	 * The workbench adapter which simply provides the label.
-	 * 
-	 * @see  Eclipse 3.1
-	 */
-	private class WorkbenchAdapter implements IWorkbenchAdapter {
-		/*
-		 * @see org.eclipse.ui.model.IWorkbenchAdapter#getChildren(java.lang.Object)
-		 */
-		public Object[] getChildren(Object o) {
-			return null;
-		}
-
-		/*
-		 * @see org.eclipse.ui.model.IWorkbenchAdapter#getImageDescriptor(java.lang.Object)
-		 */
-		public ImageDescriptor getImageDescriptor(Object object) {
-			return null;
-		}
-
-		/*
-		 * @see org.eclipse.ui.model.IWorkbenchAdapter#getLabel(java.lang.Object)
-		 */
-		public String getLabel(Object o) {
-			return ((ExternalFileEditorInput) o).getName();
-		}
-
-		/*
-		 * @see org.eclipse.ui.model.IWorkbenchAdapter#getParent(java.lang.Object)
-		 */
-		public Object getParent(Object o) {
-			return null;
-		}
-	}
-
-	private File fFile;
-	private WorkbenchAdapter fWorkbenchAdapter = new WorkbenchAdapter();
-
-	public ExternalFileEditorInput(File file) {
-		super();
-		fFile = file;
-		fWorkbenchAdapter = new WorkbenchAdapter();
-	}
-
-	/*
-	 * @see org.eclipse.ui.IEditorInput#exists()
-	 */
-	public boolean exists() {
-		return fFile.exists();
-	}
-
-	/*
-	 * @see org.eclipse.ui.IEditorInput#getImageDescriptor()
-	 */
-	public ImageDescriptor getImageDescriptor() {
-		return null;
-	}
-
-	/*
-	 * @see org.eclipse.ui.IEditorInput#getName()
-	 */
-	public String getName() {
-		return fFile.getName();
-	}
-
-	/*
-	 * @see org.eclipse.ui.IEditorInput#getPersistable()
-	 */
-	public IPersistableElement getPersistable() {
-		return null;
-	}
-
-	/*
-	 * @see org.eclipse.ui.IEditorInput#getToolTipText()
-	 */
-	public String getToolTipText() {
-		return fFile.getAbsolutePath();
-	}
-
-	/*
-	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
-	 */
-	public Object getAdapter(Class adapter) {
-		if (ILocationProvider.class.equals(adapter))
-			return this;
-		if (IWorkbenchAdapter.class.equals(adapter))
-			return fWorkbenchAdapter;
-		return Platform.getAdapterManager().getAdapter(this, adapter);
-	}
-
-	/*
-	 * @see org.eclipse.ui.editors.text.ILocationProvider#getPath(java.lang.Object)
-	 */
-	public IPath getPath(Object element) {
-		if (element instanceof ExternalFileEditorInput) {
-			ExternalFileEditorInput input = (ExternalFileEditorInput) element;
-			return Path.fromOSString(input.fFile.getAbsolutePath());
-		}
-		return null;
-	}
-	
-    /*
-     * @see org.eclipse.ui.IPathEditorInput#getPath()
-     * @since 3.1
-     */
-    public IPath getPath() {
-        return Path.fromOSString(fFile.getAbsolutePath());
-    }
-
-	/*
-	 * @see java.lang.Object#equals(java.lang.Object)
-	 */
-	public boolean equals(Object o) {
-		if (o == this)
-			return true;
-
-		if (o instanceof ExternalFileEditorInput) {
-			ExternalFileEditorInput input = (ExternalFileEditorInput) o;
-			return fFile.equals(input.fFile);
-		}
-		
-        if (o instanceof IPathEditorInput) {
-            IPathEditorInput input= (IPathEditorInput)o;
-            return getPath().equals(input.getPath());
-        }
-
-		return false;
-	}
-
-	/*
-	 * @see java.lang.Object#hashCode()
-	 */
-	public int hashCode() {
-		return fFile.hashCode();
-	}
-}
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/ExternalFileHyperlink.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/ExternalFileHyperlink.java
deleted file mode 100644
index 07b14ed..0000000
--- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/ExternalFileHyperlink.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.eclipse.wst.html.ui.internal.hyperlink;
-
-import java.io.File;
-
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.ui.IEditorDescriptor;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.ide.IDE;
-import org.eclipse.wst.html.ui.internal.Logger;
-
-/**
- * Hyperlink for external files.
- */
-class ExternalFileHyperlink implements IHyperlink {
-	// copies of this class exist in:
-	// org.eclipse.wst.xml.ui.internal.hyperlink
-	// org.eclipse.wst.html.ui.internal.hyperlink
-	// org.eclipse.jst.jsp.ui.internal.hyperlink
-	
-	private IRegion fHyperlinkRegion;
-	private File fHyperlinkFile;
-
-	public ExternalFileHyperlink(IRegion region, File file) {
-		fHyperlinkFile = file;
-		fHyperlinkRegion = region;
-	}
-	
-	public IRegion getHyperlinkRegion() {
-		return fHyperlinkRegion;
-	}
-
-	public String getTypeLabel() {
-		return null;
-	}
-
-	public String getHyperlinkText() {
-		return null;
-	}
-
-	public void open() {
-		if (fHyperlinkFile != null) {
-			IEditorInput input = new ExternalFileEditorInput(fHyperlinkFile);
-			IEditorDescriptor descriptor;
-			try {
-				descriptor = IDE.getEditorDescriptor(input.getName(), true);
-				if (descriptor != null) {
-					IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-					IDE.openEditor(page, input, descriptor.getId(), true);
-				}
-			}
-			catch (PartInitException e) {
-				Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
-			}
-		}
-	}
-}
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/WorkspaceFileHyperlink.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/WorkspaceFileHyperlink.java
deleted file mode 100644
index 8ee3ac1..0000000
--- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/WorkspaceFileHyperlink.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.eclipse.wst.html.ui.internal.hyperlink;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.ide.IDE;
-import org.eclipse.ui.texteditor.ITextEditor;
-import org.eclipse.wst.html.ui.internal.Logger;
-
-/**
- * Hyperlink for files within the workspace. (As long as there is an IFile,
- * this can be used) Opens the default editor for the file.
- */
-class WorkspaceFileHyperlink implements IHyperlink {
-	// copies of this class exist in:
-	// org.eclipse.wst.xml.ui.internal.hyperlink
-	// org.eclipse.wst.html.ui.internal.hyperlink
-	// org.eclipse.jst.jsp.ui.internal.hyperlink
-
-	private IRegion fRegion;
-	private IFile fFile;
-	private IRegion fHighlightRange;
-
-	public WorkspaceFileHyperlink(IRegion region, IFile file) {
-		fRegion = region;
-		fFile = file;
-	}
-
-	public WorkspaceFileHyperlink(IRegion region, IFile file, IRegion range) {
-		fRegion = region;
-		fFile = file;
-		fHighlightRange = range;
-	}
-
-	public IRegion getHyperlinkRegion() {
-		return fRegion;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jface.text.hyperlink.IHyperlink#getTypeLabel()
-	 */
-	public String getTypeLabel() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jface.text.hyperlink.IHyperlink#getHyperlinkText()
-	 */
-	public String getHyperlinkText() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public void open() {
-		if (fFile != null && fFile.exists()) {
-			try {
-				IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-				IEditorPart editor = IDE.openEditor(page, fFile, true);
-				// highlight range in editor if possible
-				if (fHighlightRange != null && editor instanceof ITextEditor) {
-					((ITextEditor) editor).setHighlightRange(fHighlightRange.getOffset(), fHighlightRange.getLength(), true);
-				}
-			}
-			catch (PartInitException pie) {
-				Logger.log(Logger.WARNING_DEBUG, pie.getMessage(), pie);
-			}
-		}
-	}
-
-}
diff --git a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/XMLHyperlinkDetector.java b/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/XMLHyperlinkDetector.java
deleted file mode 100644
index c4be166..0000000
--- a/bundles/org.eclipse.wst.html.ui/src/org/eclipse/wst/html/ui/internal/hyperlink/XMLHyperlinkDetector.java
+++ /dev/null
@@ -1,503 +0,0 @@
-package org.eclipse.wst.html.ui.internal.hyperlink;
-
-import java.io.File;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import com.ibm.icu.util.StringTokenizer;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-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;
-import org.eclipse.jface.text.hyperlink.URLHyperlink;
-import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
-import org.eclipse.wst.sse.core.StructuredModelManager;
-import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
-import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
-import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
-import org.eclipse.wst.sse.core.utils.StringUtils;
-import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
-import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
-import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
-import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
-import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceHelper;
-import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
-import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
-import org.w3c.dom.Attr;
-import org.w3c.dom.DocumentType;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-/**
- * Detects hyperlinks in XML tags. Includes detection in DOCTYPE and attribute
- * values. Resolves references to schemas, dtds, etc using the Common URI
- * Resolver.
- * 
- */
-public class XMLHyperlinkDetector implements IHyperlinkDetector {
-	// copies of this class exist in:
-	// org.eclipse.wst.xml.ui.internal.hyperlink
-	// org.eclipse.wst.html.ui.internal.hyperlink
-	// org.eclipse.jst.jsp.ui.internal.hyperlink
-
-	private final String HTTP_PROTOCOL = "http://";//$NON-NLS-1$
-	private final String NO_NAMESPACE_SCHEMA_LOCATION = "noNamespaceSchemaLocation"; //$NON-NLS-1$
-	private final String SCHEMA_LOCATION = "schemaLocation"; //$NON-NLS-1$
-	private final String XMLNS = "xmlns"; //$NON-NLS-1$
-	private final String XSI_NAMESPACE_URI = "http://www.w3.org/2001/XMLSchema-instance"; //$NON-NLS-1$
-
-	/**
-	 * Create the appropriate hyperlink
-	 * 
-	 * @param uriString
-	 * @param hyperlinkRegion
-	 * @return IHyperlink
-	 */
-	private IHyperlink createHyperlink(String uriString, IRegion hyperlinkRegion, IDocument document, Node node) {
-		IHyperlink link = null;
-
-		if (isHttp(uriString)) {
-			link = new URLHyperlink(hyperlinkRegion, uriString);
-		}
-		else {
-			// try to locate the file in the workspace
-			File systemFile = getFileFromUriString(uriString);
-			if (systemFile != null) {
-				String systemPath = systemFile.getPath();
-				IFile file = getFile(systemPath);
-				if (file != null) {
-					// this is a WorkspaceFileHyperlink since file exists in
-					// workspace
-					link = new WorkspaceFileHyperlink(hyperlinkRegion, file);
-				}
-				else {
-					// this is an ExternalFileHyperlink since file does not
-					// exist in workspace
-					link = new ExternalFileHyperlink(hyperlinkRegion, systemFile);
-				}
-			}
-		}
-		return link;
-	}
-
-	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
-		// for now, only capable of creating 1 hyperlink
-		List hyperlinks = new ArrayList(0);
-
-		if (region != null && textViewer != null) {
-			IDocument document = textViewer.getDocument();
-			Node currentNode = getCurrentNode(document, region.getOffset());
-			if (currentNode != null) {
-				String uriString = null;
-				if (currentNode.getNodeType() == Node.DOCUMENT_TYPE_NODE) {
-					// doctype nodes
-					uriString = getURIString(currentNode, document);
-				}
-				else if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
-					// element nodes
-					Attr currentAttr = getCurrentAttrNode(currentNode, region.getOffset());
-					if (currentAttr != null) {
-						// try to find link for current attribute
-						// resolve attribute value
-						uriString = getURIString(currentAttr, document);
-						// verify validity of uri string
-						if (uriString == null || !isValidURI(uriString))
-							// reset current attribute
-							currentAttr = null;
-					}
-					if (currentAttr == null) {
-						// try to find a linkable attribute within element
-						currentAttr = getLinkableAttr((Element) currentNode);
-						if (currentAttr != null) {
-							uriString = getURIString(currentAttr, document);
-						}
-					}
-					currentNode = currentAttr;
-				}
-				// try to create hyperlink from information gathered
-				if (uriString != null && currentNode != null && isValidURI(uriString)) {
-					IRegion hyperlinkRegion = getHyperlinkRegion(currentNode);
-					IHyperlink hyperlink = createHyperlink(uriString, hyperlinkRegion, document, currentNode);
-					if (hyperlink != null) {
-						hyperlinks.add(hyperlink);
-					}
-				}
-			}
-		}
-		if (hyperlinks.size() == 0)
-			return null;
-		return (IHyperlink[]) hyperlinks.toArray(new IHyperlink[0]);
-	}
-
-	/**
-	 * Get the base location from the current model (local file system)
-	 */
-	private String getBaseLocation(IDocument document) {
-		String baseLoc = null;
-
-		// get the base location from the current model
-		IStructuredModel sModel = null;
-		try {
-			sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document);
-			if (sModel != null) {
-				IPath location = new Path(sModel.getBaseLocation());
-				if (location.toFile().exists()) {
-					baseLoc = location.toString();
-				}
-				else {
-					if (location.segmentCount() > 1)
-						baseLoc = ResourcesPlugin.getWorkspace().getRoot().getFile(location).getLocation().toString();
-					else
-						baseLoc = ResourcesPlugin.getWorkspace().getRoot().getLocation().append(location).toString();
-				}
-			}
-		}
-		finally {
-			if (sModel != null) {
-				sModel.releaseFromRead();
-			}
-		}
-		return baseLoc;
-	}
-
-	/**
-	 * Get the CMElementDeclaration for an element
-	 * 
-	 * @param element
-	 * @return CMElementDeclaration
-	 */
-	private CMElementDeclaration getCMElementDeclaration(Element element) {
-		CMElementDeclaration ed = null;
-
-		ModelQuery mq = ModelQueryUtil.getModelQuery(element.getOwnerDocument());
-		if (mq != null) {
-			ed = mq.getCMElementDeclaration(element);
-		}
-		return ed;
-	}
-
-	/**
-	 * Returns the attribute node within node at offset
-	 * 
-	 * @param node
-	 * @param offset
-	 * @return Attr
-	 */
-	private Attr getCurrentAttrNode(Node node, int offset) {
-		if ((node instanceof IndexedRegion) && ((IndexedRegion) node).contains(offset) && (node.hasAttributes())) {
-			NamedNodeMap attrs = node.getAttributes();
-			// go through each attribute in node and if attribute contains
-			// offset, return that attribute
-			for (int i = 0; i < attrs.getLength(); ++i) {
-				// assumption that if parent node is of type IndexedRegion,
-				// then its attributes will also be of type IndexedRegion
-				IndexedRegion attRegion = (IndexedRegion) attrs.item(i);
-				if (attRegion.contains(offset)) {
-					return (Attr) attrs.item(i);
-				}
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the node the cursor is currently on in the document. null if no
-	 * node is selected
-	 * 
-	 * @param offset
-	 * @return Node either element, doctype, text, or null
-	 */
-	private Node getCurrentNode(IDocument document, int offset) {
-		// get the current node at the offset (returns either: element,
-		// doctype, text)
-		IndexedRegion inode = null;
-		IStructuredModel sModel = null;
-		try {
-			sModel = StructuredModelManager.getModelManager().getExistingModelForRead(document);
-			inode = sModel.getIndexedRegion(offset);
-			if (inode == null)
-				inode = sModel.getIndexedRegion(offset - 1);
-		}
-		finally {
-			if (sModel != null)
-				sModel.releaseFromRead();
-		}
-
-		if (inode instanceof Node) {
-			return (Node) inode;
-		}
-		return null;
-	}
-
-	/**
-	 * Returns an IFile from the given uri if possible, null if cannot find
-	 * file from uri.
-	 * 
-	 * @param fileString
-	 *            file system path
-	 * @return returns IFile if fileString exists in the workspace
-	 */
-	private IFile getFile(String fileString) {
-		IFile file = null;
-
-		if (fileString != null) {
-			IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(fileString));
-			for (int i = 0; i < files.length && file == null; i++)
-				if (files[i].exists())
-					file = files[i];
-		}
-
-		return file;
-	}
-
-	/**
-	 * Create a file from the given uri string
-	 * 
-	 * @param uriString -
-	 *            assumes uriString is not http://
-	 * @return File created from uriString if possible, null otherwise
-	 */
-	private File getFileFromUriString(String uriString) {
-		File file = null;
-		try {
-			// first just try to create a file directly from uriString as
-			// default in case create file from uri does not work
-			file = new File(uriString);
-
-			// try to create file from uri
-			URI uri = new URI(uriString);
-			file = new File(uri);
-		}
-		catch (Exception e) {
-			// if exception is thrown while trying to create File just ignore
-			// and file will be null
-		}
-		return file;
-	}
-
-	private IRegion getHyperlinkRegion(Node node) {
-		IRegion hyperRegion = null;
-
-		if (node != null) {
-			short nodeType = node.getNodeType();
-			if (nodeType == Node.DOCUMENT_TYPE_NODE) {
-				// handle doc type node
-				IDOMNode docNode = (IDOMNode) node;
-				hyperRegion = new Region(docNode.getStartOffset(), docNode.getEndOffset() - docNode.getStartOffset());
-			}
-			else if (nodeType == Node.ATTRIBUTE_NODE) {
-				// handle attribute nodes
-				IDOMAttr att = (IDOMAttr) node;
-				// do not include quotes in attribute value region
-				int regOffset = att.getValueRegionStartOffset();
-				ITextRegion valueRegion = att.getValueRegion();
-				if (valueRegion != null) {
-					int regLength = valueRegion.getTextLength();
-					String attValue = att.getValueRegionText();
-					if (StringUtils.isQuoted(attValue)) {
-						++regOffset;
-						regLength = regLength - 2;
-					}
-					hyperRegion = new Region(regOffset, regLength);
-				}
-			}
-		}
-		return hyperRegion;
-	}
-
-	/**
-	 * Attempts to find an attribute within element that is openable.
-	 * 
-	 * @param element -
-	 *            cannot be null
-	 * @return Attr attribute that can be used for open on, null if no
-	 *         attribute could be found
-	 */
-	private Attr getLinkableAttr(Element element) {
-		CMElementDeclaration ed = getCMElementDeclaration(element);
-		// get the list of attributes for this node
-		NamedNodeMap attrs = element.getAttributes();
-		for (int i = 0; i < attrs.getLength(); ++i) {
-			// check if this attribute is "openOn-able"
-			Attr att = (Attr) attrs.item(i);
-			if (isLinkableAttr(att, ed)) {
-				return att;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Find the location hint for the given namespaceURI if it exists
-	 * 
-	 * @param elementNode -
-	 *            cannot be null
-	 * @param namespaceURI -
-	 *            cannot be null
-	 * @return location hint (systemId) if it was found, null otherwise
-	 */
-	private String getLocationHint(Element elementNode, String namespaceURI) {
-		Attr schemaLocNode = elementNode.getAttributeNodeNS(XSI_NAMESPACE_URI, SCHEMA_LOCATION);
-		if (schemaLocNode != null) {
-			StringTokenizer st = new StringTokenizer(schemaLocNode.getValue());
-			while (st.hasMoreTokens()) {
-				String publicId = st.hasMoreTokens() ? st.nextToken() : null;
-				String systemId = st.hasMoreTokens() ? st.nextToken() : null;
-				// found location hint
-				if (namespaceURI.equalsIgnoreCase(publicId))
-					return systemId;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the URI string
-	 * 
-	 * @param node -
-	 *            assumes not null
-	 */
-	private String getURIString(Node node, IDocument document) {
-		String resolvedURI = null;
-		// need the base location, publicId, and systemId for URIResolver
-		String baseLoc = null;
-		String publicId = null;
-		String systemId = null;
-
-		short nodeType = node.getNodeType();
-		// handle doc type node
-		if (nodeType == Node.DOCUMENT_TYPE_NODE) {
-			baseLoc = getBaseLocation(document);
-			publicId = ((DocumentType) node).getPublicId();
-			systemId = ((DocumentType) node).getSystemId();
-		}
-		else if (nodeType == Node.ATTRIBUTE_NODE) {
-			// handle attribute node
-			Attr attrNode = (Attr) node;
-			String attrName = attrNode.getName();
-			String attrValue = attrNode.getValue();
-			attrValue = StringUtils.strip(attrValue);
-			if (attrValue != null && attrValue.length() > 0) {
-				baseLoc = getBaseLocation(document);
-
-				// handle schemaLocation attribute
-				String prefix = DOMNamespaceHelper.getPrefix(attrName);
-				String unprefixedName = DOMNamespaceHelper.getUnprefixedName(attrName);
-				if ((XMLNS.equals(prefix)) || (XMLNS.equals(unprefixedName))) {
-					publicId = attrValue;
-					systemId = getLocationHint(attrNode.getOwnerElement(), publicId);
-					if (systemId == null) {
-						systemId = attrValue;
-					}
-				}
-				else if ((XSI_NAMESPACE_URI.equals(DOMNamespaceHelper.getNamespaceURI(attrNode))) && (SCHEMA_LOCATION.equals(unprefixedName))) {
-					// for now just use the first pair
-					// need to look into being more precise
-					StringTokenizer st = new StringTokenizer(attrValue);
-					publicId = st.hasMoreTokens() ? st.nextToken() : null;
-					systemId = st.hasMoreTokens() ? st.nextToken() : null;
-					// else check if xmlns publicId = value
-				}
-				else {
-					systemId = attrValue;
-				}
-			}
-		}
-
-		resolvedURI = resolveURI(baseLoc, publicId, systemId);
-		return resolvedURI;
-	}
-
-	/**
-	 * Returns true if this uriString is an http string
-	 * 
-	 * @param uriString
-	 * @return true if uriString is http string, false otherwise
-	 */
-	private boolean isHttp(String uriString) {
-		boolean isHttp = false;
-		if (uriString != null) {
-			String tempString = uriString.toLowerCase();
-			if (tempString.startsWith(HTTP_PROTOCOL))
-				isHttp = true;
-		}
-		return isHttp;
-	}
-
-	/**
-	 * Checks to see if the given attribute is openable. Attribute is openable
-	 * if it is a namespace declaration attribute or if the attribute value is
-	 * of type URI.
-	 * 
-	 * @param attr
-	 *            cannot be null
-	 * @param cmElement
-	 *            CMElementDeclaration associated with the attribute (can be
-	 *            null)
-	 * @return true if this attribute is "openOn-able" false otherwise
-	 */
-	private boolean isLinkableAttr(Attr attr, CMElementDeclaration cmElement) {
-		String attrName = attr.getName();
-		String prefix = DOMNamespaceHelper.getPrefix(attrName);
-		String unprefixedName = DOMNamespaceHelper.getUnprefixedName(attrName);
-		// determine if attribute is namespace declaration
-		if ((XMLNS.equals(prefix)) || (XMLNS.equals(unprefixedName)))
-			return true;
-
-		// determine if attribute contains schema location
-		if ((XSI_NAMESPACE_URI.equals(DOMNamespaceHelper.getNamespaceURI(attr))) && ((SCHEMA_LOCATION.equals(unprefixedName)) || (NO_NAMESPACE_SCHEMA_LOCATION.equals(unprefixedName))))
-			return true;
-
-		// determine if attribute value is of type URI
-		if (cmElement != null) {
-			CMAttributeDeclaration attrDecl = (CMAttributeDeclaration) cmElement.getAttributes().getNamedItem(attrName);
-			if ((attrDecl != null) && (attrDecl.getAttrType() != null) && (CMDataType.URI.equals(attrDecl.getAttrType().getDataTypeName()))) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Checks whether the given uriString is really pointing to a file
-	 * 
-	 * @param uriString
-	 * @return boolean
-	 */
-	private boolean isValidURI(String uriString) {
-		boolean isValid = false;
-
-		if (isHttp(uriString))
-			isValid = true;
-		else {
-			File file = getFileFromUriString(uriString);
-			if (file != null)
-				isValid = file.isFile();
-		}
-		return isValid;
-	}
-
-	/**
-	 * Resolves the given URI information
-	 * 
-	 * @param baseLocation
-	 * @param publicId
-	 * @param systemId
-	 * @return String resolved uri.
-	 */
-	private String resolveURI(String baseLocation, String publicId, String systemId) {
-		// dont resolve if there's nothing to resolve
-		if ((baseLocation == null) && (publicId == null) && (systemId == null))
-			return null;
-		return URIResolverPlugin.createResolver().resolve(baseLocation, publicId, systemId);
-	}
-}
diff --git a/bundles/org.eclipse.wst.xml.ui/plugin.properties b/bundles/org.eclipse.wst.xml.ui/plugin.properties
index 00cb8bb..17868e6 100644
--- a/bundles/org.eclipse.wst.xml.ui/plugin.properties
+++ b/bundles/org.eclipse.wst.xml.ui/plugin.properties
@@ -75,3 +75,6 @@
 preferenceKeywords.templates=editor xml templates snippet macros
 preferenceKeywords.styles=editor xml style customize syntax highlighting type text content foreground background bold color
 preferenceKeywords.xmlcatalog=xml catalog entries
+##
+XML_Source_target_name=XML Source
+XML_hyperlink=Tags And Attributes
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.xml.ui/plugin.xml b/bundles/org.eclipse.wst.xml.ui/plugin.xml
index 7589b0f..733ee74 100644
--- a/bundles/org.eclipse.wst.xml.ui/plugin.xml
+++ b/bundles/org.eclipse.wst.xml.ui/plugin.xml
@@ -512,4 +512,20 @@
                id="org.eclipse.ui.texteditor.SelectRulerAction"/>
         </editorContribution>
 	</extension>
+	<extension
+		point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectorTargets">
+		<target
+			id="org.eclipse.core.runtime.xml"
+			name="%XML_Source_target_name">
+		</target>
+	</extension>
+	<extension
+		point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">
+		<hyperlinkDetector
+			class="org.eclipse.wst.xml.ui.internal.hyperlink.XMLHyperlinkDetector"
+			id="org.eclipse.wst.xml.ui.internal.hyperlink.XMLHyperlinkDetector"
+			name="%XML_hyperlink"
+			targetId="org.eclipse.core.runtime.xml">
+		</hyperlinkDetector>
+   </extension>
 </plugin>
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/StructuredTextViewerConfigurationXML.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/StructuredTextViewerConfigurationXML.java
index 2af1459..633f64c 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/StructuredTextViewerConfigurationXML.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/StructuredTextViewerConfigurationXML.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2005 IBM Corporation and others.
+ * Copyright (c) 2001, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -14,6 +14,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Vector;
 
 import org.eclipse.core.runtime.IPath;
@@ -24,11 +25,9 @@
 import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
 import org.eclipse.jface.text.formatter.IContentFormatter;
 import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
-import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
 import org.eclipse.jface.text.information.IInformationProvider;
 import org.eclipse.jface.text.source.ISourceViewer;
 import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
 import org.eclipse.wst.sse.core.text.IStructuredPartitions;
 import org.eclipse.wst.sse.ui.StructuredTextViewerConfiguration;
 import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
@@ -38,6 +37,7 @@
 import org.eclipse.wst.sse.ui.internal.util.EditorUtility;
 import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
 import org.eclipse.wst.xml.core.internal.preferences.XMLCorePreferenceNames;
+import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;
 import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML;
 import org.eclipse.wst.xml.core.internal.text.rules.StructuredTextPartitionerForXML;
 import org.eclipse.wst.xml.core.text.IXMLPartitions;
@@ -47,7 +47,6 @@
 import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;
 import org.eclipse.wst.xml.ui.internal.contentoutline.JFaceNodeLabelProvider;
 import org.eclipse.wst.xml.ui.internal.doubleclick.XMLDoubleClickStrategy;
-import org.eclipse.wst.xml.ui.internal.hyperlink.XMLHyperlinkDetector;
 import org.eclipse.wst.xml.ui.internal.style.LineStyleProviderForXML;
 import org.eclipse.wst.xml.ui.internal.taginfo.XMLInformationProvider;
 import org.eclipse.wst.xml.ui.internal.taginfo.XMLTagInfoHoverProcessor;
@@ -149,24 +148,6 @@
 		return doubleClickStrategy;
 	}
 
-	public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
-		if ((sourceViewer == null) || !fPreferenceStore.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_HYPERLINKS_ENABLED)) {
-			return null;
-		}
-
-		List allDetectors = new ArrayList(0);
-		allDetectors.add(new XMLHyperlinkDetector());
-
-		IHyperlinkDetector[] superDetectors = super.getHyperlinkDetectors(sourceViewer);
-		for (int m = 0; m < superDetectors.length; m++) {
-			IHyperlinkDetector detector = superDetectors[m];
-			if (!allDetectors.contains(detector)) {
-				allDetectors.add(detector);
-			}
-		}
-		return (IHyperlinkDetector[]) allDetectors.toArray(new IHyperlinkDetector[0]);
-	}
-
 	public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
 		Vector vector = new Vector();
 
@@ -238,7 +219,7 @@
 		}
 		return fLineStyleProviderForXML;
 	}
-	
+
 	public ILabelProvider getStatusLineLabelProvider(ISourceViewer sourceViewer) {
 		if (fStatusLineLabelProvider == null) {
 			fStatusLineLabelProvider = new JFaceNodeLabelProvider() {
@@ -295,4 +276,10 @@
 
 		return textHover;
 	}
+
+	protected Map getHyperlinkDetectorTargets(ISourceViewer sourceViewer) {
+		Map targets = super.getHyperlinkDetectorTargets(sourceViewer);
+		targets.put(ContentTypeIdForXML.ContentTypeID_XML, null);
+		return targets;
+	}
 }
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/hyperlink/XMLHyperlinkDetector.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/hyperlink/XMLHyperlinkDetector.java
index 98b620b..3645b5b 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/hyperlink/XMLHyperlinkDetector.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/hyperlink/XMLHyperlinkDetector.java
@@ -1,10 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.wst.xml.ui.internal.hyperlink;
 
 import java.io.File;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
-import com.ibm.icu.util.StringTokenizer;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.ResourcesPlugin;
@@ -14,8 +23,8 @@
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextViewer;
 import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
 import org.eclipse.jface.text.hyperlink.IHyperlink;
-import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
 import org.eclipse.jface.text.hyperlink.URLHyperlink;
 import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
 import org.eclipse.wst.sse.core.StructuredModelManager;
@@ -37,18 +46,15 @@
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 
+import com.ibm.icu.util.StringTokenizer;
+
 /**
  * Detects hyperlinks in XML tags. Includes detection in DOCTYPE and attribute
  * values. Resolves references to schemas, dtds, etc using the Common URI
  * Resolver.
  * 
  */
-public class XMLHyperlinkDetector implements IHyperlinkDetector {
-	// copies of this class exist in:
-	// org.eclipse.wst.xml.ui.internal.hyperlink
-	// org.eclipse.wst.html.ui.internal.hyperlink
-	// org.eclipse.jst.jsp.ui.internal.hyperlink
-
+public class XMLHyperlinkDetector extends AbstractHyperlinkDetector {
 	private final String HTTP_PROTOCOL = "http://";//$NON-NLS-1$
 	private final String NO_NAMESPACE_SCHEMA_LOCATION = "noNamespaceSchemaLocation"; //$NON-NLS-1$
 	private final String SCHEMA_LOCATION = "schemaLocation"; //$NON-NLS-1$