Initial code contribution.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9ecf4b9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+bin
+target
+
diff --git a/plugins/org.eclipse.jst.jee.web.xml/.classpath b/plugins/org.eclipse.jst.jee.web.xml/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/plugins/org.eclipse.jst.jee.web.xml/.project b/plugins/org.eclipse.jst.jee.web.xml/.project
new file mode 100644
index 0000000..a590fb4
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.jst.jee.web.xml</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/plugins/org.eclipse.jst.jee.web.xml/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.jst.jee.web.xml/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..6e44215
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Thu Dec 02 09:32:20 CET 2010

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

+org.eclipse.jdt.core.compiler.compliance=1.5

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.5

diff --git a/plugins/org.eclipse.jst.jee.web.xml/META-INF/MANIFEST.MF b/plugins/org.eclipse.jst.jee.web.xml/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..16df6df
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/META-INF/MANIFEST.MF
@@ -0,0 +1,20 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.jst.jee.web.xml;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.jst.jee.web.xml.internal.WebXMLPlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.wst.xml.core,
+ org.eclipse.core.resources,
+ org.eclipse.wst.sse.core,
+ org.eclipse.wst.xml.search.editor;bundle-version="1.0.0",
+ org.eclipse.wst.xml.ui,
+ org.eclipse.swt,
+ org.eclipse.ui
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.jst.jee.web.xml
diff --git a/plugins/org.eclipse.jst.jee.web.xml/build.properties b/plugins/org.eclipse.jst.jee.web.xml/build.properties
new file mode 100644
index 0000000..42724a0
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/build.properties
@@ -0,0 +1,17 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .,\

+               plugin.xml,\

+               plugin.properties,\

+               icons/

diff --git a/plugins/org.eclipse.jst.jee.web.xml/icons/servlet.gif b/plugins/org.eclipse.jst.jee.web.xml/icons/servlet.gif
new file mode 100644
index 0000000..fc1bece
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/icons/servlet.gif
Binary files differ
diff --git a/plugins/org.eclipse.jst.jee.web.xml/plugin.properties b/plugins/org.eclipse.jst.jee.web.xml/plugin.properties
new file mode 100644
index 0000000..20ce1c5
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/plugin.properties
@@ -0,0 +1,14 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+pluginName=Web XML config Core Support

+providerName=Eclipse.org

+

+configFileContentTypeName=XML Web
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.jee.web.xml/plugin.xml b/plugins/org.eclipse.jst.jee.web.xml/plugin.xml
new file mode 100644
index 0000000..43a959f
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/plugin.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.4"?>

+<plugin>

+

+  	<!-- XML Struts2 content type declaration --> 

+	<extension

+         point="org.eclipse.core.contenttype.contentTypes">

+      <content-type 

+            base-type="org.eclipse.core.runtime.xml"

+            file-extensions="xml" 

+            id="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile"

+            name="%configFileContentTypeName"

+            priority="high">

+         <describer

+               class="org.eclipse.core.runtime.content.XMLRootElementContentDescriber2">               

+               <parameter

+                     name="element"

+                     value="web-app">

+               </parameter>               

+         </describer>

+      </content-type>

+    </extension>

+   

+	<!-- Declaration of references between XML nodes --> 

+    <extension

+         point="org.eclipse.wst.xml.search.editor.xmlReferences">

+         <references

+               contentTypeIds="org.eclipse.jst.j2ee.webDD,org.eclipse.jst.jee.ee5webDD,org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile">

+            

+            <!-- filter/filter-class => Java class -->

+			<reference>		

+				<from path="/ns:web-app/ns:filter/ns:filter-class"

+					  targetNodes="text()"

+					  querySpecificationId="web.querySpecification" />

+				<toJava />	

+			</reference>

+			<!-- filter-mapping/filter-name => filter/filter-name -->

+			<reference>		

+				<from path="/ns:web-app/ns:filter-mapping/ns:filter-name"

+					  targetNodes="text()" 

+					  querySpecificationId="web.querySpecification" />

+				<to path="/ns:web-app/ns:filter/ns:filter-name"

+					targetNodes="text()" 

+					querySpecificationId="web.querySpecification" />	

+			</reference>

+

+            <!-- listener/listener-class => Java class -->

+			<reference>		

+				<from path="/ns:web-app/ns:listener/ns:listener-class"

+					  targetNodes="text()" 

+					  querySpecificationId="web.querySpecification" />

+				<toJava />	

+			</reference>

+						

+            <!-- servlet/servlet-class => Java class -->

+			<reference>		

+				<from path="/ns:web-app/ns:servlet/ns:servlet-class"

+					  targetNodes="text()"

+					  querySpecificationId="web.querySpecification" />

+				<toJava />	

+			</reference>

+			

+			<!-- servlet-mapping/servlet-name => servlet/servlet-name -->

+			<reference>		

+				<from path="/ns:web-app/ns:servlet-mapping/ns:servlet-name"

+					  targetNodes="text()" 

+					  querySpecificationId="web.querySpecification" />

+				<to path="/ns:web-app/ns:servlet/ns:servlet-name"

+					targetNodes="text()"

+					querySpecificationId="web.querySpecification"

+					additionalProposalInfoProviderId="web.servlet.info" />	

+			</reference>

+			

+			<!-- welcome-file -->

+			<reference>

+			      <from

+			            path="/ns:web-app/ns:welcome-file-list/ns:welcome-file"

+			            targetNodes="text()"

+			            querySpecificationId="web.querySpecification" >

+			      </from>

+			      <toResource querySpecificationId="web.files.querySpecification" />

+			</reference>

+         </references>

+   </extension>

+   

+  	<extension point="org.eclipse.wst.sse.ui.editorConfiguration">

+		<sourceViewerConfiguration

+			class="org.eclipse.wst.xml.search.editor.XMLReferencesStructuredTextViewerConfiguration"

+			target="org.eclipse.jst.j2ee.webDD" />   			

+	</extension>

+	<extension point="org.eclipse.wst.sse.ui.editorConfiguration">

+		<sourceViewerConfiguration

+			class="org.eclipse.wst.xml.search.editor.XMLReferencesStructuredTextViewerConfiguration"

+			target="org.eclipse.jst.jee.ee5webDD" />   			

+	</extension>

+  	<extension point="org.eclipse.wst.sse.ui.editorConfiguration">

+		<sourceViewerConfiguration

+			class="org.eclipse.wst.xml.search.editor.XMLReferencesStructuredTextViewerConfiguration"

+			target="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile" />   			

+	</extension>

+	

+   <!-- Source validation for XML web.xml files  -->

+   <extension point="org.eclipse.wst.sse.ui.sourcevalidation">

+		<validator

+			scope="partial"

+			class="org.eclipse.wst.xml.ui.internal.validation.MarkupValidator"

+			id="org.eclipse.jst.j2ee.webDD.validation.MarkupValidator">

+			<contentTypeIdentifier id="org.eclipse.jst.j2ee.webDD">

+				<partitionType id="org.eclipse.wst.xml.XML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>

+			<contentTypeIdentifier id="org.eclipse.jst.jee.ee5webDD" >

+				<partitionType id="org.eclipse.wst.xml.XML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>

+			<contentTypeIdentifier id="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile">

+				<partitionType id="org.eclipse.wst.xml.XML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>			

+		</validator>

+	</extension>

+   <extension point="org.eclipse.wst.sse.ui.sourcevalidation">

+		<validator

+			scope="partial"

+			class="org.eclipse.wst.xml.ui.internal.validation.DelegatingSourceValidatorForXML"

+			id="org.eclipse.jst.j2ee.webDD.validation.DelegatingSourceValidatorForXML">

+			<contentTypeIdentifier id="org.eclipse.jst.j2ee.webDD">

+				<partitionType id="org.eclipse.wst.xml.XML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>

+			<contentTypeIdentifier id="org.eclipse.jst.jee.ee5webDD" >

+				<partitionType id="org.eclipse.wst.xml.XML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>

+			<contentTypeIdentifier id="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile">

+				<partitionType id="org.eclipse.wst.xml.XML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>			

+		</validator>

+	</extension>	

+	   	

+   <extension point="org.eclipse.wst.sse.ui.sourcevalidation">

+		<validator

+			scope="partial"

+			class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesValidator"

+			id="org.eclipse.jst.j2ee.webDD.validation.Validator">

+			<contentTypeIdentifier id="org.eclipse.jst.j2ee.webDD">

+				<partitionType id="org.eclipse.wst.xml.XML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>

+			<contentTypeIdentifier id="org.eclipse.jst.jee.ee5webDD" >

+				<partitionType id="org.eclipse.wst.xml.XML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>

+			<contentTypeIdentifier id="org.eclipse.jst.jee.web.xml.contenttype.webXMLConfigFile">

+				<partitionType id="org.eclipse.wst.xml.XML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>			

+		</validator>

+	</extension>

+	

+   <extension

+         point="org.eclipse.wst.xml.search.core.querySpecifications">

+        <querySpecification id="web.querySpecification" 

+        				    class="org.eclipse.jst.jee.web.xml.internal.search.WebXMLQuerySpecification" />

+   </extension>

+   

+   <extension

+         point="org.eclipse.wst.xml.search.core.resourceQuerySpecifications">

+        <querySpecification id="web.files.querySpecification" 

+        				    class="org.eclipse.jst.jee.web.xml.internal.search.WebContentResourcesQuerySpecification" />

+   </extension>		

+   

+	<extension

+         point="org.eclipse.wst.xml.search.editor.contentAssists">

+        <additionalProposalInfoProvider id="web.servlet.info"

+        		  class="org.eclipse.jst.jee.web.xml.internal.search.contentassist.ServletContentAssistAdditionalProposalInfoProvider" >

+        </additionalProposalInfoProvider>

+   </extension>   

+   		

+</plugin>

diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/WebXMLConstants.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/WebXMLConstants.java
new file mode 100644
index 0000000..8040951
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/WebXMLConstants.java
@@ -0,0 +1,22 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jee.web.xml;

+

+public interface WebXMLConstants {

+

+	String STRUTS2_CONFIG_CONTENT_TYPE = "org.apache.struts2.ide.contenttype.struts2ConfigFile";

+		

+	// XML Attributes

+	String NAME_ATTR = "name";

+	String CLASS_ATTR = "class";

+	String ABSTRACT_ATTR = "abstract";

+	String DEFAULT_ATTR = "default";

+}

diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/WebXMLPlugin.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/WebXMLPlugin.java
new file mode 100644
index 0000000..7644cb2
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/WebXMLPlugin.java
@@ -0,0 +1,76 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jee.web.xml.internal;

+

+import java.net.URL;

+

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class WebXMLPlugin extends AbstractUIPlugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "org.eclipse.jst.jee.web.xml";

+

+	// The shared instance

+	private static WebXMLPlugin plugin;

+

+	public static String SERVLET_IMG = "servlet";

+

+	/**

+	 * The constructor

+	 */

+	public WebXMLPlugin() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;

+

+		URL baseIconsURL = getBundle().getEntry("icons/");

+		ImageDescriptor servletImage = ImageDescriptor.createFromURL(new URL(

+				baseIconsURL, "servlet.gif"));

+		getImageRegistry().put(SERVLET_IMG, servletImage);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void stop(BundleContext context) throws Exception {

+		plugin = null;

+		super.stop(context);

+	}

+

+	/**

+	 * Returns the shared instance

+	 * 

+	 * @return the shared instance

+	 */

+	public static WebXMLPlugin getDefault() {

+		return plugin;

+	}

+

+}

diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesQuerySpecification.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesQuerySpecification.java
new file mode 100644
index 0000000..4ec6fa1
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesQuerySpecification.java
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jee.web.xml.internal.search;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+import org.eclipse.wst.xml.search.core.resource.IResourceRequestor;

+import org.eclipse.wst.xml.search.core.resource.IResourceRequestorProvider;

+

+public class WebContentResourcesQuerySpecification implements

+		IResourceProvider, IResourceRequestorProvider {

+

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return resource.getParent().getParent();

+	}

+

+	public IResourceRequestor getRequestor() {

+		return WebContentResourcesRequestor.INSTANCE;

+	}

+

+}

diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesRequestor.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesRequestor.java
new file mode 100644
index 0000000..f7894d7
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebContentResourcesRequestor.java
@@ -0,0 +1,37 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jee.web.xml.internal.search;

+

+import org.eclipse.core.resources.IFolder;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.resource.DefaultResourceRequestor;

+import org.eclipse.wst.xml.search.core.resource.IResourceRequestor;

+import org.eclipse.wst.xml.search.core.resource.IURIResolver;

+

+public class WebContentResourcesRequestor extends DefaultResourceRequestor {

+

+	public static final IResourceRequestor INSTANCE = new WebContentResourcesRequestor();

+

+	@Override

+	public boolean accept(Object selectedNode, IResource rootContainer,

+			IFolder folder, IURIResolver resolver, String matching,

+			boolean fullMatch) {

+		if ("WEB-INF".equals(folder.getName())) {

+			return false;

+		}

+		if ("META-INF".equals(folder.getName())) {

+			return false;

+		}

+		return super.accept(selectedNode, rootContainer, folder, resolver,

+				matching, fullMatch);

+	}

+}

diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLQuerySpecification.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLQuerySpecification.java
new file mode 100644
index 0000000..f179efa
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLQuerySpecification.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jee.web.xml.internal.search;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IdentityResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestorProvider;

+

+public class WebXMLQuerySpecification implements IXMLSearchRequestorProvider,

+		IResourceProvider {

+

+	public IXMLSearchRequestor getRequestor() {

+		return WebXMLSearchRequestor.INSTANCE;

+	}

+

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return resource;

+	}

+

+}

diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLSearchRequestor.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLSearchRequestor.java
new file mode 100644
index 0000000..f8b5193
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/WebXMLSearchRequestor.java
@@ -0,0 +1,26 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jee.web.xml.internal.search;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AbstractXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+

+public class WebXMLSearchRequestor extends AbstractXMLSearchRequestor {

+

+	public static IXMLSearchRequestor INSTANCE = new WebXMLSearchRequestor();

+

+	@Override

+	protected boolean accept(IFile file, IResource rootResource) {

+		return true;

+	}

+}

diff --git a/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/contentassist/ServletContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/contentassist/ServletContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..7d1e933
--- /dev/null
+++ b/plugins/org.eclipse.jst.jee.web.xml/src/org/eclipse/jst/jee/web/xml/internal/search/contentassist/ServletContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,79 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jee.web.xml.internal.search.contentassist;

+

+import org.eclipse.jst.jee.web.xml.internal.WebXMLPlugin;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;

+import org.eclipse.wst.xml.search.editor.contentassist.ElementContentAssistAdditionalProposalInfoProvider;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+import org.w3c.dom.NodeList;

+import org.w3c.dom.Text;

+

+public class ServletContentAssistAdditionalProposalInfoProvider extends

+		ElementContentAssistAdditionalProposalInfoProvider {

+

+	public Image getImage(Node node) {

+		return WebXMLPlugin.getDefault().getImageRegistry().get(

+				WebXMLPlugin.SERVLET_IMG);

+	}

+

+	@Override

+	protected String doGetTextInfo(IDOMElement servletNameElt) {

+		IDOMElement element = (IDOMElement)servletNameElt.getParentNode();

+		StringBuilder buf = new StringBuilder();

+		buf.append("<b>------------------------ Servlet ------------------------</b> ");

+		// description

+		buf.append("<br><b>Description:</b> ");

+		String description = getTextContent(element, "description");

+		if (description != null) {

+			buf.append(description);

+		}

+		// display-name

+		buf.append("<br><b>Display name:</b> ");

+		String displayName = getTextContent(element, "display-name");

+		if (displayName != null) {

+			buf.append(displayName);

+		}

+		// servlet-name

+		buf.append("<br><b>Servlet name:</b> ");

+		String servletName = getTextContent(element, "servlet-name");

+		if (servletName != null) {

+			buf.append(servletName);

+		}

+		// servlet-class

+		buf.append("<br><b>Servlet class:</b> ");

+		String servletClass = getTextContent(element, "servlet-class");

+		if (servletClass != null) {

+			buf.append(servletClass);

+		}

+		//buf.append("<br><b>File:</b> ");

+		//String baseLocation = element.getModel().getBaseLocation();

+		//buf.append(baseLocation);

+		return buf.toString();

+

+	}

+

+	private String getTextContent(IDOMElement element, String elementName) {

+		NodeList nodes = element.getElementsByTagName(elementName);

+		if (nodes.getLength() < 1) {

+			return "";

+		}

+		Element childElement = (Element)nodes.item(0);

+		Text text = (Text) childElement.getFirstChild();

+		if (text == null) {

+			return "";

+		}

+		return text.getData();

+	}

+

+}

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/.classpath b/plugins/org.eclipse.jst.jsp.search.editor/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/.project b/plugins/org.eclipse.jst.jsp.search.editor/.project
new file mode 100644
index 0000000..8cb13fa
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.jst.jsp.search.editor</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.jst.jsp.search.editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..423215b
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Wed Jan 19 14:52:01 CET 2011

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

+org.eclipse.jdt.core.compiler.compliance=1.5

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.5

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.jst.jsp.search.editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8c3ba5d
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.jst.jsp.search.editor;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.jst.jsp.search.editor.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.wst.sse.ui,
+ org.eclipse.jst.jsp.ui,
+ org.eclipse.jface.text,
+ org.eclipse.wst.xml.ui,
+ org.eclipse.wst.sse.core,
+ org.eclipse.wst.xml.core,
+ org.eclipse.wst.xml.search.editor;bundle-version="1.0.0",
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.core.resources,
+ org.eclipse.jst.jsp.core,
+ org.eclipse.ui.workbench.texteditor
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.jst.jsp.search.editor,
+ org.eclipse.jst.jsp.search.editor.queryspecifications,
+ org.eclipse.jst.jsp.search.editor.references.filters,
+ org.eclipse.jst.jsp.search.editor.util
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/build.properties b/plugins/org.eclipse.jst.jsp.search.editor/build.properties
new file mode 100644
index 0000000..8454c29
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/build.properties
@@ -0,0 +1,16 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .,\

+               plugin.xml,\

+               plugin.properties

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/plugin.properties b/plugins/org.eclipse.jst.jsp.search.editor/plugin.properties
new file mode 100644
index 0000000..7c6a6d5
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/plugin.properties
@@ -0,0 +1,14 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+pluginName=WST JSP Search Editor

+providerName=Angelo ZERR

+

+JSPReferencesBatchValidator_description= JSP References Validator
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/plugin.xml b/plugins/org.eclipse.jst.jsp.search.editor/plugin.xml
new file mode 100644
index 0000000..c0a997c
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/plugin.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.0"?>

+<plugin>

+	

+	<extension

+	      point="org.eclipse.wst.sse.ui.editorConfiguration">

+	      <sourceViewerConfiguration

+             class="org.eclipse.jst.jsp.ui.StructuredTextViewerConfigurationJSP"

+             target="org.eclipse.jst.jsp.core.jspsource" />

+       	 <provisionalConfiguration 

+                    type="contentassistprocessor" 

+                    class="org.eclipse.jst.jsp.search.editor.internal.contentassist.JSPReferenceContentAssistProcessor" 

+                    target="org.eclipse.jst.jsp.JSP_DIRECTIVE" />

+	    <!--<documentationTextHover

+	          class="org.eclipse.wst.xml.search.editor.hover.XMLReferencesInfoHoverProcessor"

+	          target="org.eclipse.jst.jsp.JSP_DEFAULT,org.eclipse.jst.jsp.JSP_DIRECTIVE">

+	    </documentationTextHover>-->                           	

+		<!--<provisionalConfiguration 

+                    type="linestyleprovider" 

+                    class="org.eclipse.jst.jsp.search.editor.JSPReferencesContentAssistProcessor" 

+                    target="org.eclipse.jst.jsp.JSP_DIRECTIVE" />-->                    

+	</extension>

+	

+	<extension

+		point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">

+		<hyperlinkDetector

+			class="org.eclipse.wst.xml.search.editor.hyperlink.XMLReferencesHyperlinkDetector"

+			id="org.eclipse.jst.jsp.search.editor.internal.hyperlink.JSPReferenceHyperlinkDetector"

+			name="%JSPJava_hyperlink"

+			targetId="org.eclipse.jst.jsp.core.jspsource">

+		</hyperlinkDetector>

+   </extension>

+	

+   <extension point="org.eclipse.wst.sse.ui.sourcevalidation">

+		<validator

+			scope="partial"

+			class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesValidator"

+			id="org.eclipse.jst.jsp.search.editor.JSPSearchValidator">

+			<contentTypeIdentifier id="org.eclipse.jst.jsp.core.jspsource">

+				<partitionType id="org.eclipse.jst.jsp.JSP_DIRECTIVE">

+				</partitionType>

+			</contentTypeIdentifier>

+		</validator>

+	</extension> 

+   	

+	<extension id="jspReferencesBatchValidator" name="%JSPReferencesBatchValidator_description" point="org.eclipse.wst.validation.validatorV2">

+      <validator

+            build="true"

+            class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesBatchValidator"

+            manual="true"            

+            version="1"

+            markerId="org.eclipse.wst.xml.search.editor.validationMarker">

+         <include>

+            <rules>

+               <fileext

+                     caseSensitive="false"

+                     ext="jsp">

+               </fileext>

+            </rules>

+         </include>

+      </validator>

+   </extension>

+      	

+</plugin>
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/Activator.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/Activator.java
new file mode 100644
index 0000000..59f4997
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/Activator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jsp.search.editor;

+

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class Activator extends AbstractUIPlugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "org.eclipse.jst.jsp.search.editor";

+

+	// The shared instance

+	private static Activator plugin;

+	

+	/**

+	 * The constructor

+	 */

+	public Activator() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)

+	 */

+	public void stop(BundleContext context) throws Exception {

+		plugin = null;

+		super.stop(context);

+	}

+

+	/**

+	 * Returns the shared instance

+	 *

+	 * @return the shared instance

+	 */

+	public static Activator getDefault() {

+		return plugin;

+	}

+

+}

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/JSPReferenceContentAssistProcessor.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/JSPReferenceContentAssistProcessor.java
new file mode 100644
index 0000000..051f371
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/JSPReferenceContentAssistProcessor.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jsp.search.editor.internal.contentassist;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.contentassist.XMLReferencesContentAssistUtils;

+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;

+import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;

+

+public class JSPReferenceContentAssistProcessor extends

+		XMLContentAssistProcessor {

+

+	@Override

+	protected void addAttributeValueProposals(

+			ContentAssistRequest contentAssistRequest) {

+		int proposalCount = 0;

+		if (contentAssistRequest.getCompletionProposals() != null) {

+			proposalCount = contentAssistRequest.getCompletionProposals().length;

+		}

+		IDOMNode node = (IDOMNode) contentAssistRequest.getNode();

+		// XML reference

+		XMLReferencesContentAssistUtils

+				.addAttributeValueProposals(contentAssistRequest);

+

+		super.addAttributeValueProposals(contentAssistRequest);

+

+	}

+}

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/util/TaglibUtils.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/util/TaglibUtils.java
new file mode 100644
index 0000000..90c002e
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/internal/contentassist/util/TaglibUtils.java
@@ -0,0 +1,113 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jsp.search.editor.internal.contentassist.util;

+

+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDAttributeDeclaration;

+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDDocument;

+import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;

+import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;

+import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;

+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;

+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;

+import org.eclipse.wst.xml.core.internal.ssemodelquery.ModelQueryAdapter;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+public class TaglibUtils {

+

+	public static String getTagURI(Node node) {

+		int nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			Attr attr = (Attr) node;

+			return getTagURI(attr);

+		case Node.ELEMENT_NODE:

+			Element element = (Element) node;

+			return getTagURI(element);

+		}

+		return null;

+	}

+

+	public static String getTagURI(Attr attr) {

+		CMAttributeDeclaration decl = getAttributeDeclaration(attr);

+		if (decl == null) {

+			return null;

+		}

+		if (decl instanceof TLDAttributeDeclaration) {

+			CMDocument doc = ((TLDAttributeDeclaration) decl)

+					.getOwnerDocument();

+			if (doc instanceof TLDDocument) {

+				return ((TLDDocument) doc).getUri();

+			}

+		}

+		return null;

+	}

+

+	public static String getTagURI(Element element) {

+		CMElementDeclaration decl = getElementDeclaration(element);

+		if (decl == null) {

+			return null;

+		}

+		if (decl instanceof TLDElementDeclaration) {

+			CMDocument doc = ((TLDElementDeclaration) decl).getOwnerDocument();

+			if (doc instanceof TLDDocument) {

+				return ((TLDDocument) doc).getUri();

+			}

+		}

+		return null;

+	}

+

+	/**

+	 * Get attribute declaration of specified element

+	 * 

+	 * @param attr

+	 * @return null if can't get it.

+	 */

+	public static CMAttributeDeclaration getAttributeDeclaration(Attr attr) {

+		if (attr == null) {

+			return null;

+		}

+		INodeNotifier notifier = (INodeNotifier) attr.getOwnerDocument();

+		if (notifier == null) {

+			return null;

+		}

+		ModelQueryAdapter mqa = (ModelQueryAdapter) notifier

+				.getAdapterFor(ModelQueryAdapter.class);

+		if (mqa == null) {

+			return null;

+		}

+		return mqa.getModelQuery().getCMAttributeDeclaration(attr);

+	}

+

+	/**

+	 * get element declaration of specified element

+	 * 

+	 * @param element

+	 * @return null if can't get it.

+	 */

+	public static CMElementDeclaration getElementDeclaration(Element element) {

+		if (element == null) {

+			return null;

+		}

+		INodeNotifier notifier = (INodeNotifier) element.getOwnerDocument();

+		if (notifier == null) {

+			return null;

+		}

+		ModelQueryAdapter mqa = (ModelQueryAdapter) notifier

+				.getAdapterFor(ModelQueryAdapter.class);

+		if (mqa == null) {

+			return null;

+		}

+		return mqa.getModelQuery().getCMElementDeclaration(element);

+	}

+

+}

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPQuerySpecification.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPQuerySpecification.java
new file mode 100644
index 0000000..4d984a7
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPQuerySpecification.java
@@ -0,0 +1,44 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jsp.search.editor.queryspecifications;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestorProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchVisitorProvider;

+import org.eclipse.wst.xml.search.editor.queryspecifications.visitor.XPathPathNodeSetSearchVisitorWithFilter;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+

+public abstract class JSPQuerySpecification implements

+		IXMLSearchRequestorProvider, IResourceProvider,

+		IXMLSearchVisitorProvider {

+

+	private final IXMLSearchDOMDocumentVisitor visitor;

+

+	public JSPQuerySpecification(IXMLReferenceFilter filter) {

+		visitor = new XPathPathNodeSetSearchVisitorWithFilter(filter);

+	}

+

+	public IXMLSearchRequestor getRequestor() {

+		return JSPSearchRequestor.INSTANCE;

+	}

+

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return WebContentFolderProvider.INSTANCE.getResource(selectedNode,

+				resource);

+	}

+

+	public IXMLSearchDOMDocumentVisitor getVisitor() {

+		return visitor;

+	}

+}

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPSearchRequestor.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPSearchRequestor.java
new file mode 100644
index 0000000..bbf84e6
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/JSPSearchRequestor.java
@@ -0,0 +1,45 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jsp.search.editor.queryspecifications;

+

+import java.util.ArrayList;

+import java.util.Collection;

+

+import org.eclipse.core.resources.IFolder;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jst.jsp.core.internal.provisional.contenttype.ContentTypeIdForJSP;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.ContentTypeXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+

+public class JSPSearchRequestor extends ContentTypeXMLSearchRequestor {

+

+	private static final String META_INF = "META-INF";

+	private static final String WEB_INF = "WEB-INF";

+	

+	public static IXMLSearchRequestor INSTANCE = new JSPSearchRequestor();

+

+	@Override

+	protected Collection<String> getSupportedContentTypeIds() {

+		Collection<String> contentTypeIds = new ArrayList<String>();

+		contentTypeIds.add(ContentTypeIdForJSP.ContentTypeID_JSP);

+		return contentTypeIds;

+	}

+

+	@Override

+	public boolean accept(IFolder folder, IResource rootResource) {

+		if (WEB_INF.equals(folder.getName())

+				|| META_INF.equals(folder.getName())) {

+			return false;

+		}

+		return super.accept(folder, rootResource);

+	}

+

+}

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/WebContentFolderProvider.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/WebContentFolderProvider.java
new file mode 100644
index 0000000..0ef05b9
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/queryspecifications/WebContentFolderProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jsp.search.editor.queryspecifications;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jst.jsp.search.editor.util.WebProjectUtils;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+

+public class WebContentFolderProvider implements IResourceProvider {

+

+	public static final IResourceProvider INSTANCE = new WebContentFolderProvider();;

+

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return WebProjectUtils.getWebContentRootFolder(resource.getProject());

+	}

+

+}

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/references/filters/AbstractTaglibReferenceFilter.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/references/filters/AbstractTaglibReferenceFilter.java
new file mode 100644
index 0000000..81141ef
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/references/filters/AbstractTaglibReferenceFilter.java
@@ -0,0 +1,42 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jsp.search.editor.references.filters;

+

+import java.util.Collection;

+

+import org.eclipse.jst.jsp.search.editor.internal.contentassist.util.TaglibUtils;

+import org.eclipse.wst.sse.core.utils.StringUtils;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.w3c.dom.Node;

+

+public abstract class AbstractTaglibReferenceFilter implements

+		IXMLReferenceFilter {

+

+	private Collection<String> taglibURIs = null;

+

+	public boolean accept(Node node) {

+		String taglibURI = TaglibUtils.getTagURI(node);

+		if (StringUtils.isQuoted(taglibURI)) {

+			return false;

+		}

+		Collection<String> uris = internalGetTaglibURIs();

+		return uris.contains(taglibURI);

+	}

+

+	public Collection<String> internalGetTaglibURIs() {

+		if (taglibURIs == null) {

+			taglibURIs = getTaglibURIs();

+		}

+		return taglibURIs;

+	}

+

+	protected abstract Collection<String> getTaglibURIs();

+}

diff --git a/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/util/WebProjectUtils.java b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/util/WebProjectUtils.java
new file mode 100644
index 0000000..d3e1aac
--- /dev/null
+++ b/plugins/org.eclipse.jst.jsp.search.editor/src/org/eclipse/jst/jsp/search/editor/util/WebProjectUtils.java
@@ -0,0 +1,28 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jst.jsp.search.editor.util;

+

+import org.eclipse.core.resources.IFolder;

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.core.runtime.IPath;

+import org.eclipse.jst.jsp.core.internal.util.FacetModuleCoreSupport;

+

+public class WebProjectUtils {

+

+	public static IFolder getWebContentRootFolder(IProject project) {

+		IPath webContentPath = FacetModuleCoreSupport.getWebContentRootPath(project);

+		if(webContentPath != null) {

+			return (IFolder)ResourcesPlugin.getWorkspace().getRoot().findMember(webContentPath);

+		}

+		return null;

+	}

+}

diff --git a/plugins/org.eclipse.wst.html.search.editor/.classpath b/plugins/org.eclipse.wst.html.search.editor/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/plugins/org.eclipse.wst.html.search.editor/.project b/plugins/org.eclipse.wst.html.search.editor/.project
new file mode 100644
index 0000000..d39c587
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.wst.html.search.editor</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/plugins/org.eclipse.wst.html.search.editor/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.html.search.editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2217aed
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon Jul 04 14:28:17 CEST 2011

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

+org.eclipse.jdt.core.compiler.compliance=1.5

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.5

diff --git a/plugins/org.eclipse.wst.html.search.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.html.search.editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..63d8ab2
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Editor
+Bundle-SymbolicName: org.eclipse.wst.html.search.editor;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.html.search.editor.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.wst.xml.search.editor;bundle-version="1.0.0",
+ org.eclipse.wst.html.ui,
+ org.eclipse.wst.xml.ui,
+ org.eclipse.wst.sse.ui,
+ org.eclipse.wst.sse.core,
+ org.eclipse.wst.xml.core,
+ org.eclipse.jface.text
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.wst.html.search.editor/build.properties b/plugins/org.eclipse.wst.html.search.editor/build.properties
new file mode 100644
index 0000000..41eb6ad
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/build.properties
@@ -0,0 +1,4 @@
+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .

diff --git a/plugins/org.eclipse.wst.html.search.editor/plugin.xml b/plugins/org.eclipse.wst.html.search.editor/plugin.xml
new file mode 100644
index 0000000..88850b4
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/plugin.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.4"?>

+<plugin>		

+

+	<extension point="org.eclipse.wst.sse.ui.completionProposal">

+		<proposalCategory

+				icon="search.png"

+				id="org.eclipse.wst.html.ui.proposalCategory.wtpxmlsearch"

+				name="WTP XML Search - HTML">

+		</proposalCategory>

+		<proposalComputer

+				activate="true"

+				categoryId="org.eclipse.wst.html.ui.proposalCategory.wtpxmlsearch"

+				class="org.eclipse.wst.html.search.editor.internal.contentassist.HTMLReferencesCompletionProposalComputer"

+				id="org.eclipse.wst.html.search.editor.internal.contentassist.HTMLReferencesCompletionProposalComputer">

+			<contentType

+					id="org.eclipse.wst.html.core.htmlsource">

+					<partitionType id="org.eclipse.wst.html.HTML_DEFAULT"></partitionType>

+			</contentType>

+		</proposalComputer>

+	</extension>

+	

+	<extension

+		point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">

+		<hyperlinkDetector

+			class="org.eclipse.wst.xml.search.editor.hyperlink.XMLReferencesHyperlinkDetector"

+			id="org.eclipse.wst.html.search.editor.internal.hyperlink.HTMLReferenceHyperlinkDetector"

+			name="%HTMLSearch_hyperlink"

+			targetId="org.eclipse.wst.html.core.htmlsource">

+		</hyperlinkDetector>

+   </extension>

+	

+   <extension point="org.eclipse.wst.sse.ui.sourcevalidation">

+		<validator

+			scope="partial"

+			class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesValidator"

+			id="org.eclipse.wst.html.search.editor.HTMLSearchValidator">

+			<contentTypeIdentifier id="org.eclipse.wst.html.core.htmlsource">

+				<partitionType id="org.eclipse.wst.html.HTML_DEFAULT">

+				</partitionType>

+			</contentTypeIdentifier>

+		</validator>

+	</extension> 

+		

+</plugin>	

diff --git a/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/Activator.java b/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/Activator.java
new file mode 100644
index 0000000..6acad1b
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/Activator.java
@@ -0,0 +1,50 @@
+package org.eclipse.wst.html.search.editor;

+

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class Activator extends AbstractUIPlugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "org.eclipse.wst.html.search.editor"; //$NON-NLS-1$

+

+	// The shared instance

+	private static Activator plugin;

+	

+	/**

+	 * The constructor

+	 */

+	public Activator() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)

+	 */

+	public void stop(BundleContext context) throws Exception {

+		plugin = null;

+		super.stop(context);

+	}

+

+	/**

+	 * Returns the shared instance

+	 *

+	 * @return the shared instance

+	 */

+	public static Activator getDefault() {

+		return plugin;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/internal/contentassist/HTMLReferencesCompletionProposalComputer.java b/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/internal/contentassist/HTMLReferencesCompletionProposalComputer.java
new file mode 100644
index 0000000..885bade
--- /dev/null
+++ b/plugins/org.eclipse.wst.html.search.editor/src/org/eclipse/wst/html/search/editor/internal/contentassist/HTMLReferencesCompletionProposalComputer.java
@@ -0,0 +1,26 @@
+package org.eclipse.wst.html.search.editor.internal.contentassist;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.wst.html.ui.internal.contentassist.HTMLTemplatesCompletionProposalComputer;

+import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;

+import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.contentassist.XMLReferencesContentAssistUtils;

+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;

+

+public class HTMLReferencesCompletionProposalComputer extends HTMLTemplatesCompletionProposalComputer {

+

+	@Override

+	protected void addAttributeValueProposals(

+			ContentAssistRequest contentAssistRequest,

+			CompletionProposalInvocationContext context) {

+		// XML reference

+		XMLReferencesContentAssistUtils.addAttributeValueProposals(contentAssistRequest);

+		super.addAttributeValueProposals(contentAssistRequest, context);

+	}

+	

+	

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/.classpath b/plugins/org.eclipse.wst.xml.search.core/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/plugins/org.eclipse.wst.xml.search.core/.project b/plugins/org.eclipse.wst.xml.search.core/.project
new file mode 100644
index 0000000..0e4bc05
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.wst.xml.search.core</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/plugins/org.eclipse.wst.xml.search.core/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.xml.search.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..12ceb96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Thu Nov 18 10:20:11 CET 2010

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

+org.eclipse.jdt.core.compiler.compliance=1.5

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.5

diff --git a/plugins/org.eclipse.wst.xml.search.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.xml.search.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..aeaf235
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/META-INF/MANIFEST.MF
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.core;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.wst.xml.core,
+ org.eclipse.core.resources,
+ org.eclipse.wst.sse.core
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.wst.xml.search.core,
+ org.eclipse.wst.xml.search.core.namespaces,
+ org.eclipse.wst.xml.search.core.properties,
+ org.eclipse.wst.xml.search.core.queryspecifications,
+ org.eclipse.wst.xml.search.core.queryspecifications.container,
+ org.eclipse.wst.xml.search.core.queryspecifications.querybuilder,
+ org.eclipse.wst.xml.search.core.queryspecifications.requestor,
+ org.eclipse.wst.xml.search.core.queryspecifications.visitor,
+ org.eclipse.wst.xml.search.core.reporter,
+ org.eclipse.wst.xml.search.core.resource,
+ org.eclipse.wst.xml.search.core.statics,
+ org.eclipse.wst.xml.search.core.storage,
+ org.eclipse.wst.xml.search.core.util,
+ org.eclipse.wst.xml.search.core.xpath,
+ org.eclipse.wst.xml.search.core.xpath.matcher
diff --git a/plugins/org.eclipse.wst.xml.search.core/build.properties b/plugins/org.eclipse.wst.xml.search.core/build.properties
new file mode 100644
index 0000000..73a5119
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/build.properties
@@ -0,0 +1,6 @@
+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .,\

+               plugin.properties,\

+               plugin.xml

diff --git a/plugins/org.eclipse.wst.xml.search.core/plugin.properties b/plugins/org.eclipse.wst.xml.search.core/plugin.properties
new file mode 100644
index 0000000..46cf46f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/plugin.properties
@@ -0,0 +1,23 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+pluginName=WST XML Search Core

+providerName=Angelo ZERR

+

+# Extension Point

+propertiesQuerySpecificationsContributionName=Properties file Query specifications contribution.

+querySpecificationsContributionName=XML Query specifications contribution.

+resourceQuerySpecificationsContributionName=Resource (file, folder) Query specifications contribution.

+staticValueQuerySpecificationsContributionName=Static value Query specifications contribution.

+xpathEvaluatorsContributionName=XPath evaluators Contribution.

+namespacesContributionName=Namespaces contribution.

+

+# XPath processor

+standardXPathProcessor=Standard XPath processor (XPathFactory.newInstance())
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.core/plugin.xml b/plugins/org.eclipse.wst.xml.search.core/plugin.xml
new file mode 100644
index 0000000..012af4c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.4"?>

+<plugin>

+		

+	<extension-point id="querySpecifications" name="%querySpecificationsContributionName"

+		schema="schema/querySpecifications.exsd" />		

+	<extension-point id="propertiesQuerySpecifications" name="%propertiesQuerySpecificationsContributionName"

+		schema="schema/propertiesQuerySpecifications.exsd" />	

+	<extension-point id="resourceQuerySpecifications" name="%resourceQuerySpecificationsContributionName"

+		schema="schema/resourceQuerySpecifications.exsd" />	

+	<extension-point id="staticValueQuerySpecifications" name="%staticValueQuerySpecificationsContributionName"

+		schema="schema/staticValueQuerySpecifications.exsd" />		                            			       

+	<extension-point id="xpathProcessors" name="%xpathProcessorsContributionName"

+		schema="schema/xpathProcessors.exsd" />

+	<extension-point id="namespaces" name="%namespacesContributionName"

+		schema="schema/namespaces.exsd" />

+				

+	<extension

+	      point="org.eclipse.wst.xml.search.core.xpathProcessors">

+	    <processor

+	          class="org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor"

+	          id="org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor"

+	          name="%standardXPathProcessor">

+	    </processor>

+	</extension>

+	

+	<extension point="org.eclipse.core.runtime.preferences">

+		<initializer

+			class="org.eclipse.wst.xml.search.core.internal.preferences.PreferenceInitializer" />

+	</extension>

+	

+</plugin>

diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/namespaces.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/namespaces.exsd
new file mode 100644
index 0000000..0c35a7b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/namespaces.exsd
@@ -0,0 +1,105 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.core" id="namespaces" name="XML Namespaces Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML Namespaces.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="namespaces" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="namespaces">

+      <complexType>

+         <sequence>

+            <element ref="matcher" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="matcher">

+      <complexType>

+         <attribute name="prefix" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.core.namespaces.INamespaceMatcher"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/propertiesQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/propertiesQuerySpecifications.exsd
new file mode 100644
index 0000000..c53848e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/propertiesQuerySpecifications.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.core" id="propertiesQuerySpecifications" name="Propertiess Query specification Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide Properties file Query specification.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="querySpecification">

+      <complexType>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/querySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/querySpecifications.exsd
new file mode 100644
index 0000000..71d0b83
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/querySpecifications.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.core" id="querySpecifications" name="XML Query specification Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML Query specification.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="querySpecification">

+      <complexType>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/resourceQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/resourceQuerySpecifications.exsd
new file mode 100644
index 0000000..950680e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/resourceQuerySpecifications.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.core" id="resourceQuerySpecifications" name="Resources Query specification Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide Resource (file, folder...) Query specification.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="querySpecification">

+      <complexType>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/staticValueQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/staticValueQuerySpecifications.exsd
new file mode 100644
index 0000000..0b7fe58
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/staticValueQuerySpecifications.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.core" id="staticValueQuerySpecifications" name="Static value Query specification Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide Static value Query specification.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="querySpecification">

+      <complexType>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.core/schema/xpathProcessors.exsd b/plugins/org.eclipse.wst.xml.search.core/schema/xpathProcessors.exsd
new file mode 100644
index 0000000..e1c5a6b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/schema/xpathProcessors.exsd
@@ -0,0 +1,97 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.core" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.core" id="xpathProcessors" name="XPath processors Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XPath processor.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="processor" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="processor">

+      <complexType>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.core.xpath.IXPathProcessor"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/AbstractRegistryManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/AbstractRegistryManager.java
new file mode 100644
index 0000000..3bdb3ae
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/AbstractRegistryManager.java
@@ -0,0 +1,62 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core;

+

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.IRegistryChangeEvent;

+import org.eclipse.core.runtime.IRegistryChangeListener;

+import org.eclipse.core.runtime.Platform;

+

+/**

+ * Abstract class of the registry managed which is used to register WTP/XML

+ * Search configuration (querySPecification...) with Extension Point.

+ * 

+ */

+public abstract class AbstractRegistryManager implements

+		IRegistryChangeListener {

+

+	private boolean registryListenerIntialized = false;

+

+	public void initialize() {

+

+	}

+

+	public void destroy() {

+		Platform.getExtensionRegistry().removeRegistryChangeListener(this);

+	}

+

+	protected void addRegistryListenerIfNeeded() {

+		if (registryListenerIntialized)

+			return;

+

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			registry.addRegistryChangeListener(this, getPluginId());

+		}

+		registryListenerIntialized = true;

+	}

+

+	public void registryChanged(IRegistryChangeEvent event) {

+		IExtensionDelta[] deltas = event.getExtensionDeltas(getPluginId(),

+				getExtensionPoint());

+		if (deltas != null) {

+			for (IExtensionDelta delta : deltas)

+				handleExtensionDelta(delta);

+		}

+	}

+

+	protected abstract void handleExtensionDelta(IExtensionDelta delta);

+

+	protected abstract String getPluginId();

+

+	protected abstract String getExtensionPoint();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IQueryProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IQueryProvider.java
new file mode 100644
index 0000000..2862cda
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IQueryProvider.java
@@ -0,0 +1,12 @@
+package org.eclipse.wst.xml.search.core;

+

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;

+

+public interface IQueryProvider {

+

+	String getQuery(Object selectedNode, IStringQueryBuilder builder,

+			String[] values, Namespaces namespaces, IDOMDocument document);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/ISimpleXMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/ISimpleXMLSearchEngine.java
new file mode 100644
index 0000000..31d9492
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/ISimpleXMLSearchEngine.java
@@ -0,0 +1,47 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;

+

+public interface ISimpleXMLSearchEngine {

+

+	IStatus search(IResource container, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor);

+

+	IStatus search(IResource[] containers, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor);

+

+	IStatus search(IStorage storage, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor);

+

+	IStatus search(IStorage[] storages, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchDOMNodeCollector.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchDOMNodeCollector.java
new file mode 100644
index 0000000..4c72152
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchDOMNodeCollector.java
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+/**

+ * A collector to add DOM node {@link IDOMNode} retrieved by the XML search

+ * engine.

+ * 

+ */

+public interface IXMLSearchDOMNodeCollector {

+

+	/**

+	 * Appends the specified node.

+	 * 

+	 * @param node the node to add.

+	 * @return

+	 */

+	boolean add(IDOMNode node);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchEngine.java
new file mode 100644
index 0000000..d4d804b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/IXMLSearchEngine.java
@@ -0,0 +1,27 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core;

+

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;

+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;

+

+/**

+ * XML search engine interface.

+ * 

+ */

+public interface IXMLSearchEngine extends ISimpleXMLSearchEngine {

+

+	IStatus search(IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			IXMLSearchDOMNodeCollector collector, IXMLSearchReporter reporter,

+			IProgressMonitor monitor);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/SimpleXMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/SimpleXMLSearchEngine.java
new file mode 100644
index 0000000..056aa01
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/SimpleXMLSearchEngine.java
@@ -0,0 +1,237 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.MultiStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.wst.xml.search.core.internal.AbstractXMLSearchEngine;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.internal.reporter.XMLSearchReporterIdProvider;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;

+

+public class SimpleXMLSearchEngine extends AbstractXMLSearchEngine {

+

+	private static final ISimpleXMLSearchEngine INSTANCE = new SimpleXMLSearchEngine();

+

+	public static ISimpleXMLSearchEngine getDefault() {

+		return INSTANCE;

+	}

+

+	public IStatus search(IResource container, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor) {

+		long startTime = -1;

+		int searchId = -1;

+		if (isReporterEnabled(reporter)) {

+			searchId = XMLSearchReporterIdProvider.getSearchId();

+			startTime = System.currentTimeMillis();

+			Collection<String> queries = new ArrayList<String>();

+			queries.add(query);

+			Map<IResource, Collection<String>> containersReporter = new HashMap<IResource, Collection<String>>();

+			containersReporter.put(container, queries);

+			reporter.beginSearch(searchId, containersReporter);

+		}

+		MultiStatus status = createStatus();

+		try {

+			search(container, container, requestor, visitor, query,

+					xpathEvaluatorId, namespaceInfos, collector, selectedNode,

+					monitor, status);

+		} finally {

+			if (searchId != -1) {

+				reporter.endSearch(searchId, System.currentTimeMillis()

+						- startTime);

+			}

+		}

+		return status;

+	}

+

+	public IStatus search(IResource[] containers,

+			IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor) {

+		long startTime = -1;

+		int searchId = -1;

+		if (isReporterEnabled(reporter)) {

+			searchId = XMLSearchReporterIdProvider.getSearchId();

+			startTime = System.currentTimeMillis();

+			Map<IResource, Collection<String>> containersReporter = new HashMap<IResource, Collection<String>>();

+			if (containers != null) {

+				Collection<String> queries = new ArrayList<String>();

+				queries.add(query);

+				for (int i = 0; i < containers.length; i++) {

+					containersReporter.put(containers[i], queries);

+				}

+			}

+			reporter.beginSearch(searchId, containersReporter);

+		}

+		MultiStatus status = createStatus();

+		try {

+			if (containers == null) {

+				return Status.CANCEL_STATUS;

+			}

+

+			IResource container = null;

+			for (int i = 0; i < containers.length; i++) {

+				container = containers[i];

+				search(container, container, requestor, visitor, query,

+						xpathEvaluatorId, namespaceInfos, collector,

+						selectedNode, monitor, status);

+			}

+		} finally {

+			if (searchId != -1) {

+				reporter.endSearch(searchId, System.currentTimeMillis()

+						- startTime);

+			}

+		}

+		return status;

+	}

+

+	private void search(IResource resource, IResource rootResource,

+			IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IProgressMonitor monitor, MultiStatus status) {

+		if (acceptResource(resource, rootResource, requestor)) {

+			int resourceType = resource.getType();

+			switch (resourceType) {

+			case IResource.FILE:

+				IFile file = (IFile) resource;

+				processFile(file, rootResource, requestor, visitor, query,

+						xpathEvaluatorId, namespaceInfos, collector,

+						selectedNode, status);

+				break;

+			case IResource.ROOT:

+			case IResource.PROJECT:

+			case IResource.FOLDER:

+				try {

+					IResource[] resources = ((IContainer) resource).members();

+					search(resources, rootResource, requestor, visitor, query,

+							xpathEvaluatorId, namespaceInfos, collector,

+							selectedNode, monitor, status);

+				} catch (CoreException e) {

+					// Error while loop for files

+					status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR,

+							e.getMessage(), e));

+				}

+				break;

+			}

+		}

+	}

+

+	private void search(IResource[] resources, IResource rootResource,

+			IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IProgressMonitor monitor, MultiStatus status) {

+		for (int i = 0; i < resources.length; i++) {

+			search(resources[i], rootResource, requestor, visitor, query,

+					xpathEvaluatorId, namespaceInfos, collector, selectedNode,

+					monitor, status);

+		}

+	}

+

+	public IStatus search(IStorage storage, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor) {

+		long startTime = -1;

+		int searchId = -1;

+		if (isReporterEnabled(reporter)) {

+			searchId = XMLSearchReporterIdProvider.getSearchId();

+			startTime = System.currentTimeMillis();

+

+		}

+		MultiStatus status = createStatus();

+		try {

+			if (storage == null) {

+				return Status.CANCEL_STATUS;

+			}

+			super.processStorage(storage, storage, requestor, visitor, query,

+					xpathEvaluatorId, namespaceInfos, collector, selectedNode,

+					status);

+

+		} finally {

+			if (searchId != -1) {

+				reporter.endSearch(searchId, System.currentTimeMillis()

+						- startTime);

+			}

+		}

+		return status;

+	}

+

+	private void search(IStorage storage, IStorage rootStorage,

+			IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IProgressMonitor monitor, MultiStatus status) {

+		super.processStorage(storage, rootStorage, requestor, visitor, query,

+				xpathEvaluatorId, namespaceInfos, collector, selectedNode,

+				status);

+

+	}

+

+	public IStatus search(IStorage[] storages, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor) {

+		long startTime = -1;

+		int searchId = -1;

+		if (isReporterEnabled(reporter)) {

+			searchId = XMLSearchReporterIdProvider.getSearchId();

+			startTime = System.currentTimeMillis();

+

+		}

+		MultiStatus status = createStatus();

+		try {

+			if (storages == null) {

+				return Status.CANCEL_STATUS;

+			}

+

+			IStorage storage = null;

+			for (int i = 0; i < storages.length; i++) {

+				storage = storages[i];

+				super.processStorage(storage, storage, requestor, visitor,

+						query, xpathEvaluatorId, namespaceInfos, collector,

+						selectedNode, status);

+			}

+		} finally {

+			if (searchId != -1) {

+				reporter.endSearch(searchId, System.currentTimeMillis()

+						- startTime);

+			}

+		}

+		return status;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine.java
new file mode 100644
index 0000000..f8d9ef5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine.java
@@ -0,0 +1,263 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.Set;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.MultiStatus;

+import org.eclipse.wst.xml.search.core.internal.AbstractXMLSearchEngine;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.internal.queryspecifications.XMLQuerySpecification2;

+import org.eclipse.wst.xml.search.core.internal.reporter.XMLSearchReporterIdProvider;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.IExecutableXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;

+import org.eclipse.wst.xml.search.core.queryspecifications.XMLQuerySpecificationRegistry;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllFilesXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;

+

+public class XMLSearchEngine extends AbstractXMLSearchEngine implements

+		IXMLSearchEngine {

+

+	private static final XMLSearchEngine INSTANCE = new XMLSearchEngine();

+

+	public static IXMLSearchEngine getDefault() {

+		return INSTANCE;

+	}

+

+	protected void search(IFile[] files, IXMLSearchDOMDocumentVisitor visitor,

+			String query, String xpathEvaluatorId,

+			Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IProgressMonitor monitor, MultiStatus status) {

+		IFile file = null;

+		for (int i = 0; i < files.length; i++) {

+			file = files[i];

+			processFile(file, file, AllFilesXMLSearchRequestor.INSTANCE,

+					visitor, query, xpathEvaluatorId, namespaceInfos,

+					collector, selectedNode, status);

+		}

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.IXMLSearchEngine#search(org.eclipse.wst

+	 * .xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry,

+	 * org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector,

+	 * org.eclipse.core.runtime.IProgressMonitor)

+	 */

+	public IStatus search(

+			IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			IXMLSearchDOMNodeCollector collector, IXMLSearchReporter reporter,

+			IProgressMonitor monitor) {

+		long startTime = -1;

+		int searchId = -1;

+		if (isReporterEnabled(reporter)) {

+			searchId = XMLSearchReporterIdProvider.getSearchId();

+			startTime = System.currentTimeMillis();

+

+			Map<IResource, Collection<String>> containersReporter = new HashMap<IResource, Collection<String>>();

+			Set<Entry<IResource, Collection<IExecutableXMLQuerySpecification>>> entries = querySpecificationRegistry

+					.getQuerySpecificationsMap().entrySet();

+			for (Entry<IResource, Collection<IExecutableXMLQuerySpecification>> entry : entries) {

+				IResource container = entry.getKey();

+				Collection<String> queries = new ArrayList<String>();

+				Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications = entry

+						.getValue();

+				for (IExecutableXMLQuerySpecification executableXMLQuerySpecification : executableXMLQuerySpecifications) {

+					queries.add(executableXMLQuerySpecification.getQuery());

+				}

+				containersReporter.put(container, queries);

+			}

+			reporter.beginSearch(searchId, containersReporter);

+		}

+		MultiStatus status = createStatus();

+		try {

+			search(querySpecificationRegistry, collector, monitor, status);

+		} finally {

+			if (searchId != -1) {

+				reporter.endSearch(searchId, System.currentTimeMillis()

+						- startTime);

+			}

+		}

+		return status;

+	}

+

+	protected void search(

+			IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			IXMLSearchDOMNodeCollector collector, IProgressMonitor monitor,

+			MultiStatus status) {

+		Set<Entry<IResource, Collection<IExecutableXMLQuerySpecification>>> entries = querySpecificationRegistry

+				.getQuerySpecificationsMap().entrySet();

+		for (Entry<IResource, Collection<IExecutableXMLQuerySpecification>> entry : entries) {

+			IResource container = entry.getKey();

+			Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications = entry

+					.getValue();

+			search(container, container, executableXMLQuerySpecifications,

+					collector, status);

+		}

+	}

+

+	protected void search(

+			IResource resource,

+			IResource rootResource,

+			Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications,

+			IXMLSearchDOMNodeCollector collector, MultiStatus status) {

+		if (acceptResource(resource, rootResource,

+				executableXMLQuerySpecifications)) {

+			int resourceType = resource.getType();

+			switch (resourceType) {

+			case IResource.FILE:

+				IFile file = (IFile) resource;

+				processFile(file, rootResource,

+						executableXMLQuerySpecifications, collector, status);

+				break;

+			case IResource.ROOT:

+			case IResource.PROJECT:

+			case IResource.FOLDER:

+				try {

+					IResource[] resources = ((IContainer) resource).members();

+					search(resources, rootResource,

+							executableXMLQuerySpecifications, collector, status);

+				} catch (CoreException e) {

+					// Error while loop for files

+					status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR,

+							e.getMessage(), e));

+				}

+				break;

+			}

+		}

+	}

+

+	private void search(

+			IResource[] resources,

+			IResource rootResource,

+			Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications,

+			IXMLSearchDOMNodeCollector collector, MultiStatus status) {

+		for (int i = 0; i < resources.length; i++) {

+			search(resources[i], rootResource,

+					executableXMLQuerySpecifications, collector, status);

+		}

+	}

+

+	private boolean acceptResource(

+			IResource resource,

+			IResource rootResource,

+			Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications) {

+		if (resource == null) {

+			return false;

+		}

+		for (IExecutableXMLQuerySpecification executableXMLQuerySpecification : executableXMLQuerySpecifications) {

+			if (acceptResource(resource, rootResource,

+					executableXMLQuerySpecification)) {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	private boolean acceptResource(IResource resource, IResource rootResource,

+			IExecutableXMLQuerySpecification executableXMLQuerySpecification) {

+		IXMLSearchRequestor requestor = executableXMLQuerySpecification

+				.getRequestor();

+		return requestor != null && requestor.accept(resource, rootResource);

+	}

+

+	protected void processFile(

+			IFile file,

+			IResource rootResource,

+			Collection<IExecutableXMLQuerySpecification> executableXMLQuerySpecifications,

+			IXMLSearchDOMNodeCollector collector, MultiStatus status) {

+		for (IExecutableXMLQuerySpecification executableXMLQuerySpecification : executableXMLQuerySpecifications) {

+			if (acceptResource(file, rootResource,

+					executableXMLQuerySpecification)) {

+				super.processFile(file, rootResource,

+						executableXMLQuerySpecification.getRequestor(),

+						executableXMLQuerySpecification.getVisitor(),

+						executableXMLQuerySpecification.getQuery(),

+						executableXMLQuerySpecification.getXPathProcessorId(),

+						executableXMLQuerySpecification.getNamespaces(),

+						collector,

+						executableXMLQuerySpecification.getSelectedNode(),

+						status);

+			}

+		}

+	}

+

+	public IStatus search(IResource container, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathProcessorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor) {

+		XMLQuerySpecificationRegistry querySpecificationRegistry = new XMLQuerySpecificationRegistry(

+				container, selectedNode);

+		XMLQuerySpecification2 specification = XMLQuerySpecification2

+				.newDefaultQuerySpecification(container);

+		specification.setVisitor(visitor);

+		specification.setRequestor(requestor);

+		specification.setXPathProcessorId(xpathProcessorId);

+		querySpecificationRegistry.register(specification, query,

+				namespaceInfos);

+		return search(querySpecificationRegistry, collector, reporter, monitor);

+	}

+

+	public IStatus search(IResource[] containers,

+			IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathProcessorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor) {

+		XMLQuerySpecificationRegistry querySpecificationRegistry = new XMLQuerySpecificationRegistry(

+				(IContainer) null, selectedNode);

+		XMLQuerySpecification2 specification = XMLQuerySpecification2

+				.newDefaultQuerySpecification(containers);

+		specification.setVisitor(visitor);

+		specification.setRequestor(requestor);

+		specification.setXPathProcessorId(xpathProcessorId);

+		querySpecificationRegistry.register(specification, query,

+				namespaceInfos);

+		return search(querySpecificationRegistry, collector, reporter, monitor);

+	}

+

+	public IStatus search(IStorage storage, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor) {

+		// TODO Auto-generated method stub

+		return null;

+	}

+

+	public IStatus search(IStorage[] storages, IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IXMLSearchReporter reporter, IProgressMonitor monitor) {

+		// TODO Auto-generated method stub

+		return null;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine2.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine2.java
new file mode 100644
index 0000000..901ff85
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngine2.java
@@ -0,0 +1,155 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core;

+

+import java.util.Collection;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.MultiStatus;

+import org.eclipse.core.runtime.OperationCanceledException;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.core.runtime.jobs.Job;

+import org.eclipse.osgi.util.NLS;

+import org.eclipse.wst.xml.search.core.internal.FilesOfScopeCalculator;

+import org.eclipse.wst.xml.search.core.internal.Messages;

+import org.eclipse.wst.xml.search.core.queryspecifications.IExecutableXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;

+

+public class XMLSearchEngine2 extends XMLSearchEngine {

+

+	private int fNumberOfFilesToScan;

+	private IFile fCurrentFile;

+	private int fNumberOfScannedFiles;

+

+	@Override

+	protected void search(

+			IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			IXMLSearchDOMNodeCollector collector,

+			final IProgressMonitor monitor, MultiStatus status) {

+

+		IFile[] files = evaluateFilesInScope(querySpecificationRegistry, status);

+		if (files == null) {

+			return;

+		}

+		fNumberOfScannedFiles = 0;

+		fNumberOfFilesToScan = files.length;

+		fCurrentFile = null;

+

+		Job monitorUpdateJob = new Job(

+				Messages.XMLSearchEngine2_progress_updating_job) {

+			private int fLastNumberOfScannedFiles = 0;

+

+			public IStatus run(IProgressMonitor inner) {

+				while (!inner.isCanceled()) {

+					IFile file = fCurrentFile;

+					if (file != null) {

+						String fileName = file.getName();

+						Object[] args = { fileName,

+								new Integer(fNumberOfScannedFiles),

+								new Integer(fNumberOfFilesToScan) };

+						monitor.subTask(NLS.bind(

+								Messages.XMLSearchEngine2_scanning, args));

+						int steps = fNumberOfScannedFiles

+								- fLastNumberOfScannedFiles;

+						monitor.worked(steps);

+						fLastNumberOfScannedFiles += steps;

+					}

+					try {

+						Thread.sleep(100);

+					} catch (InterruptedException e) {

+						return Status.OK_STATUS;

+					}

+				}

+				return Status.OK_STATUS;

+			}

+		};

+

+		try {

+			String taskName = NLS.bind(

+					Messages.XMLSearchEngine2_textsearch_task_label,

+					querySpecificationRegistry.getQueriesLabel());

+			// SearchMessages.TextSearchVisitor_filesearch_task_label

+			// :

+			// Messages.format(SearchMessages.TextSearchVisitor_textsearch_task_label,

+			// fMatcher.pattern().pattern());

+			monitor.beginTask(taskName, fNumberOfFilesToScan);

+			monitorUpdateJob.setSystem(true);

+			monitorUpdateJob.schedule();

+			try {

+				// fCollector.beginReporting();

+				// processFiles(files);

+				// return fStatus;

+				processFiles(files, null, querySpecificationRegistry,

+						collector, monitor, status);

+			} finally {

+				monitorUpdateJob.cancel();

+			}

+		} finally {

+			monitor.done();

+			// fCollector.endReporting();

+		}

+

+	}

+

+	private void processFiles(IFile[] files, IResource rootResource,

+			IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			IXMLSearchDOMNodeCollector collector, IProgressMonitor monitor,

+			MultiStatus status) {

+		for (int i = 0; i < files.length; i++) {

+			fCurrentFile = files[i];

+			boolean res = processFile(fCurrentFile, rootResource,

+					querySpecificationRegistry, collector, monitor, status);

+			if (!res)

+				break;

+		}

+

+	}

+

+	private boolean processFile(IFile file, IResource rootResource,

+			IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			IXMLSearchDOMNodeCollector collector, IProgressMonitor monitor,

+			MultiStatus status) {

+

+		try {

+			Collection<Collection<IExecutableXMLQuerySpecification>> all = querySpecificationRegistry

+					.getQuerySpecificationsMap().values();

+			for (Collection<IExecutableXMLQuerySpecification> collection : all) {

+				super.processFile(file, rootResource, collection, collector,

+						status);

+			}

+		} finally {

+			fNumberOfScannedFiles++;

+		}

+		if (monitor.isCanceled())

+			throw new OperationCanceledException(

+					Messages.XMLSearchEngine2_canceled);

+		return true;

+	}

+

+	/**

+	 * Evaluates all files in this scope.

+	 * 

+	 * @param status

+	 *            a {@link MultiStatus} to collect the error status that

+	 *            occurred while collecting resources.

+	 * @return returns the files in the scope.

+	 */

+	protected IFile[] evaluateFilesInScope(

+			IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			MultiStatus status) {

+		return new FilesOfScopeCalculator(querySpecificationRegistry, status)

+				.process();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngineException.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngineException.java
new file mode 100644
index 0000000..982406f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/XMLSearchEngineException.java
@@ -0,0 +1,19 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core;

+

+public class XMLSearchEngineException extends RuntimeException {

+

+	public XMLSearchEngineException(Throwable e) {

+		super(e);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/AbstractXMLSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/AbstractXMLSearchEngine.java
new file mode 100644
index 0000000..784b49d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/AbstractXMLSearchEngine.java
@@ -0,0 +1,319 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.MultiStatus;

+import org.eclipse.osgi.util.NLS;

+import org.eclipse.wst.sse.core.StructuredModelManager;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;

+import org.eclipse.wst.xml.search.core.ISimpleXMLSearchEngine;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllFilesXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;

+import org.eclipse.wst.xml.search.core.storage.StructuredStorageModelManager;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+

+/**

+ * 

+ * Abstract class for XML Search engine which implements

+ * {@link ISimpleXMLSearchEngine}.

+ * 

+ */

+public abstract class AbstractXMLSearchEngine implements ISimpleXMLSearchEngine {

+

+	/**

+	 * Returns true if reporter is enabled and false otherwise.

+	 * 

+	 * @param reporter

+	 *            the XML reporter or null otherwise.

+	 * @return

+	 */

+	protected boolean isReporterEnabled(IXMLSearchReporter reporter) {

+		return reporter != null && reporter.isEnabled();

+	}

+

+	/**

+	 * Returns true if the given <code>resource</code> must be accepted and

+	 * false Otherwise.

+	 * 

+	 * @param resource

+	 * @param rootResource

+	 * @param requestor

+	 * @return

+	 */

+	protected boolean acceptResource(IResource resource,

+			IResource rootResource, IXMLSearchRequestor requestor) {

+		return requestor == null ? false : requestor.accept(resource,

+				rootResource);

+	}

+

+	/**

+	 * Process search DOM nodes in the given <code>file</code>.

+	 * 

+	 * @param file

+	 *            used to process the search.

+	 * @param rootResource

+	 *            the root resources where search is started.

+	 * @param requestor

+	 *            used to know if search must be done for the given file.

+	 * @param visitor

+	 *            used to execute XPath query for the current file which is a

+	 *            DOM Document.

+	 * @param query

+	 *            the XPath to execute.

+	 * @param xpathProcessorId

+	 *            the XPath processor id to use to execute XPath.

+	 * @param namespaceInfos

+	 *            namespace infos used by the XPath processor to execute the

+	 *            given XPath query.

+	 * @param collector

+	 *            the collector used to collect DOM Node.

+	 * @param selectedNode

+	 *            the selected node which start the search.

+	 * @return the status of the search.

+	 */

+	protected void processFile(IFile file, IResource rootResource,

+			IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathProcessorId, Namespaces namespaces,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			MultiStatus status) {

+		if (acceptResource(file, rootResource, requestor)) {

+			boolean hasError = false;

+			// boolean releaseModelForRead = false;

+			// Load DOM Document

+			IStructuredModel model = null;

+			try {

+				// releaseModelForRead = false;

+				model = StructuredModelManager.getModelManager()

+						.getExistingModelForRead(file);

+				if (model == null) {

+					model = StructuredModelManager.getModelManager()

+							.getModelForRead(file);

+					// releaseModelForRead = true;

+				}

+			} catch (Throwable e) {

+				hasError = true;

+				status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR,

+						e.getMessage(), e));

+			}

+

+			IDOMModel domModel = null;

+			if (model instanceof IDOMModel) {

+				domModel = (IDOMModel) model;

+			}

+			if (!hasError && domModel != null && requestor.accept(domModel)) {

+				// DOM Model was loaded, visit the DOM Document

+				try {

+					process(visitor, query, xpathProcessorId, namespaces,

+							collector, selectedNode, model, domModel);

+				} catch (Throwable e) {

+					// Error while visting DOM Document

+					status.add(XMLSearchCorePlugin.createStatus(

+							IStatus.ERROR,

+							NLS.bind(

+									Messages.searchEngineDOMDocumentVisitedError,

+									file.getLocation().toString()), e));

+				} finally {

+					if (model != null /* && releaseModelForRead */) {

+						model.releaseFromRead();

+					}

+				}

+			}

+		}

+	}

+

+	/**

+	 * Process search DOM nodes in the given <code>storage</code>.

+	 * 

+	 * @param storage

+	 *            used to process the search.

+	 * @param rootStorage

+	 *            the root storage where search is started.

+	 * @param requestor

+	 *            used to know if search must be done for the given file.

+	 * @param visitor

+	 *            used to execute XPath query for the current file which is a

+	 *            DOM Document.

+	 * @param query

+	 *            the XPath to execute.

+	 * @param xpathProcessorId

+	 *            the XPath processor id to use to execute XPath.

+	 * @param namespaceInfos

+	 *            namespace infos used by the XPath processor to execute the

+	 *            given XPath query.

+	 * @param collector

+	 *            the collector used to collect DOM Node.

+	 * @param selectedNode

+	 *            the selected node which start the search.

+	 * @return the status of the search.

+	 */

+	protected void processStorage(IStorage storage, IStorage rootStorage,

+			IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathProcessorId, Namespaces namespaces,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			MultiStatus status) {

+		// if (acceptStorage(storage, rootStorage, requestor)) {

+		boolean hasError = false;

+		// boolean releaseModelForRead = false;

+		// Load DOM Document

+		IStructuredModel model = null;

+		try {

+			// releaseModelForRead = false;

+			model = StructuredStorageModelManager.getModelManager().getModel(

+					storage);

+		} catch (Throwable e) {

+			hasError = true;

+			status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR,

+					e.getMessage(), e));

+		}

+

+		IDOMModel domModel = null;

+		if (model instanceof IDOMModel) {

+			domModel = (IDOMModel) model;

+		}

+		if (!hasError && domModel != null /* && requestor.accept(domModel) */) {

+			// DOM Model was loaded, visit the DOM Document

+			try {

+				process(visitor, query, xpathProcessorId, namespaces,

+						collector, selectedNode, model, domModel);

+			} catch (Throwable e) {

+				// Error while visting DOM Document

+				status.add(XMLSearchCorePlugin.createStatus(IStatus.ERROR, NLS

+						.bind(Messages.searchEngineDOMDocumentVisitedError,

+								storage.getFullPath().toString()), e));

+			} finally {

+				if (model != null /* && releaseModelForRead */) {

+					model.releaseFromRead();

+				}

+			}

+		}

+	}

+

+	private void process(IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathProcessorId, Namespaces namespaces,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IStructuredModel model, IDOMModel domModel) {

+		if (model != null) {

+			IDOMDocument document = domModel.getDocument();

+			if (namespaces != null) {

+				NamespaceInfos namespaceInfos = XPathManager

+						.getManager().getNamespaceInfo(document);

+				query = namespaces.format(query, namespaceInfos);

+			}

+			visitor.visit(document, query, xpathProcessorId, collector,

+					selectedNode);

+		}

+	}

+

+	/**

+	 * Execute the XPath query for the given <code>files</code> and collect

+	 * nodes result in the given <code>collector</code> and return the status of

+	 * the search.

+	 * 

+	 * @param files

+	 *            list of files where the query must be executed to collect DOM

+	 *            nodes (if file is a DOM Document).

+	 * @param visitor

+	 *            used to execute XPath query for the current file which is a

+	 *            DOM Document.

+	 * @param query

+	 *            the XPath to execute.

+	 * @param xpathProcessorId

+	 *            the XPath processor id to use to execute XPath.

+	 * @param namespaceInfos

+	 *            namespace infos used by the XPath processor to execute the

+	 *            given XPath query.

+	 * @param collector

+	 *            the collector used to collect DOM Node.

+	 * @param selectedNode

+	 *            the selected node which start the search.

+	 * @param monitor

+	 *            the progress monitor.

+	 * @return the status of the search.

+	 */

+	public IStatus search(IFile files[], IXMLSearchDOMDocumentVisitor visitor,

+			String query, String xpathProcessorId, Namespaces namespaces,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IProgressMonitor monitor) {

+		// Create status instance

+		MultiStatus status = createStatus();

+		// Execute search

+		search(files, visitor, query, xpathProcessorId, namespaces, collector,

+				selectedNode, monitor, status);

+		// Returns status

+		return status;

+	}

+

+	/**

+	 * Execute the XPath query for the given <code>files</code> and collect

+	 * nodes result in the given <code>collector</code> populate the given

+	 * <code>status</code> of the search.

+	 * 

+	 * @param files

+	 *            list of files where the query must be executed to collect DOM

+	 *            nodes (if file is a DOM Document).

+	 * @param visitor

+	 *            used to execute XPath query for the current file which is a

+	 *            DOM Document.

+	 * @param query

+	 *            the XPath to execute.

+	 * @param xpathProcessorId

+	 *            the XPath processor id to use to execute XPath.

+	 * @param namespaceInfos

+	 *            namespace infos used by the XPath processor to execute the

+	 *            given XPath query.

+	 * @param collector

+	 *            the collector used to collect DOM Node.

+	 * @param selectedNode

+	 *            the selected node which start the search.

+	 * @param monitor

+	 *            the progress monitor.

+	 * @param status

+	 *            the status to populate while searching.

+	 */

+	protected void search(IFile files[], IXMLSearchDOMDocumentVisitor visitor,

+			String query, String xpathProcessorId, Namespaces namespace,

+			IXMLSearchDOMNodeCollector collector, Object selectedNode,

+			IProgressMonitor monitor, MultiStatus status) {

+		IFile file = null;

+		// Loop for files

+		for (int i = 0; i < files.length; i++) {

+			file = files[i];

+			// process search for the current file

+			processFile(file, file, AllFilesXMLSearchRequestor.INSTANCE,

+					visitor, query, xpathProcessorId, namespace, collector,

+					selectedNode, status);

+		}

+	}

+

+	/**

+	 * Create an instance of {@link MultiStatus}.

+	 * 

+	 * @return

+	 */

+	protected MultiStatus createStatus() {

+		return new MultiStatus(XMLSearchCorePlugin.PLUGIN_ID, IStatus.OK,

+				Messages.XMLSearchEngine_statusMessage, null);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/FilesOfScopeCalculator.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/FilesOfScopeCalculator.java
new file mode 100644
index 0000000..d8b4c78
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/FilesOfScopeCalculator.java
@@ -0,0 +1,119 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.List;

+import java.util.Set;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IResourceProxy;

+import org.eclipse.core.resources.IResourceProxyVisitor;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.MultiStatus;

+import org.eclipse.wst.xml.search.core.queryspecifications.IExecutableXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+

+/**

+ * Implementation of {@link IResourceProxyVisitor} to loop for list of

+ * {@link IResource} registered in the {@link IXMLQuerySpecificationRegistry}

+ * registry and visit each files to execute query.

+ * 

+ */

+public class FilesOfScopeCalculator implements IResourceProxyVisitor {

+

+	private final IXMLQuerySpecificationRegistry querySpecificationRegistry;

+	private final MultiStatus fStatus;

+	private List<IFile> fFiles;

+

+	public FilesOfScopeCalculator(

+			IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			MultiStatus status) {

+		this.querySpecificationRegistry = querySpecificationRegistry;

+		fStatus = status;

+	}

+

+	public boolean visit(IResourceProxy proxy) {

+		boolean inScope = isInScope(proxy);

+		if (inScope && proxy.getType() == IResource.FILE) {

+			fFiles.add((IFile) proxy.requestResource());

+		}

+		return inScope;

+	}

+

+	public IFile[] process() {

+		fFiles = new ArrayList<IFile>();

+		try {

+			Set<IResource> containers = querySpecificationRegistry

+					.getQuerySpecificationsMap().keySet();

+			for (IResource resource : containers) {

+				switch (resource.getType()) {

+				case IResource.FILE:

+					resource.accept(this, 0);

+					break;

+				case IResource.ROOT:

+				case IResource.PROJECT:

+				case IResource.FOLDER:

+					IContainer container = (IContainer) resource;

+					IResource[] roots = container.members();

+					for (int i = 0; i < roots.length; i++) {

+						IResource r = roots[i];

+						if (r.isAccessible()) {

+							r.accept(this, 0);

+						}

+					}

+					break;

+				}

+			}

+			return (IFile[]) fFiles.toArray(new IFile[fFiles.size()]);

+		} catch (CoreException ex) {

+			// report and ignore

+			fStatus.add(ex.getStatus());

+

+		} finally {

+			fFiles = null;

+		}

+		return null;

+	}

+

+	private boolean isInScope(IResourceProxy proxy) {

+		Collection<Collection<IExecutableXMLQuerySpecification>> values = querySpecificationRegistry

+				.getQuerySpecificationsMap().values();

+		for (Collection<IExecutableXMLQuerySpecification> collection : values) {

+			if (isInScope(proxy, collection)) {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	private boolean isInScope(IResourceProxy proxy,

+			Collection<IExecutableXMLQuerySpecification> collection) {

+		for (IExecutableXMLQuerySpecification executableXMLQuerySpecification : collection) {

+			if (isInScope(proxy, executableXMLQuerySpecification)) {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	private boolean isInScope(IResourceProxy proxy,

+			IExecutableXMLQuerySpecification executableXMLQuerySpecification) {

+		IXMLSearchRequestor requestor = executableXMLQuerySpecification

+				.getRequestor();

+		return (requestor != null ? requestor.accept(proxy.requestResource(),

+				null) : false);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.java
new file mode 100644
index 0000000..f7a9bdb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal;

+

+import org.eclipse.osgi.util.NLS;

+

+/**

+ * Messages for XML Search Core.

+ * 

+ */

+public class Messages extends NLS {

+

+	public static String searchEngineDOMModelError;

+	public static String searchEngineDOMDocumentVisitedError;

+	public static String searchEngineContainerResourcesError;

+	public static String XMLSearchEngine_statusMessage;

+

+	public static String XMLSearchEngine2_scanning;

+	public static String XMLSearchEngine2_progress_updating_job;

+	public static String XMLSearchEngine2_canceled;

+	public static String XMLSearchEngine2_textsearch_task_label;

+

+	static {

+		NLS.initializeMessages(XMLSearchCorePlugin.PLUGIN_ID

+				+ ".internal.Messages", Messages.class);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.properties b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.properties
new file mode 100644
index 0000000..d1377cf
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Messages.properties
@@ -0,0 +1,21 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+searchEngineDOMModelError=Error while getting DOM Model for file "{0}".

+searchEngineDOMDocumentVisitedError=Error while visit DOM Document for file "{0}".

+searchEngineContainerResourcesError=Error while loop for files from the container "{0}".

+

+# Search engine

+XMLSearchEngine_statusMessage= Problems encountered during XML search.

+

+XMLSearchEngine2_scanning=Scanning file {1} of {2}: {0}

+XMLSearchEngine2_progress_updating_job=Search progress polling

+XMLSearchEngine2_canceled=Operation Canceled

+XMLSearchEngine2_textsearch_task_label=Searching for pattern ''{0}''...
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Trace.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Trace.java
new file mode 100644
index 0000000..0c7622a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/Trace.java
@@ -0,0 +1,99 @@
+/*******************************************************************************

+ * Copyright (c) 2003, 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.search.core.internal;

+

+import java.text.SimpleDateFormat;

+import java.util.Date;

+import java.util.HashSet;

+import java.util.Set;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+

+/**

+ * Helper class to route trace output.

+ */

+public class Trace {

+	public static final byte CONFIG = 0;

+	public static final byte INFO = 1;

+	public static final byte WARNING = 2;

+	public static final byte SEVERE = 3;

+	public static final byte FINEST = 4;

+	public static final byte FINER = 5;

+	public static final byte PERFORMANCE = 6;

+	public static final byte EXTENSION_POINT = 7;

+

+	private static final String[] levelNames = new String[] { "CONFIG ",

+			"INFO   ", "WARNING", "SEVERE ", "FINER  ", "FINEST ", "PERF   ",

+			"EXTENSION" };

+

+	private static final SimpleDateFormat sdf = new SimpleDateFormat(

+			"dd/MM/yy HH:mm.ss.SSS");

+

+	private static Set<String> logged = new HashSet<String>();

+

+	/**

+	 * Trace constructor comment.

+	 */

+	private Trace() {

+		super();

+	}

+

+	/**

+	 * Trace the given text.

+	 * 

+	 * @param level

+	 *            a trace level

+	 * @param s

+	 *            a message

+	 */

+	public static void trace(byte level, String s) {

+		trace(level, s, null);

+	}

+

+	/**

+	 * Trace the given message and exception.

+	 * 

+	 * @param level

+	 *            a trace level

+	 * @param s

+	 *            a message

+	 * @param t

+	 *            a throwable

+	 */

+	public static void trace(byte level, String s, Throwable t) {

+		if (s == null)

+			return;

+

+		if (level == SEVERE) {

+			if (!logged.contains(s)) {

+				XMLSearchCorePlugin.getDefault().getLog().log(

+						new Status(IStatus.ERROR,

+								XMLSearchCorePlugin.PLUGIN_ID, s, t));

+				logged.add(s);

+			}

+		}

+

+		if (!XMLSearchCorePlugin.getDefault().isDebugging())

+			return;

+

+		StringBuilder sb = new StringBuilder(XMLSearchCorePlugin.PLUGIN_ID);

+		sb.append(" ");

+		sb.append(levelNames[level]);

+		sb.append(" ");

+		sb.append(sdf.format(new Date()));

+		sb.append(" ");

+		sb.append(s);

+		System.out.println(sb.toString());

+		if (t != null)

+			t.printStackTrace();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/XMLSearchCorePlugin.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/XMLSearchCorePlugin.java
new file mode 100644
index 0000000..a809002
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/XMLSearchCorePlugin.java
@@ -0,0 +1,91 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Plugin;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.wst.xml.search.core.properties.PropertiesQuerySpecificationManager;

+import org.eclipse.wst.xml.search.core.queryspecifications.XMLQuerySpecificationManager;

+import org.eclipse.wst.xml.search.core.resource.ResourceQuerySpecificationManager;

+import org.eclipse.wst.xml.search.core.statics.StaticValueQuerySpecificationManager;

+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class XMLSearchCorePlugin extends Plugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.core";

+

+	// The shared instance

+	private static XMLSearchCorePlugin plugin;

+

+	/**

+	 * The constructor

+	 */

+	public XMLSearchCorePlugin() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;		

+		XMLQuerySpecificationManager.getDefault().initialize();

+		StaticValueQuerySpecificationManager.getDefault().initialize();

+		ResourceQuerySpecificationManager.getDefault().initialize();

+		PropertiesQuerySpecificationManager.getDefault().initialize();

+		XPathProcessorManager.getDefault().initialize();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void stop(BundleContext context) throws Exception {

+		XMLQuerySpecificationManager.getDefault().destroy();

+		StaticValueQuerySpecificationManager.getDefault().destroy();

+		ResourceQuerySpecificationManager.getDefault().destroy();

+		PropertiesQuerySpecificationManager.getDefault().destroy();

+		XPathProcessorManager.getDefault().destroy();

+		plugin = null;

+		super.stop(context);

+	}

+

+	/**

+	 * Returns the shared instance

+	 * 

+	 * @return the shared instance

+	 */

+	public static XMLSearchCorePlugin getDefault() {

+		return plugin;

+	}

+

+	public static IStatus createStatus(int severity, String message) {

+		return new Status(severity, XMLSearchCorePlugin.PLUGIN_ID, message);

+	}

+

+	public static IStatus createStatus(int severity, String message, Throwable e) {

+		return new Status(severity, XMLSearchCorePlugin.PLUGIN_ID, message, e);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/preferences/PreferenceInitializer.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..64af5b9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/preferences/PreferenceInitializer.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.preferences;

+

+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;

+import org.eclipse.core.runtime.preferences.DefaultScope;

+import org.eclipse.core.runtime.preferences.IEclipsePreferences;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor;

+

+/**

+ * XML Search Core preferences initializer used to initialize the preference of XPath

+ * Preprocessor.

+ * 

+ */

+public class PreferenceInitializer extends AbstractPreferenceInitializer {

+

+	public static final String DEFAULT_XPATH_PROCESSOR = "defaultXPathProcessor";

+

+	@Override

+	public void initializeDefaultPreferences() {

+		IEclipsePreferences node = new DefaultScope()

+				.getNode(XMLSearchCorePlugin.getDefault().getBundle()

+						.getSymbolicName());

+		node.put(DEFAULT_XPATH_PROCESSOR, DefaultXPathProcessor.ID);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/properties/PropertiesQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/properties/PropertiesQuerySpecification.java
new file mode 100644
index 0000000..fdc4d25
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/properties/PropertiesQuerySpecification.java
@@ -0,0 +1,143 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.properties;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.properties.DefaultPropertiesRequestor;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesQuerySpecification;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesRequestor;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesRequestorProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.FolderContainerProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+

+/**

+ * 

+ * {@link IPropertiesQuerySpecification} implementation.

+ * 

+ */

+public class PropertiesQuerySpecification implements

+		IPropertiesQuerySpecification {

+

+	public static final IPropertiesQuerySpecification DEFAULT = newDefaultQuerySpecification();

+

+	private IResourceProvider containerProvider;

+	private IMultiResourceProvider multiContainerProvider;

+	private IPropertiesRequestor requestor;

+

+	protected PropertiesQuerySpecification(IResourceProvider containerProvider,

+			IMultiResourceProvider multiContainerProvider,

+			IPropertiesRequestor requestor) {

+		this.containerProvider = containerProvider;

+		this.multiContainerProvider = multiContainerProvider;

+		this.requestor = requestor;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.container.

+	 * IResourceProvider

+	 * #getResource(org.eclipse.wst.xml.core.internal.provisional

+	 * .document.IDOMNode, org.eclipse.core.resources.IResource)

+	 */

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return containerProvider.getResource(selectedNode, resource);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.properties.IPropertiesRequestorProvider

+	 * #getRequestor()

+	 */

+	public IPropertiesRequestor getRequestor() {

+		return requestor;

+	}

+

+	/**

+	 * Create default properties query specification.

+	 * 

+	 * @return

+	 */

+	public static IPropertiesQuerySpecification newDefaultQuerySpecification() {

+		return new PropertiesQuerySpecification(

+				FolderContainerProvider.INSTANCE, null,

+				DefaultPropertiesRequestor.INSTANCE);

+	}

+

+	/**

+	 * Create properties query specification by using information about the

+	 * given <code>querySpecification</code>.

+	 * 

+	 * @param querySpecification

+	 * @return

+	 */

+	public static IPropertiesQuerySpecification newQuerySpecification(

+			Object querySpecification) {

+		PropertiesQuerySpecification specification = (PropertiesQuerySpecification) newDefaultQuerySpecification();

+		if (querySpecification instanceof IResourceProvider) {

+			// resource provider is customized.

+			specification

+					.setContainerProvider((IResourceProvider) querySpecification);

+		}

+		if (querySpecification instanceof IMultiResourceProvider) {

+			// multi-resource provider is customized.

+			specification

+					.setMultiContainerProvider((IMultiResourceProvider) querySpecification);

+		}

+		if (querySpecification instanceof IPropertiesRequestorProvider) {

+			// requestor provider is customized.

+			specification

+					.setRequestor(((IPropertiesRequestorProvider) querySpecification)

+							.getRequestor());

+		}

+		return specification;

+	}

+

+	private void setMultiContainerProvider(

+			IMultiResourceProvider multiContainerProvider) {

+		this.multiContainerProvider = multiContainerProvider;

+	}

+

+	private void setRequestor(IPropertiesRequestor requestor) {

+		this.requestor = requestor;

+	}

+

+	private void setContainerProvider(IResourceProvider containerProvider) {

+		this.containerProvider = containerProvider;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.properties.IPropertiesQuerySpecification

+	 * #isMultiResource()

+	 */

+	public boolean isMultiResource() {

+		return multiContainerProvider != null;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.container.

+	 * IMultiResourceProvider

+	 * #getResources(org.eclipse.wst.xml.core.internal.provisional

+	 * .document.IDOMNode, org.eclipse.core.resources.IResource)

+	 */

+	public IResource[] getResources(Object selectedNode, IResource resource) {

+		return multiContainerProvider.getResources(selectedNode, resource);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/ExecutableXMLQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/ExecutableXMLQuerySpecification.java
new file mode 100644
index 0000000..f01ed96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/ExecutableXMLQuerySpecification.java
@@ -0,0 +1,207 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.queryspecifications;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.IExecutableXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+

+/**

+ * 

+ * Implementation of {@link IExecutableXMLQuerySpecification}.

+ * 

+ */

+public class ExecutableXMLQuerySpecification implements

+		IExecutableXMLQuerySpecification {

+

+	private final IXMLQuerySpecificationRegistry registry;

+	private final IXMLQuerySpecification querySpecification;

+	private final String query;

+	private final Namespaces namespaceInfos;

+

+	public ExecutableXMLQuerySpecification(

+			IXMLQuerySpecificationRegistry registry,

+			IXMLQuerySpecification querySpecification, String query,

+			Namespaces namespaceInfos) {

+		this.registry = registry;

+		this.querySpecification = querySpecification;

+		this.query = query;

+		this.namespaceInfos = namespaceInfos;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.container.

+	 * IResourceProvider

+	 * #getResource(org.eclipse.wst.xml.core.internal.provisional

+	 * .document.IDOMNode, org.eclipse.core.resources.IResource)

+	 */

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return querySpecification.getResource(selectedNode, resource);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.container.

+	 * IMultiResourceProvider

+	 * #getResources(org.eclipse.wst.xml.core.internal.provisional

+	 * .document.IDOMNode, org.eclipse.core.resources.IResource)

+	 */

+	public IResource[] getResources(Object selectedNode, IResource resource) {

+		return querySpecification.getResources(selectedNode, resource);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification

+	 * #isMultiResource()

+	 */

+	public boolean isMultiResource() {

+		return querySpecification.isMultiResource();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.container.

+	 * IStorageProvider

+	 * #getStorage(org.eclipse.wst.xml.core.internal.provisional.

+	 * document.IDOMNode, org.eclipse.core.resources.IResource)

+	 */

+	public IStorage getStorage(Object selectedNode, IResource resource) {

+		return querySpecification.getStorage(selectedNode, resource);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.container.

+	 * IMultiStorageProvider

+	 * #getStorages(org.eclipse.wst.xml.core.internal.provisional

+	 * .document.IDOMNode, org.eclipse.core.resources.IResource)

+	 */

+	public IStorage[] getStorages(Object selectedNode, IResource resource) {

+		return querySpecification.getStorages(selectedNode, resource);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification

+	 * #isSimpleStorage()

+	 */

+	public boolean isSimpleStorage() {

+		return querySpecification.isSimpleStorage();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification

+	 * #isMultiStorage()

+	 */

+	public boolean isMultiStorage() {

+		return querySpecification.isMultiStorage();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.requestor.

+	 * IXMLSearchRequestorProvider#getRequestor()

+	 */

+	public IXMLSearchRequestor getRequestor() {

+		return querySpecification.getRequestor();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.visitor.

+	 * IXMLSearchVisitorProvider#getVisitor()

+	 */

+	public IXMLSearchDOMDocumentVisitor getVisitor() {

+		return querySpecification.getVisitor();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.

+	 * IExecutableXMLQuerySpecification#getSelectedNode()

+	 */

+	public Object getSelectedNode() {

+		return registry.getSelectedNode();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.

+	 * IExecutableXMLQuerySpecification#getQuery()

+	 */

+	public String getQuery() {

+		return query;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.

+	 * IExecutableXMLQuerySpecification#getNamespaces()

+	 */

+	public Namespaces getNamespaces() {

+		return namespaceInfos;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.queryspecifications.IXPathEvaluatorIdProvider

+	 * #getXPathProcessorId()

+	 */

+	public String getXPathProcessorId() {

+		return querySpecification.getXPathProcessorId();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.

+	 * IStringQueryBuilderProvider#getEqualsStringQueryBuilder()

+	 */

+	public IStringQueryBuilder getEqualsStringQueryBuilder() {

+		return querySpecification.getEqualsStringQueryBuilder();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.

+	 * IStringQueryBuilderProvider#getStartsWithStringQueryBuilder()

+	 */

+	public IStringQueryBuilder getStartsWithStringQueryBuilder() {

+		return querySpecification.getStartsWithStringQueryBuilder();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification.java
new file mode 100644
index 0000000..1cec5b7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification.java
@@ -0,0 +1,206 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.queryspecifications;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXPathProcessorIdProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiStorageProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IStorageProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.ProjectContainerProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.DefaultStringQueryBuilderProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilderProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllXMLExtensionFilesXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestorProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchVisitorProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.XPathNodeSetSearchVisitor;

+

+/**

+ * 

+ * Implementation of {@link IXMLQuerySpecification} which use providers like

+ * {@link IResourceProvider} instead of directly {@link IResource}.

+ * 

+ */

+public class XMLQuerySpecification implements IXMLQuerySpecification {

+

+	public static final IXMLQuerySpecification INSTANCE = newDefaultQuerySpecification();

+

+	private IStorageProvider storageProvider;

+	private IMultiStorageProvider multiStorageProvider;

+	private IResourceProvider containerProvider;

+	private IMultiResourceProvider multiContainerProvider;

+	private IXMLSearchRequestor requestor;

+	private IXMLSearchDOMDocumentVisitor visitor;

+	private IStringQueryBuilderProvider queryBuilderProvider;

+	private String xpathProcessorId;

+

+	protected XMLQuerySpecification(IResourceProvider containerProvider,

+			IMultiResourceProvider multiContainerProvider,

+			IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor,

+			IStringQueryBuilderProvider queryBuilderProvider,

+			String xpathProcessorId) {

+		this.containerProvider = containerProvider;

+		this.multiContainerProvider = multiContainerProvider;

+		this.storageProvider = null;

+		this.multiStorageProvider = null;

+		this.requestor = requestor;

+		this.visitor = visitor;

+		this.queryBuilderProvider = queryBuilderProvider;

+		this.xpathProcessorId = xpathProcessorId;

+	}

+

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return containerProvider.getResource(selectedNode, resource);

+	}

+

+	public IResource[] getResources(Object selectedNode, IResource resource) {

+		if (multiContainerProvider == null) {

+			return null;

+		}

+		return multiContainerProvider.getResources(selectedNode, resource);

+	}

+

+	public boolean isMultiResource() {

+		return multiContainerProvider != null;

+	}

+

+	public IStorage getStorage(Object selectedNode, IResource resource) {

+		if (storageProvider == null) {

+			return null;

+		}

+		return storageProvider.getStorage(selectedNode, resource);

+	}

+

+	public IStorage[] getStorages(Object selectedNode, IResource resource) {

+		if (multiStorageProvider == null) {

+			return null;

+		}

+		return multiStorageProvider.getStorages(selectedNode, resource);

+	}

+

+	public boolean isSimpleStorage() {

+		return storageProvider != null;

+	}

+

+	public boolean isMultiStorage() {

+		return multiStorageProvider != null;

+	}

+

+	public IXMLSearchRequestor getRequestor() {

+		return requestor;

+	}

+

+	public IXMLSearchDOMDocumentVisitor getVisitor() {

+		return visitor;

+	}

+

+	public static IXMLQuerySpecification newDefaultQuerySpecification() {

+		return new XMLQuerySpecification(ProjectContainerProvider.INSTANCE,

+				null, AllXMLExtensionFilesXMLSearchRequestor.INSTANCE,

+				XPathNodeSetSearchVisitor.INSTANCE,

+				DefaultStringQueryBuilderProvider.INSTANCE, null);

+	}

+

+	public static IXMLQuerySpecification newQuerySpecification(

+			Object querySpecification) {

+		XMLQuerySpecification specification = (XMLQuerySpecification) newDefaultQuerySpecification();

+		if (querySpecification instanceof IResourceProvider) {

+			specification

+					.setContainerProvider((IResourceProvider) querySpecification);

+		}

+		if (querySpecification instanceof IMultiResourceProvider) {

+			specification

+					.setMultiContainerProvider((IMultiResourceProvider) querySpecification);

+		}

+		if (querySpecification instanceof IStorageProvider) {

+			specification

+					.setStorageProvider((IStorageProvider) querySpecification);

+		}

+		if (querySpecification instanceof IMultiStorageProvider) {

+			specification

+					.setMultiStorageProvider((IMultiStorageProvider) querySpecification);

+		}

+		if (querySpecification instanceof IXMLSearchRequestorProvider) {

+			specification

+					.setRequestor(((IXMLSearchRequestorProvider) querySpecification)

+							.getRequestor());

+		}

+		if (querySpecification instanceof IXMLSearchVisitorProvider) {

+			specification

+					.setVisitor(((IXMLSearchVisitorProvider) querySpecification)

+							.getVisitor());

+		}

+		if (querySpecification instanceof IStringQueryBuilderProvider) {

+			specification

+					.setStringQueryBuilderProvider((IStringQueryBuilderProvider) querySpecification);

+		}

+		if (querySpecification instanceof IXPathProcessorIdProvider) {

+			specification

+					.setXPathEvaluatorId(((IXPathProcessorIdProvider) querySpecification)

+							.getXPathProcessorId());

+		}

+		return specification;

+	}

+

+	private void setMultiContainerProvider(

+			IMultiResourceProvider multiContainerProvider) {

+		this.multiContainerProvider = multiContainerProvider;

+	}

+

+	private void setStorageProvider(IStorageProvider storageProvider) {

+		this.storageProvider = storageProvider;

+	}

+

+	private void setMultiStorageProvider(

+			IMultiStorageProvider multiStorageProvider) {

+		this.multiStorageProvider = multiStorageProvider;

+	}

+

+	private void setXPathEvaluatorId(String xPathEvaluatorId) {

+		this.xpathProcessorId = xPathEvaluatorId;

+	}

+

+	private void setStringQueryBuilderProvider(

+			IStringQueryBuilderProvider queryBuilderProvider) {

+		this.queryBuilderProvider = queryBuilderProvider;

+	}

+

+	private void setRequestor(IXMLSearchRequestor requestor) {

+		this.requestor = requestor;

+	}

+

+	private void setVisitor(IXMLSearchDOMDocumentVisitor visitor) {

+		this.visitor = visitor;

+	}

+

+	private void setContainerProvider(IResourceProvider containerProvider) {

+		this.containerProvider = containerProvider;

+	}

+

+	public IStringQueryBuilder getEqualsStringQueryBuilder() {

+		return queryBuilderProvider.getEqualsStringQueryBuilder();

+	}

+

+	public IStringQueryBuilder getStartsWithStringQueryBuilder() {

+		return queryBuilderProvider.getStartsWithStringQueryBuilder();

+	}

+

+	public String getXPathProcessorId() {

+		return xpathProcessorId;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification2.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification2.java
new file mode 100644
index 0000000..01f3418
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/queryspecifications/XMLQuerySpecification2.java
@@ -0,0 +1,156 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.queryspecifications;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.DefaultStringQueryBuilderProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllXMLExtensionFilesXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.XPathNodeSetSearchVisitor;

+

+/**

+ * 

+ * Implementation of {@link IXMLQuerySpecification} which doesn't use providers

+ * (it use directly {@link IResource} instead of using {@link IResourceProvider}

+ * ).

+ * 

+ */

+public class XMLQuerySpecification2 implements IXMLQuerySpecification {

+

+	private IResource container;

+	private IResource[] containers;

+	private IXMLSearchRequestor requestor;

+	private IXMLSearchDOMDocumentVisitor visitor;

+	private IStringQueryBuilder equalsStringQueryBuilder;

+	private IStringQueryBuilder startsWithStringQueryBuilder;

+	private String xpathEvaluatorId;

+

+	public XMLQuerySpecification2(IResource container, IResource[] containers,

+			IXMLSearchRequestor requestor,

+			IXMLSearchDOMDocumentVisitor visitor,

+			IStringQueryBuilder equalsStringQueryBuilder,

+			IStringQueryBuilder startsWithStringQueryBuilder,

+			String xpathEvaluatorId) {

+		this.container = container;

+		this.requestor = requestor;

+		this.visitor = visitor;

+		this.equalsStringQueryBuilder = equalsStringQueryBuilder;

+		this.startsWithStringQueryBuilder = startsWithStringQueryBuilder;

+	}

+

+	public static XMLQuerySpecification2 newDefaultQuerySpecification(

+			IResource container) {

+		return new XMLQuerySpecification2(container, null,

+				AllXMLExtensionFilesXMLSearchRequestor.INSTANCE,

+				XPathNodeSetSearchVisitor.INSTANCE,

+				DefaultStringQueryBuilderProvider.INSTANCE

+						.getEqualsStringQueryBuilder(),

+				DefaultStringQueryBuilderProvider.INSTANCE

+						.getStartsWithStringQueryBuilder(), null);

+	}

+

+	public static XMLQuerySpecification2 newDefaultQuerySpecification(

+			IResource[] containers) {

+		return new XMLQuerySpecification2(null, containers,

+				AllXMLExtensionFilesXMLSearchRequestor.INSTANCE,

+				XPathNodeSetSearchVisitor.INSTANCE,

+				DefaultStringQueryBuilderProvider.INSTANCE

+						.getEqualsStringQueryBuilder(),

+				DefaultStringQueryBuilderProvider.INSTANCE

+						.getStartsWithStringQueryBuilder(), null);

+	}

+

+	public boolean isMultiResource() {

+		return containers != null;

+	}

+

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return container;

+	}

+

+	public IResource[] getResources(Object selectedNode, IResource resource) {

+		return containers;

+	}

+

+	public void setContainer(IContainer container) {

+		this.container = container;

+	}

+

+	public IXMLSearchRequestor getRequestor() {

+		return requestor;

+	}

+

+	public void setRequestor(IXMLSearchRequestor requestor) {

+		this.requestor = requestor;

+	}

+

+	public IXMLSearchDOMDocumentVisitor getVisitor() {

+		return visitor;

+	}

+

+	public void setVisitor(IXMLSearchDOMDocumentVisitor visitor) {

+		this.visitor = visitor;

+	}

+

+	public IStringQueryBuilder getEqualsStringQueryBuilder() {

+		return equalsStringQueryBuilder;

+	}

+

+	public void setEqualsStringQueryBuilder(

+			IStringQueryBuilder equalsStringQueryBuilder) {

+		this.equalsStringQueryBuilder = equalsStringQueryBuilder;

+	}

+

+	public IStringQueryBuilder getStartsWithStringQueryBuilder() {

+		return startsWithStringQueryBuilder;

+	}

+

+	public void setStartsWithStringQueryBuilder(

+			IStringQueryBuilder startsWithStringQueryBuilder) {

+		this.startsWithStringQueryBuilder = startsWithStringQueryBuilder;

+	}

+

+	public String getXPathProcessorId() {

+		return xpathEvaluatorId;

+	}

+

+	public void setXPathProcessorId(String xpathEvaluatorId) {

+		this.xpathEvaluatorId = xpathEvaluatorId;

+	}

+

+	public boolean isMultiStorage() {

+		// TODO Auto-generated method stub

+		return false;

+	}

+

+	public boolean isSimpleStorage() {

+		// TODO Auto-generated method stub

+		return false;

+	}

+

+	public IStorage getStorage(Object selectedNode, IResource resource) {

+		// TODO Auto-generated method stub

+		return null;

+	}

+

+	public IStorage[] getStorages(Object selectedNode, IResource resource) {

+		// TODO Auto-generated method stub

+		return null;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/reporter/XMLSearchReporterIdProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/reporter/XMLSearchReporterIdProvider.java
new file mode 100644
index 0000000..e519615
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/reporter/XMLSearchReporterIdProvider.java
@@ -0,0 +1,24 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.reporter;

+

+/**

+ * Increment the done search.

+ * 

+ */

+public class XMLSearchReporterIdProvider {

+

+	private static int searchId = 0;

+

+	public static synchronized int getSearchId() {

+		return searchId++;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/resource/ResourceQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/resource/ResourceQuerySpecification.java
new file mode 100644
index 0000000..aff1958
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/resource/ResourceQuerySpecification.java
@@ -0,0 +1,115 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.resource;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.FolderContainerProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+import org.eclipse.wst.xml.search.core.resource.DefaultResourceRequestor;

+import org.eclipse.wst.xml.search.core.resource.DefaultURIResolverProvider;

+import org.eclipse.wst.xml.search.core.resource.IResourceQuerySpecification;

+import org.eclipse.wst.xml.search.core.resource.IResourceRequestor;

+import org.eclipse.wst.xml.search.core.resource.IResourceRequestorProvider;

+import org.eclipse.wst.xml.search.core.resource.IURIResolver;

+import org.eclipse.wst.xml.search.core.resource.IURIResolverProvider;

+

+/**

+ * 

+ * Implementation of {@link IResourceQuerySpecification}.

+ * 

+ */

+public class ResourceQuerySpecification implements IResourceQuerySpecification {

+

+	public static final IResourceQuerySpecification DEFAULT = newDefaultQuerySpecification();

+

+	private IResourceProvider containerProvider;

+	private IMultiResourceProvider multiContainerProvider;

+	private IResourceRequestor requestor;

+	private IURIResolverProvider resolverProvider;

+

+	protected ResourceQuerySpecification(IResourceProvider containerProvider,

+			IMultiResourceProvider multiContainerProvider,

+			IResourceRequestor requestor, IURIResolverProvider resolverProvider) {

+		this.containerProvider = containerProvider;

+		this.multiContainerProvider = multiContainerProvider;

+		this.requestor = requestor;

+		this.resolverProvider = resolverProvider;

+	}

+

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return containerProvider.getResource(selectedNode, resource);

+	}

+

+	public IResourceRequestor getRequestor() {

+		return requestor;

+	}

+

+	public IURIResolver getURIResolver(IFile file, Object selectedNode) {

+		return resolverProvider.getURIResolver(file, selectedNode);

+	}

+

+	public static IResourceQuerySpecification newDefaultQuerySpecification() {

+		return new ResourceQuerySpecification(FolderContainerProvider.INSTANCE,

+				null, DefaultResourceRequestor.INSTANCE,

+				DefaultURIResolverProvider.INSTANCE);

+	}

+

+	public static IResourceQuerySpecification newQuerySpecification(

+			Object querySpecification) {

+		ResourceQuerySpecification specification = (ResourceQuerySpecification) newDefaultQuerySpecification();

+		if (querySpecification instanceof IResourceProvider) {

+			specification

+					.setContainerProvider((IResourceProvider) querySpecification);

+		}

+		if (querySpecification instanceof IMultiResourceProvider) {

+			specification

+					.setMultiContainerProvider((IMultiResourceProvider) querySpecification);

+		}

+		if (querySpecification instanceof IResourceRequestorProvider) {

+			specification

+					.setRequestor(((IResourceRequestorProvider) querySpecification)

+							.getRequestor());

+		}

+		if (querySpecification instanceof IURIResolverProvider) {

+			specification

+					.setURIResolverProvider((IURIResolverProvider) querySpecification);

+		}

+		return specification;

+	}

+

+	private void setMultiContainerProvider(

+			IMultiResourceProvider multiContainerProvider) {

+		this.multiContainerProvider = multiContainerProvider;

+	}

+

+	private void setURIResolverProvider(IURIResolverProvider resolverProvider) {

+		this.resolverProvider = resolverProvider;

+	}

+

+	private void setRequestor(IResourceRequestor requestor) {

+		this.requestor = requestor;

+	}

+

+	private void setContainerProvider(IResourceProvider containerProvider) {

+		this.containerProvider = containerProvider;

+	}

+

+	public boolean isMultiResource() {

+		return multiContainerProvider != null;

+	}

+

+	public IResource[] getResources(Object selectedNode, IResource resource) {

+		return multiContainerProvider.getResources(selectedNode, resource);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/statics/StaticValueQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/statics/StaticValueQuerySpecification.java
new file mode 100644
index 0000000..7c76451
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/statics/StaticValueQuerySpecification.java
@@ -0,0 +1,59 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.statics;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueQuerySpecification;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitor;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitorProvider;

+

+/**

+ * 

+ * Implementation of {@link IStaticValueQuerySpecification}.

+ * 

+ */

+public class StaticValueQuerySpecification implements

+		IStaticValueQuerySpecification {

+

+	private final IStaticValueVisitorProvider provider;

+	private final IStaticValueVisitor visitor;

+

+	public StaticValueQuerySpecification(IStaticValueVisitorProvider provider) {

+		this.visitor = null;

+		this.provider = provider;

+	}

+

+	public StaticValueQuerySpecification(IStaticValueVisitor visitor) {

+		this.visitor = visitor;

+		this.provider = null;

+	}

+

+	public IStaticValueVisitor getVisitor(Object selectedNode, IFile file) {

+		if (provider != null) {

+			return provider.getVisitor(selectedNode, file);

+		}

+		return visitor;

+	}

+

+	public static IStaticValueQuerySpecification newQuerySpecification(

+			Object createExecutableExtension) {

+		if (createExecutableExtension instanceof IStaticValueVisitorProvider) {

+			return new StaticValueQuerySpecification(

+					(IStaticValueVisitorProvider) createExecutableExtension);

+		}

+		if (createExecutableExtension instanceof IStaticValueVisitor) {

+			return new StaticValueQuerySpecification(

+					(IStaticValueVisitor) createExecutableExtension);

+		}

+		return null;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/storage/StorageModelManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/storage/StorageModelManager.java
new file mode 100644
index 0000000..eebbefc
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/storage/StorageModelManager.java
@@ -0,0 +1,222 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.storage;

+

+import java.io.IOException;

+import java.io.InputStream;

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IPath;

+import org.eclipse.wst.sse.core.StructuredModelManager;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+import org.eclipse.wst.xml.search.core.internal.Trace;

+import org.eclipse.wst.xml.search.core.storage.IStorageLocationProvider;

+import org.eclipse.wst.xml.search.core.storage.IStorageModelManager;

+

+/**

+ * 

+ * {@link IStorageModelManager} implementation.

+ * 

+ */

+public class StorageModelManager implements IStorageModelManager {

+

+	public static final IStorageModelManager INSTANCE = new StorageModelManager();

+

+	private Map<IStorage, ModelInfo> modelInfoMap = new HashMap<IStorage, ModelInfo>();

+

+	private IStorageLocationProvider locationProvider = null;

+

+	/**

+	 * Collection of info that goes with a model.

+	 */

+	private class ModelInfo {

+

+		public final IStructuredModel structuredModel;

+		public final IStorage storage;

+

+		public ModelInfo(IStructuredModel structuredModel, IStorage storage) {

+			this.structuredModel = structuredModel;

+			this.storage = storage;

+		}

+	}

+

+	public IStructuredModel getModel(IStorage storage) {

+		ModelInfo info = getModelInfoFor(storage);

+		if (info != null) {

+			return info.structuredModel;

+		} else {

+			IStructuredModel model = loadModel(storage);

+			if (model != null) {

+				modelInfoMap.put(storage, new ModelInfo(model, storage));

+			}

+		}

+		return null;

+	}

+

+	public IStructuredModel loadModel(IStorage storage) {

+		String id = calculateID(storage);

+		if (id == null) {

+			return null;

+		}

+		InputStream contents = null;

+		try {

+			contents = storage.getContents();

+		} catch (CoreException noStorageExc) {

+			// if (logExceptions)

+			// Logger.logException(NLS.bind(SSEUIMessages._32concat_EXC_, new

+			// Object[]{input.getName()}), noStorageExc);

+		}

+

+		IStructuredModel model = null;

+		try {

+			// first parameter must be unique

+			model = StructuredModelManager.getModelManager().getModelForEdit(

+					id, contents, null);

+			model.setBaseLocation(calculateBaseLocation(storage));

+		} catch (IOException e) {

+			// if (logExceptions)

+			// Logger.logException(NLS.bind(SSEUIMessages._32concat_EXC_, new

+			// Object[]{input}), e);

+		} finally {

+			if (contents != null) {

+				try {

+					contents.close();

+				} catch (IOException e) {

+					// nothing

+				} catch (Exception e) {

+					Trace.trace(Trace.SEVERE, "StorageModelManager#loadModel",

+							e);

+				}

+			}

+		}

+		return model;

+

+	}

+

+	String calculateBaseLocation(IStorage storage) {

+		String location = null;

+		if (locationProvider != null) {

+			location = locationProvider.getLocation(storage);

+		}

+		if (location != null) {

+			return location;

+		}

+		try {

+			if (storage != null) {

+				IPath storagePath = storage.getFullPath();

+				String name = storage.getName();

+				if (storagePath != null) {

+					// If they are different, the IStorage contract is not

+					// being honored

+					// (https://bugs.eclipse.org/bugs/show_bug.cgi?id=73098).

+					// Favor the name.

+					if (!storagePath.lastSegment().equals(name)) {

+						IPath workingPath = storagePath.addTrailingSeparator();

+						location = workingPath.append(name).toString();

+					} else {

+						location = storagePath.makeAbsolute().toString();

+					}

+				}

+				if (location == null)

+					location = name;

+			}

+		} catch (Throwable e) {

+			Trace.trace(Trace.SEVERE,

+					"StorageModelManager#calculateBaseLocation", e);

+		} finally {

+			if (location == null)

+				location = storage.getName();

+		}

+		return location;

+	}

+

+	String calculateID(IStorage storage) {

+		/**

+		 * Typically CVS will return a path of "filename.ext" and the input's

+		 * name will be "filename.ext version". The path must be used to load

+		 * the model so that the suffix will be available to compute the

+		 * contentType properly. The editor input name can then be set as the

+		 * base location for display on the editor title bar.

+		 * 

+		 */

+		String path = null;

+		try {

+			if (storage != null) {

+				IPath storagePath = storage.getFullPath();

+				String name = storage.getName();

+				if (storagePath != null) {

+					// If they are different, the IStorage contract is not

+					// being honored

+					// (https://bugs.eclipse.org/bugs/show_bug.cgi?id=73098).

+					// Favor the name.

+					if (!storagePath.lastSegment().equals(name)) {

+						IPath workingPath = storagePath.addTrailingSeparator();

+						path = workingPath.append(name).toString();

+					} else {

+						path = storagePath.makeAbsolute().toString();

+					}

+				}

+				if (path == null)

+					path = name;

+			}

+		} catch (Throwable e) {

+			Trace.trace(Trace.SEVERE, "StorageModelManager#calculateID", e);

+		} finally {

+			if (path == null)

+				path = ""; //$NON-NLS-1$

+		}

+		/*

+		 * Prepend the hash to the path value so that we have a 1:1:1 match

+		 * between editor inputs, element info, and models. The editor manager

+		 * should help prevent needlessly duplicated models as long as two

+		 * editor inputs from the same storage indicate they're equals().

+		 */

+		path = storage.hashCode() + "#" + path; //$NON-NLS-1$

+		return path;

+	}

+

+	public IStorage getStorage(IStructuredModel model) {

+		ModelInfo info = getModelInfoFor(model);

+		if (info != null) {

+			return info.storage;

+		}

+		return null;

+	}

+

+	private ModelInfo getModelInfoFor(IStorage storage) {

+		ModelInfo result = (ModelInfo) modelInfoMap.get(storage);

+		return result;

+	}

+

+	private ModelInfo getModelInfoFor(IStructuredModel structuredModel) {

+		ModelInfo result = null;

+		if (structuredModel != null) {

+			ModelInfo[] modelInfos = (ModelInfo[]) modelInfoMap.values()

+					.toArray(new ModelInfo[0]);

+			for (int i = 0; i < modelInfos.length; i++) {

+				ModelInfo info = modelInfos[i];

+				if (structuredModel.equals(info.structuredModel)) {

+					result = info;

+					break;

+				}

+			}

+		}

+		return result;

+	}

+

+	public void setStorageLocationProvider(

+			IStorageLocationProvider locationProvider) {

+		this.locationProvider = locationProvider;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/xpath/XPathProcessorType.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/xpath/XPathProcessorType.java
new file mode 100644
index 0000000..5657d44
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/internal/xpath/XPathProcessorType.java
@@ -0,0 +1,85 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.internal.xpath;

+

+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessor;

+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;

+

+/**

+ * 

+ * Implementation of {@link IXPathProcessorType}.

+ * 

+ */

+public class XPathProcessorType implements IXPathProcessorType {

+

+	private final String id;

+	private final String name;

+	private final boolean contributed;

+	private final String source;

+	private final IXPathProcessor evaluator;

+

+	public XPathProcessorType(String id, String name, String source,

+			boolean contributed, IXPathProcessor evaluator) {

+		this.id = id;

+		this.name = name;

+		this.source = source;

+		this.contributed = contributed;

+		this.evaluator = evaluator;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#getProcessor()

+	 */

+	public IXPathProcessor getProcessor() {

+		return evaluator;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#getId()

+	 */

+	public String getId() {

+		return id;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#getName()

+	 */

+	public String getName() {

+		return name;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#isContributed()

+	 */

+	public boolean isContributed() {

+		return contributed;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType#getSource()

+	 */

+	public String getSource() {

+		return source;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/INamespaceMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/INamespaceMatcher.java
new file mode 100644
index 0000000..e00eb34
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/INamespaceMatcher.java
@@ -0,0 +1,12 @@
+package org.eclipse.wst.xml.search.core.namespaces;

+

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.w3c.dom.Node;

+

+public interface INamespaceMatcher {

+

+	boolean match(Node node);

+

+	String format(String prefix, String xpath, NamespaceInfos namespaceInfos);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespaceMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespaceMatcher.java
new file mode 100644
index 0000000..d5a347e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespaceMatcher.java
@@ -0,0 +1,46 @@
+package org.eclipse.wst.xml.search.core.namespaces;

+

+import java.util.List;

+

+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.w3c.dom.Node;

+

+public abstract class NamespaceMatcher implements INamespaceMatcher {

+

+	public String format(String prefix, final String xpath,

+			NamespaceInfos namespaceInfos) {

+		String newXpath = xpath;

+		String namespaceURI = null;

+		String p = null;

+		boolean formatted = false;

+		List<NamespaceInfo> infos = namespaceInfos;

+		for (NamespaceInfo namespaceInfo : infos) {

+			namespaceURI = namespaceInfo.uri;

+			if (namespaceURI != null && isMatchedNamespace(namespaceURI)) {

+				p = namespaceInfo.prefix;

+				newXpath = xpath.replaceAll(prefix + ":", p + ":");

+				formatted = true;

+			}

+		}

+		if (!formatted) {

+			newXpath = xpath.replaceAll(prefix + ":", "");

+			newXpath += "[starts-with(name(.), \"" + prefix + "\")]";

+		}

+		return newXpath;

+	}

+

+	public boolean match(Node node) {

+		String namespaceURI = node.getNamespaceURI();

+		if (namespaceURI != null) {

+			return isMatchedNamespace(namespaceURI);

+		} else {

+			return isMatchedPrefix(node.getPrefix());

+		}

+	}

+

+	protected abstract boolean isMatchedNamespace(String namespaceURI);

+

+	protected abstract boolean isMatchedPrefix(String prefix);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/Namespaces.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/Namespaces.java
new file mode 100644
index 0000000..ce9ace2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/Namespaces.java
@@ -0,0 +1,48 @@
+package org.eclipse.wst.xml.search.core.namespaces;

+

+import java.util.HashMap;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.Set;

+

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.w3c.dom.Node;

+

+public class Namespaces {

+

+	private Map<String, INamespaceMatcher> matchers;

+

+	public Namespaces() {

+		matchers = new HashMap<String, INamespaceMatcher>();

+	}

+

+	public boolean match(Node node) {

+		// String prefix = null;

+		INamespaceMatcher matcher = null;

+		Set<Entry<String, INamespaceMatcher>> entries = matchers.entrySet();

+		for (Entry<String, INamespaceMatcher> entry : entries) {

+			matcher = entry.getValue();

+			if (matcher.match(node)) {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	public String format(String xpath, NamespaceInfos namespaceInfos) {

+		String prefix = null;

+		INamespaceMatcher matcher = null;

+		Set<Entry<String, INamespaceMatcher>> entries = matchers.entrySet();

+		for (Entry<String, INamespaceMatcher> entry : entries) {

+			prefix = entry.getKey();

+			matcher = entry.getValue();

+			xpath = matcher.format(prefix, xpath, namespaceInfos);

+		}

+		return xpath;

+	}

+

+	public void addMatcher(String prefix, INamespaceMatcher matcher) {

+		matchers.put(prefix, matcher);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespacesManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespacesManager.java
new file mode 100644
index 0000000..0318be5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/namespaces/NamespacesManager.java
@@ -0,0 +1,119 @@
+package org.eclipse.wst.xml.search.core.namespaces;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.internal.Trace;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+

+public class NamespacesManager extends AbstractRegistryManager {

+

+	private static final String NAMESPACES_EXTENSION_POINT = "namespaces";

+

+	private static final String ID_ATTR = "id";

+	private static final String NAMESPACES_ELT = "namespaces";

+	private static final String MATCHER_ELT = "matcher";

+	private static final String CLASS_ATTR = "class";

+	private static final String PREFIX_ATTR = "prefix";

+

+	private static final NamespacesManager INSTANCE = new NamespacesManager();

+

+	private Map<String, Namespaces> namespacesById;

+

+	public static NamespacesManager getInstance() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (namespacesById == null) {// not loaded yet

+			return;

+		}

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addNamespaces(namespacesById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	public Namespaces getNamespaces(String id) {

+		if (StringUtils.isEmpty(id)) {

+			return null;

+		}

+		if (namespacesById == null) {

+			loadNamespaces();

+		}

+		return namespacesById.get(id);

+	}

+

+	private synchronized void loadNamespaces() {

+		if (namespacesById != null) {

+			return;

+		}

+

+		Map<String, Namespaces> namespacesById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry

+					.getConfigurationElementsFor(

+							getPluginId(),

+							NAMESPACES_EXTENSION_POINT);

+			namespacesById = new HashMap<String, Namespaces>(cf.length);

+			addNamespaces(namespacesById, cf);

+		} else {

+			namespacesById = new HashMap<String, Namespaces>();

+		}

+		this.namespacesById = namespacesById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	private synchronized void addNamespaces(

+			Map<String, Namespaces> namespacesById, IConfigurationElement[] cf) {

+		String id = null;

+		for (IConfigurationElement ce : cf) {

+			// loop for to get searcher declaration

+			if (NAMESPACES_ELT.equals(ce.getName())) {

+				id = ce.getAttribute(ID_ATTR);

+				Namespaces namespaces = new Namespaces();

+				for (IConfigurationElement cns : ce.getChildren(MATCHER_ELT)) {

+					parseNamespacesDecl(namespaces, cns);

+				}

+				namespacesById.put(id, namespaces);

+			}

+		}

+	}

+

+	private void parseNamespacesDecl(Namespaces namespaces,

+			IConfigurationElement cns) {

+		String prefix = cns.getAttribute(PREFIX_ATTR);

+		try {

+			INamespaceMatcher matcher = (INamespaceMatcher)cns.createExecutableExtension(CLASS_ATTR);

+			namespaces.addMatcher(prefix, matcher);			

+		} catch (CoreException e) {			

+			Trace.trace(Trace.SEVERE, "Error namespace matcher.", e);

+		}

+		

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchCorePlugin.PLUGIN_ID;

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return NAMESPACES_EXTENSION_POINT;

+	}

+

+}

+

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/DefaultPropertiesRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/DefaultPropertiesRequestor.java
new file mode 100644
index 0000000..db13eed
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/DefaultPropertiesRequestor.java
@@ -0,0 +1,65 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.properties;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IFolder;

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IWorkspaceRoot;

+

+/**

+ * Default implementation of {@link IPropertiesRequestor}.

+ * 

+ */

+public class DefaultPropertiesRequestor implements IPropertiesRequestor {

+

+	public static final IPropertiesRequestor INSTANCE = new DefaultPropertiesRequestor();

+

+	public static final String PROPERTIES_EXT = "properties";

+	protected static final String DOT_FOLDER = ".";

+

+	public boolean accept(IResource resource, IResource rootResource) {

+		int resourceType = resource.getType();

+		switch (resourceType) {

+		case IResource.ROOT:

+			return accept((IWorkspaceRoot) resource, rootResource);

+		case IResource.PROJECT:

+			return accept((IProject) resource, rootResource);

+		case IResource.FOLDER:

+			return accept((IFolder) resource, rootResource);

+		case IResource.FILE:

+			return accept((IFile) resource, rootResource);

+		}

+		return false;

+	}

+

+	public boolean accept(IWorkspaceRoot workspaceRoot, IResource rootResource) {

+		return true;

+	}

+

+	public boolean accept(IProject project, IResource rootResource) {

+		if (project.isOpen()) {

+			return true;

+		}

+		return false;

+	}

+

+	public boolean accept(IFolder folder, IResource rootResource) {

+		// ignore .svn folder....

+		return !folder.getName().startsWith(DOT_FOLDER);

+	}

+

+	protected boolean accept(IFile file, IResource rootResource) {

+		return PROPERTIES_EXT.equals(file.getFileExtension());

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesCollector.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesCollector.java
new file mode 100644
index 0000000..41fe48a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesCollector.java
@@ -0,0 +1,31 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.properties;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+

+/**

+ * A collector to collect {@link IResource} found with the search.

+ * 

+ */

+public interface IPropertiesCollector {

+

+	/**

+	 * Collect the storage.

+	 * 

+	 * @param storage

+	 * @param key

+	 * @param name

+	 * @return

+	 */

+	boolean add(IStorage storage, String key, String name);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesQuerySpecification.java
new file mode 100644
index 0000000..6ddf0b3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesQuerySpecification.java
@@ -0,0 +1,33 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.properties;

+

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+

+/**

+ * Interface of Properties Query specification used to search property from

+ * properties files coming from workspace or JAR.

+ * 

+ */

+public interface IPropertiesQuerySpecification extends IResourceProvider,

+		IPropertiesRequestorProvider, IMultiResourceProvider {

+

+	public static final IPropertiesQuerySpecification[] EMPTY = new IPropertiesQuerySpecification[0];

+

+	/**

+	 * Returns true if multi-resources is supported and false otherwise.

+	 * 

+	 * @return

+	 */

+	boolean isMultiResource();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestor.java
new file mode 100644
index 0000000..376e0d5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestor.java
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.properties;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;

+

+/**

+ * Resource requestor is used when search is started. Search loop for each

+ * container and files and call a requestor to know if the resource is accepted

+ * for the search result or not. If the resource is accepted, it is added by

+ * using a a {@link IResourceCollector}.

+ * 

+ * @author Angelo ZERR

+ * 

+ */

+public interface IPropertiesRequestor {

+

+	/**

+	 * Returns true if resource (file, folder, project) must be accepted while

+	 * searching and false otherwise.

+	 * 

+	 * @param resource

+	 *            the resource to accept

+	 * @param resource

+	 *            the root resource where search start.

+	 * @return

+	 */

+	boolean accept(IResource resource, IResource rootResource);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestorProvider.java
new file mode 100644
index 0000000..1763002
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesRequestorProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.properties;

+

+/**

+ * A provider to returns {@link IPropertiesRequestor}.

+ * 

+ */

+public interface IPropertiesRequestorProvider {

+

+	/**

+	 * Resource requestor to use.

+	 * 

+	 * @return

+	 */

+	IPropertiesRequestor getRequestor();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesSearchEngine.java
new file mode 100644
index 0000000..4ebdaa2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/IPropertiesSearchEngine.java
@@ -0,0 +1,59 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.properties;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+/**

+ * Interface of Properties Search engine.

+ * 

+ */

+public interface IPropertiesSearchEngine {

+

+	/**

+	 * Search property which matches the given <code>matching</code> in files

+	 * properties hosted in the list of the given <code>containers</code>.

+	 * 

+	 * @param selectedNode

+	 *            the selected node which has started the search.

+	 * @param containers

+	 *            list of {@link IResource} where property must be searched in

+	 *            files.

+	 * @param requestor

+	 *            property requestor used to.

+	 * @param collector

+	 * @param matching

+	 * @param fullMatch

+	 * @param monitor

+	 * @return

+	 */

+	IStatus search(Object selectedNode, IResource[] containers,

+			IPropertiesRequestor requestor, IPropertiesCollector collector,

+			String matching, boolean fullMatch, IProgressMonitor monitor);

+

+	/**

+	 * 

+	 * @param selectedNode

+	 * @param container

+	 * @param requestor

+	 * @param collector

+	 * @param matching

+	 * @param fullMatch

+	 * @param monitor

+	 * @return

+	 */

+	IStatus search(Object selectedNode, IResource container,

+			IPropertiesRequestor requestor, IPropertiesCollector collector,

+			String matching, boolean fullMatch, IProgressMonitor monitor);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesQuerySpecificationManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesQuerySpecificationManager.java
new file mode 100644
index 0000000..1b805a5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesQuerySpecificationManager.java
@@ -0,0 +1,126 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.properties;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.internal.Trace;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.internal.properties.PropertiesQuerySpecification;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+

+/**

+ * Manager of {@link IPropertiesQuerySpecification} which are registered with

+ * extension point "propertiesQuerySpecifications".

+ * 

+ */

+public class PropertiesQuerySpecificationManager extends

+		AbstractRegistryManager {

+

+	private static final PropertiesQuerySpecificationManager INSTANCE = new PropertiesQuerySpecificationManager();

+	private static final String RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT = "propertiesQuerySpecifications";

+	private Map<String, IPropertiesQuerySpecification> querySpecificationsById = null;

+

+	public static PropertiesQuerySpecificationManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (querySpecificationsById == null) // not loaded yet

+			return;

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addQuerySpecifications(querySpecificationsById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	public IPropertiesQuerySpecification getQuerySpecification(

+			String querySpecificationId) {

+		if (StringUtils.isEmpty(querySpecificationId)) {

+			return PropertiesQuerySpecification.DEFAULT;

+		}

+		if (querySpecificationsById == null) {

+			loadQuerySpecifications();

+		}

+

+		IPropertiesQuerySpecification querySpecification = querySpecificationsById

+				.get(querySpecificationId);

+		if (querySpecification == null) {

+			querySpecification = PropertiesQuerySpecification.DEFAULT;

+			querySpecificationsById.put(querySpecificationId,

+					querySpecification);

+		}

+		return querySpecification;

+	}

+

+	private synchronized void loadQuerySpecifications() {

+		if (querySpecificationsById != null) {

+			return;

+		}

+

+		Map<String, IPropertiesQuerySpecification> querySpecificationsById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchCorePlugin.PLUGIN_ID,

+					RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT);

+			querySpecificationsById = new HashMap<String, IPropertiesQuerySpecification>(

+					cf.length);

+			addQuerySpecifications(querySpecificationsById, cf);

+		} else {

+			querySpecificationsById = new HashMap<String, IPropertiesQuerySpecification>();

+		}

+		this.querySpecificationsById = querySpecificationsById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	private synchronized void addQuerySpecifications(

+			Map<String, IPropertiesQuerySpecification> querySpecificationsById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		IPropertiesQuerySpecification querySpecification = null;

+		for (IConfigurationElement ce : cf) {

+			// querySpecification declaration,

+			id = ce.getAttribute("id");

+			try {

+				querySpecification = PropertiesQuerySpecification

+						.newQuerySpecification(ce

+								.createExecutableExtension("class"));

+				querySpecificationsById.put(id, querySpecification);

+			} catch (Throwable t) {

+				Trace.trace(Trace.SEVERE,

+						"  Could not load querySpecification for id: " + id, t);

+			}

+		}

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchCorePlugin.PLUGIN_ID;

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesSearchEngine.java
new file mode 100644
index 0000000..b2648dd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/properties/PropertiesSearchEngine.java
@@ -0,0 +1,142 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.properties;

+

+import java.io.IOException;

+import java.util.Map.Entry;

+import java.util.Properties;

+import java.util.Set;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.wst.xml.search.core.internal.Trace;

+

+/**

+ * {@link IPropertiesSearchEngine} implementation.

+ * 

+ */

+public class PropertiesSearchEngine implements IPropertiesSearchEngine {

+

+	private static final IPropertiesSearchEngine INSTANCE = new PropertiesSearchEngine();

+

+	public static IPropertiesSearchEngine getDefault() {

+		return INSTANCE;

+	}

+

+	public IStatus search(Object selectedNode, IResource[] containers,

+			IPropertiesRequestor requestor, IPropertiesCollector collector,

+			String matching, boolean fullMatch, IProgressMonitor monitor) {

+		for (int i = 0; i < containers.length; i++) {

+			IResource resource = containers[i];

+			internalSearch(selectedNode, resource, containers[i], requestor,

+					collector, matching, fullMatch, monitor);

+		}

+		return Status.OK_STATUS;

+	}

+

+	public IStatus search(Object selectedNode, IResource container,

+			IPropertiesRequestor requestor, IPropertiesCollector collector,

+			String matching, boolean fullMatch, IProgressMonitor monitor) {

+		internalSearch(selectedNode, container, container, requestor,

+				collector, matching, fullMatch, monitor);

+		return Status.OK_STATUS;

+	}

+

+	private void internalSearch(Object selectedNode, IResource rootContainer,

+			IResource container, IPropertiesRequestor requestor,

+			IPropertiesCollector collector, String matching, boolean fullMatch,

+			IProgressMonitor monitor) {

+		if (!requestor.accept(container, rootContainer))

+			return;

+		int resourceType = container.getType();

+		switch (resourceType) {

+		case IResource.FILE:

+			IFile file = (IFile) container;

+			processFile(file, collector, matching, fullMatch);

+			break;

+		case IResource.ROOT:

+		case IResource.PROJECT:

+		case IResource.FOLDER:

+			try {

+

+				// if (!fullMatch) {

+				// if (resolver

+				// .resolve(selectedNode, rootContainer, container)

+				// .toUpperCase().startsWith(matching.toUpperCase())) {

+				// collector.add(container, rootContainer, resolver);

+				// }

+				// } else {

+				// if (resolver

+				// .resolve(selectedNode, rootContainer, container)

+				// .equals(matching)) {

+				// collector.add(container, rootContainer, resolver);

+				// }

+				// }

+

+				internalSearch(selectedNode, rootContainer,

+						((IContainer) container).members(), requestor,

+						collector, matching, fullMatch, monitor);

+			} catch (CoreException e) {

+				Trace.trace(Trace.SEVERE, e.getMessage(), e);

+			}

+			break;

+		}

+	}

+

+	private IStatus internalSearch(Object selectedNode,

+			IResource rootContainer, IResource[] containers,

+			IPropertiesRequestor requestor, IPropertiesCollector collector,

+			String matching, boolean fullMatch, IProgressMonitor monitor) {

+		for (int i = 0; i < containers.length; i++) {

+			internalSearch(selectedNode, rootContainer, containers[i],

+					requestor, collector, matching, fullMatch, monitor);

+		}

+		return Status.OK_STATUS;

+	}

+

+	private void processFile(IFile file, IPropertiesCollector collector,

+			String matching, boolean fullMatch) {

+		try {

+			Properties properties = new Properties();

+			properties.load(file.getContents());

+			if (fullMatch) {

+				if (properties.containsKey(matching)) {

+					String value = properties.getProperty(matching);

+					collector.add(file, matching, value);

+				}

+			} else {

+				String matchingUpperCased = matching.toUpperCase();

+				String key = null;

+				String value = null;

+				Set<Entry<Object, Object>> entries = properties.entrySet();

+				for (Entry<Object, Object> entry : entries) {

+					key = (String) entry.getKey();

+					value = (String) entry.getValue();

+					if (key.toUpperCase().startsWith(matchingUpperCased)) {

+						collector.add(file, key, value);

+					}

+				}

+			}

+

+		} catch (CoreException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (IOException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IExecutableXMLQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IExecutableXMLQuerySpecification.java
new file mode 100644
index 0000000..bd63e6b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IExecutableXMLQuerySpecification.java
@@ -0,0 +1,44 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications;

+

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+

+/**

+ * Executable XML query specification is {@link IXMLQuerySpecification} which

+ * can be executed.

+ * 

+ */

+public interface IExecutableXMLQuerySpecification extends

+		IXMLQuerySpecification {

+

+	/**

+	 * Returns the query (XPath...) to execute.

+	 * 

+	 * @return

+	 */

+	String getQuery();

+

+	/**

+	 * Returns information about namespaces which must be used when XPath is

+	 * executed.

+	 * 

+	 * @return

+	 */

+	Namespaces getNamespaces();

+

+	/**

+	 * Returns the selected node which has started the search.

+	 * 

+	 * @return

+	 */

+	Object getSelectedNode();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IStringQueryProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IStringQueryProvider.java
new file mode 100644
index 0000000..30d883b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IStringQueryProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications;

+

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;

+import org.w3c.dom.Node;

+

+/**

+ * Query provider.

+ */

+public interface IStringQueryProvider {

+

+	/**

+	 * Returns the XPath query to execute for the given node and given string

+	 * query builder..

+	 * 

+	 * @param node

+	 * @param builder

+	 * @return

+	 */

+	String getQuery(Node node, IStringQueryBuilder builder);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecification.java
new file mode 100644
index 0000000..9ffd3b3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecification.java
@@ -0,0 +1,56 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications;

+

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiStorageProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IStorageProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilderProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestorProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchVisitorProvider;

+

+/**

+ * XML Query specification contains the all informations to execute search DOM Nodes from

+ * DOM Document coming from workspace or JAR.

+ * 

+ */

+public interface IXMLQuerySpecification extends IResourceProvider,

+		IMultiResourceProvider, IXMLSearchRequestorProvider,

+		IXMLSearchVisitorProvider, IStringQueryBuilderProvider,

+		IXPathProcessorIdProvider, IStorageProvider, IMultiStorageProvider {

+

+	/**

+	 * Returns true if DOM Document to search is done with multiple resources

+	 * (several IFile, IContainer....) and false otherwise (one IFile, one

+	 * IContainer...).

+	 * 

+	 * @return

+	 */

+	boolean isMultiResource();

+

+	/**

+	 * Returns true if DOM Document to search is done with a simple storage (XML

+	 * file coming from JAR) and false otherwise.

+	 * 

+	 * @return

+	 */

+	boolean isSimpleStorage();

+

+	/**

+	 * Returns true if DOM Document to search is done with several storages (XML

+	 * files coming from JAR) and false otherwise.

+	 * 

+	 * @return

+	 */

+	boolean isMultiStorage();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecificationRegistry.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecificationRegistry.java
new file mode 100644
index 0000000..e0632fc
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXMLQuerySpecificationRegistry.java
@@ -0,0 +1,39 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications;

+

+import java.util.Collection;

+import java.util.Map;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+

+/**

+ * Registry of query {@link IExecutableXMLQuerySpecification} to execute.

+ * 

+ */

+public interface IXMLQuerySpecificationRegistry {

+

+	void register(IXMLQuerySpecification querySpecification, String query,

+			Namespaces namespaceInfos);

+

+	void register(IXMLQuerySpecification xmlQuerySpecification, String query,

+			IResource container, Namespaces namespaceInfos);

+

+	Map<IResource, Collection<IExecutableXMLQuerySpecification>> getQuerySpecificationsMap();

+

+	Object getSelectedNode();

+

+	Collection<String> getQueries();

+

+	String getQueriesLabel();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXPathProcessorIdProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXPathProcessorIdProvider.java
new file mode 100644
index 0000000..d7c61cf
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/IXPathProcessorIdProvider.java
@@ -0,0 +1,21 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications;

+

+/**

+ * XPath processor identifiant.

+ *

+ */

+public interface IXPathProcessorIdProvider {

+

+	String getXPathProcessorId();

+	

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationManager.java
new file mode 100644
index 0000000..39ff1ad
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationManager.java
@@ -0,0 +1,126 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.internal.Trace;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.internal.queryspecifications.XMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+

+/**

+ * Manager of {@link IXMLQuerySpecification} which are registered with extension

+ * point "querySpecifications".

+ * 

+ */

+public class XMLQuerySpecificationManager extends AbstractRegistryManager {

+

+	private static final XMLQuerySpecificationManager INSTANCE = new XMLQuerySpecificationManager();

+	private static final String XML_QUERY_SPECIFICATIONS_EXTENSION_POINT = "querySpecifications";

+

+	private Map<String, IXMLQuerySpecification> querySpecificationsById = null;

+

+	public static XMLQuerySpecificationManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (querySpecificationsById == null) // not loaded yet

+			return;

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addQuerySpecifications(querySpecificationsById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	public IXMLQuerySpecification getQuerySpecification(

+			String querySpecificationId) {

+		if (StringUtils.isEmpty(querySpecificationId)) {

+			return XMLQuerySpecification.INSTANCE;

+		}

+		if (querySpecificationsById == null) {

+			loadQuerySpecifications();

+		}

+

+		IXMLQuerySpecification querySpecification = querySpecificationsById

+				.get(querySpecificationId);

+		if (querySpecification == null) {

+			querySpecification = XMLQuerySpecification.INSTANCE;

+			querySpecificationsById.put(querySpecificationId,

+					querySpecification);

+		}

+		return querySpecification;

+	}

+

+	private synchronized void loadQuerySpecifications() {

+		if (querySpecificationsById != null) {

+			return;

+		}

+

+		Map<String, IXMLQuerySpecification> querySpecificationsById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchCorePlugin.PLUGIN_ID,

+					XML_QUERY_SPECIFICATIONS_EXTENSION_POINT);

+			querySpecificationsById = new HashMap<String, IXMLQuerySpecification>(

+					cf.length);

+			addQuerySpecifications(querySpecificationsById, cf);

+		} else {

+			querySpecificationsById = new HashMap<String, IXMLQuerySpecification>();

+		}

+		this.querySpecificationsById = querySpecificationsById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	private synchronized void addQuerySpecifications(

+			Map<String, IXMLQuerySpecification> querySpecificationsById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		IXMLQuerySpecification querySpecification = null;

+		for (IConfigurationElement ce : cf) {

+			// querySpecification declaration,

+			id = ce.getAttribute("id");

+			try {

+				querySpecification = XMLQuerySpecification

+						.newQuerySpecification(ce

+								.createExecutableExtension("class"));

+				querySpecificationsById.put(id, querySpecification);

+			} catch (Throwable t) {

+				Trace.trace(Trace.SEVERE,

+						"  Could not load querySpecification for id: " + id, t);

+			}

+		}

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchCorePlugin.PLUGIN_ID;

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return XML_QUERY_SPECIFICATIONS_EXTENSION_POINT;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationRegistry.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationRegistry.java
new file mode 100644
index 0000000..23c02bc
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/XMLQuerySpecificationRegistry.java
@@ -0,0 +1,121 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.internal.queryspecifications.ExecutableXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+

+/**

+ * Registry of query {@link IExecutableXMLQuerySpecification} to execute.

+ * 

+ */

+public class XMLQuerySpecificationRegistry implements

+		IXMLQuerySpecificationRegistry {

+

+	private final Map<IResource, Collection<IExecutableXMLQuerySpecification>> querySpecificationsMap;

+	private final Collection<String> queries;

+	private final IContainer container;

+	private final IFile file;

+	private final Object selectedNode;

+

+	public XMLQuerySpecificationRegistry(IResource resource, Object selectedNode) {

+		if (resource.getType() == IResource.FILE) {

+			this.file = (IFile) resource;

+			this.container = null;

+		} else {

+			this.file = null;

+			this.container = (IContainer) resource;

+		}

+		this.selectedNode = selectedNode;

+		this.querySpecificationsMap = new HashMap<IResource, Collection<IExecutableXMLQuerySpecification>>();

+		this.queries = new ArrayList<String>();

+	}

+

+	public void register(IXMLQuerySpecification querySpecification,

+			String query, Namespaces namespaceInfos) {

+		if (querySpecification.isMultiResource() && file != null) {

+			IResource[] containers = querySpecification.getResources(

+					selectedNode, file);

+			for (IResource container : containers) {

+				register(querySpecification, query, container, namespaceInfos);

+			}

+		} else {

+			IResource container = (file != null ? querySpecification

+					.getResource(selectedNode, file) : this.container);

+			if (container == null)

+				return;

+			register(querySpecification, query, container, namespaceInfos);

+		}

+	}

+

+	public void register(IXMLQuerySpecification querySpecification,

+			String query, IResource container, Namespaces namespaceInfos) {

+		Collection<IExecutableXMLQuerySpecification> querySpecifications = querySpecificationsMap

+				.get(container);

+		if (querySpecifications == null) {

+			querySpecifications = new ArrayList<IExecutableXMLQuerySpecification>();

+			querySpecificationsMap.put(container, querySpecifications);

+		}

+		if (!hasQuery(querySpecifications, query)) {

+			queries.add(query);

+			querySpecifications.add(new ExecutableXMLQuerySpecification(this,

+					querySpecification, query, namespaceInfos));

+		}

+	}

+

+	private boolean hasQuery(

+			Collection<IExecutableXMLQuerySpecification> querySpecifications,

+			String query) {

+		for (IExecutableXMLQuerySpecification querySpecification : querySpecifications) {

+			if (querySpecification.getQuery().equals(query))

+				return true;

+		}

+		return false;

+	}

+

+	public Map<IResource, Collection<IExecutableXMLQuerySpecification>> getQuerySpecificationsMap() {

+		return querySpecificationsMap;

+	}

+

+	public Object getSelectedNode() {

+		return selectedNode;

+	}

+

+	public Collection<String> getQueries() {

+		return queries;

+	}

+

+	public String getQueriesLabel() {

+		Collection<String> cache = new ArrayList<String>();

+		StringBuilder label = new StringBuilder();

+		int i = 0;

+		for (String query : queries) {

+			if (!cache.contains(query)) {

+				if (i > 0) {

+					label.append(", ");

+				}

+				label.append(query);

+				i++;

+				cache.add(query);

+			}

+		}

+		return label.toString();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/FolderContainerProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/FolderContainerProvider.java
new file mode 100644
index 0000000..19d655f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/FolderContainerProvider.java
@@ -0,0 +1,45 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.container;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IWorkspaceRoot;

+

+/**

+ * Provider to returns the {@link IContainer} of the file of the selected Node

+ * which launch the search.

+ */

+public class FolderContainerProvider implements IResourceProvider {

+

+	public static IResourceProvider INSTANCE = new FolderContainerProvider();

+

+	/**

+	 * Returns the {@link IContainer} of the file of the selected Node which

+	 * launch the search.

+	 * 

+	 * @param selectedNode

+	 *            the selected node which have launch the search.

+	 * @param resource

+	 *            the owner resource file of the selected node.

+	 */

+	public IResource getResource(Object selectedNode, IResource resource) {

+		if (resource.getType() == IResource.PROJECT) {

+			return (IProject) resource;

+		}

+		if (resource.getType() == IResource.ROOT) {

+			return (IWorkspaceRoot) resource;

+		}

+		return resource.getParent();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiResourceProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiResourceProvider.java
new file mode 100644
index 0000000..fe2760a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiResourceProvider.java
@@ -0,0 +1,51 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.container;

+

+import org.eclipse.core.resources.IResource;

+

+/**

+ * 

+ * Provider to get several {@link IResource} (IFile, IContainer....) used to

+ * search DOM Document to use to search DOM Nodes.

+ * 

+ * <ul>

+ * <li>when {@link IResource} returned is IFile, it use DOM Document loaded from

+ * the IFile.</li>

+ * <li>when {@link IResource} returned is IContainer, it loops for each IFile

+ * and IContainer and load several DOM Document where search Nodes must be done.

+ * </li>

+ * </ul>

+ */

+public interface IMultiResourceProvider {

+

+	public static final IResource[] EMPTY_RESOURCE = new IResource[0];

+

+	/**

+	 * Returns array of {@link IResource} (IFile, IContainer....) used to search

+	 * DOM Document to use to search DOM Nodes. If null is returned, search is

+	 * stopped.

+	 * 

+	 * <ul>

+	 * <li>when {@link IResource} returned is IFile, it use DOM Document loaded

+	 * from the IFile.</li>

+	 * <li>when {@link IResource} returned is IContainer, it loops for each

+	 * IFile and IContainer and load several DOM Document where search Nodes

+	 * must be done.</li>

+	 * 

+	 * @param selectedNode

+	 *            the selected node which have launch the search.

+	 * @param resource

+	 *            the owner resource file of the selected node.

+	 * @return

+	 */

+	IResource[] getResources(Object selectedNode, IResource resource);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiStorageProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiStorageProvider.java
new file mode 100644
index 0000000..ab6f2e8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IMultiStorageProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.container;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+

+/**

+ * 

+ * Provider to get several {@link IStorage} (files coming from JAR....) used to

+ * search DOM Document to use to search DOM Nodes.

+ * 

+ */

+public interface IMultiStorageProvider {

+

+	public static final IStorage[] EMPTY_STORAGE = new IStorage[0];

+

+	/**

+	 * Returns array of {@link IStorage} (files coming from JAR....) used to

+	 * search DOM Document to use to search DOM Nodes. If null is returned,

+	 * search is stopped.

+	 * 

+	 * @param selectedNode

+	 *            the selected node which have launch the search.

+	 * @param resource

+	 *            the owner resource file of the selected node.

+	 * @return

+	 */

+	IStorage[] getStorages(Object selectedNode, IResource resource);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IResourceProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IResourceProvider.java
new file mode 100644
index 0000000..11183d8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IResourceProvider.java
@@ -0,0 +1,49 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.container;

+

+import org.eclipse.core.resources.IResource;

+

+/**

+ * 

+ * Provider to get one {@link IResource} (IFile, IContainer....) used to search

+ * DOM Document to use to search DOM Nodes.

+ * 

+ * <ul>

+ * <li>when {@link IResource} returned is IFile, it use DOM Document loaded from

+ * the IFile.</li>

+ * <li>when {@link IResource} returned is IContainer, it loops for each IFile

+ * and IContainer and load several DOM Document where search Nodes must be done.

+ * </li>

+ * </ul>

+ */

+public interface IResourceProvider {

+

+	/**

+	 * Returns {@link IResource} (IFile, IContainer....) used to search DOM

+	 * Document to use to search DOM Nodes. If null is returned, search is

+	 * stopped.

+	 * 

+	 * <ul>

+	 * <li>when {@link IResource} returned is IFile, it use DOM Document loaded

+	 * from the IFile.</li>

+	 * <li>when {@link IResource} returned is IContainer, it loops for each

+	 * IFile and IContainer and load several DOM Document where search Nodes

+	 * must be done.</li>

+	 * 

+	 * @param selectedNode

+	 *            the selected node which have launch the search.

+	 * @param resource

+	 *            the owner resource file of the selected node.

+	 * @return

+	 */

+	IResource getResource(Object selectedNode, IResource resource);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IStorageProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IStorageProvider.java
new file mode 100644
index 0000000..f4817b8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IStorageProvider.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.container;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+

+/**

+ * 

+ * Provider to get one {@link IStorage} (file coming from JAR....) used to

+ * search DOM Document to use to search DOM Nodes.

+ * 

+ */

+public interface IStorageProvider {

+

+	/**

+	 * Returns @link IStorage} (file coming from JAR....) used to search DOM

+	 * Document to use to search DOM Nodes. If null is returned, search is

+	 * stopped.

+	 * 

+	 * @param selectedNode

+	 *            the selected node which have launch the search.

+	 * @param resource

+	 *            the owner resource file of the selected node.

+	 * @return

+	 */

+	IStorage getStorage(Object selectedNode, IResource resource);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IdentityResourceProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IdentityResourceProvider.java
new file mode 100644
index 0000000..a9559c1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/IdentityResourceProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.container;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+/**

+ * Provider to get the same resource than the selected Node which launch the

+ * search.

+ * 

+ */

+public class IdentityResourceProvider implements IResourceProvider {

+

+	public static final IResourceProvider INSTANCE = new IdentityResourceProvider();

+

+	/**

+	 * Returns the same resource than the selected Node which launch the search.

+	 * 

+	 * @param selectedNode

+	 *            the selected node which have launch the search.

+	 * 

+	 * @param resource

+	 *            the owner resource file of the selected node.

+	 */

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return resource;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/ProjectContainerProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/ProjectContainerProvider.java
new file mode 100644
index 0000000..976e502
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/ProjectContainerProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.container;

+

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+/**

+ * Provider to returns the {@link IProject} of the file of the selected Node

+ * which launch the search.

+ */

+public class ProjectContainerProvider implements IResourceProvider {

+

+	public static final IResourceProvider INSTANCE = new ProjectContainerProvider();

+

+	/**

+	 * Returns the {@link IProject} of the file of the selected Node which

+	 * launch the search.

+	 * 

+	 * @param selectedNode

+	 *            the selected node which have launch the search.

+	 * @param resource

+	 *            the owner resource file of the selected node.

+	 */

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return resource.getProject();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/WorkspaceContainerProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/WorkspaceContainerProvider.java
new file mode 100644
index 0000000..d236f01
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/container/WorkspaceContainerProvider.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.container;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+/**

+ * Provider to returns the workspace root.

+ */

+public class WorkspaceContainerProvider implements IResourceProvider {

+

+	public static final IResourceProvider INSTANCE = new WorkspaceContainerProvider();

+

+	/**

+	 * Returns the workspace roor.

+	 * 

+	 * @param selectedNode

+	 *            the selected node which have launch the search.

+	 * @param resource

+	 *            the owner resource file of the selected node.

+	 */

+	public IResource getResource(Object selectedNode, IResource resource) {

+		return ResourcesPlugin.getWorkspace().getRoot();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/AbstractStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/AbstractStringQueryBuilder.java
new file mode 100644
index 0000000..4cb906d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/AbstractStringQueryBuilder.java
@@ -0,0 +1,66 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;

+

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.w3c.dom.Node;

+

+/**

+ * Abstract class for {@link IStringQueryBuilder}.

+ * 

+ */

+public abstract class AbstractStringQueryBuilder implements IStringQueryBuilder {

+

+	private static final String NORMALIZE_SPACE_TEXT = "normalize-space(text())";

+	private static final String TEXT_TARGETNODE = "text()";

+

+	public String getNodeValue(Node node) {

+		return DOMUtils.getNodeValue(node);

+	}

+

+	public String build(String baseQuery, String[] targetNodes,

+			Object selectedNode) {

+		return build(baseQuery, targetNodes, 0, selectedNode);

+	}

+

+	public String build(String baseQuery, String[] targetNodes, int startIndex,

+			Object selectedNode) {

+		if (targetNodes == null) {

+			targetNodes = StringUtils.EMPTY_ARRAY;

+		}

+		baseQuery = baseQuery.replaceAll("'", "''");

+		StringBuilder xpath = new StringBuilder(baseQuery);

+		if (baseQuery.endsWith("//")) {

+			xpath.append("*");

+		}

+		build(xpath, targetNodes, startIndex, selectedNode);

+		if (targetNodes.length > 0 && addLastTargetNodeAtEnds()) {

+			xpath.append("/");

+			xpath.append(targetNodes[targetNodes.length - 1]);

+		}

+		return xpath.toString();

+	}

+

+	protected String getTargetNode(String targetNode) {

+		if (TEXT_TARGETNODE.equals(targetNode)) {

+			targetNode = NORMALIZE_SPACE_TEXT;

+		}

+		return targetNode;

+	}

+

+	protected boolean addLastTargetNodeAtEnds() {

+		return true;

+	}

+

+	protected abstract void build(StringBuilder xpath, String[] targetNodes,

+			int startIndex, Object selectedNode);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilder.java
new file mode 100644
index 0000000..8b9a314
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilder.java
@@ -0,0 +1,51 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;

+

+import org.w3c.dom.Node;

+

+/**

+ * String query builder to use fn:contains() XPath function.

+ * 

+ */

+public class ContainsStringQueryBuilder extends AbstractStringQueryBuilder {

+

+	public static IStringQueryBuilder INSTANCE = new ContainsStringQueryBuilder();

+

+	protected ContainsStringQueryBuilder() {

+

+	}

+

+	public String getId() {

+		return ContainsStringQueryBuilder.class.getSimpleName();

+	}

+

+	@Override

+	protected void build(StringBuilder xpath, String[] targetNodes,

+			int startIndex, Object selectedNode) {

+		String attrName = null;

+		for (int i = 0; i < targetNodes.length; i++) {

+			attrName = targetNodes[i];

+			// Attribute exists

+			xpath.append("[");

+			xpath.append(attrName);

+			xpath.append(" and ");

+			// starts-with

+			xpath.append("contains(");

+			xpath.append(getTargetNode(attrName));

+			xpath.append(",\"{");

+			xpath.append(i + startIndex);

+			xpath.append("}\")");

+			xpath.append("]");

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilderProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilderProvider.java
new file mode 100644
index 0000000..5b43aa1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/ContainsStringQueryBuilderProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;

+

+/**

+ * Provider of {@link ContainsStringQueryBuilder}.

+ * 

+ */

+public class ContainsStringQueryBuilderProvider implements

+		IStringQueryBuilderProvider {

+

+	public static final IStringQueryBuilderProvider INSTANCE = new ContainsStringQueryBuilderProvider();

+

+	public IStringQueryBuilder getEqualsStringQueryBuilder() {

+		return ContainsStringQueryBuilder.INSTANCE;

+	}

+

+	public IStringQueryBuilder getStartsWithStringQueryBuilder() {

+		return StartsWithStringQueryBuilder.INSTANCE;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/DefaultStringQueryBuilderProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/DefaultStringQueryBuilderProvider.java
new file mode 100644
index 0000000..bb21493
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/DefaultStringQueryBuilderProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;

+

+/**

+ * Default string query builder provider.

+ * 

+ */

+public class DefaultStringQueryBuilderProvider implements

+		IStringQueryBuilderProvider {

+

+	public static final IStringQueryBuilderProvider INSTANCE = new DefaultStringQueryBuilderProvider();

+

+	public IStringQueryBuilder getEqualsStringQueryBuilder() {

+		return EqualsStringQueryBuilder.INSTANCE;

+	}

+

+	public IStringQueryBuilder getStartsWithStringQueryBuilder() {

+		return StartsWithStringQueryBuilder.INSTANCE;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/EqualsStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/EqualsStringQueryBuilder.java
new file mode 100644
index 0000000..e62d3df
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/EqualsStringQueryBuilder.java
@@ -0,0 +1,51 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;

+

+import org.w3c.dom.Node;

+

+/**

+ * String query builder to use = XPath function.

+ * 

+ */

+public class EqualsStringQueryBuilder extends AbstractStringQueryBuilder {

+

+	public static IStringQueryBuilder INSTANCE = new EqualsStringQueryBuilder();

+

+	protected EqualsStringQueryBuilder() {

+

+	}

+

+	public String getId() {

+		return EqualsStringQueryBuilder.class.getSimpleName();

+	}

+

+	@Override

+	protected void build(StringBuilder xpath, String[] targetNodes,

+			int startIndex, Object selectedNode) {

+		String targetNode = null;

+		for (int i = 0; i < targetNodes.length; i++) {

+			targetNode = targetNodes[i];

+			targetNode = getTargetNode(targetNode);

+			xpath.append("[");

+			xpath.append(targetNode);

+			xpath.append("=\"{");

+			xpath.append(i + startIndex);

+			xpath.append("}\"]");

+		}

+	}

+

+	@Override

+	protected boolean addLastTargetNodeAtEnds() {

+		return true;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilder.java
new file mode 100644
index 0000000..89046bb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilder.java
@@ -0,0 +1,22 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;

+

+

+public interface IStringQueryBuilder {

+

+	String getId();

+

+	String build(String baseQuery, String[] targetNodes, Object selectedNode);

+

+	String build(String baseQuery, String[] targetNodes, int startIndex,

+			Object selectedNode);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilderProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilderProvider.java
new file mode 100644
index 0000000..76b6307
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/IStringQueryBuilderProvider.java
@@ -0,0 +1,18 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;

+

+public interface IStringQueryBuilderProvider {

+	

+	IStringQueryBuilder getEqualsStringQueryBuilder();

+

+	IStringQueryBuilder getStartsWithStringQueryBuilder();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/StartsWithStringQueryBuilder.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/StartsWithStringQueryBuilder.java
new file mode 100644
index 0000000..32aff6d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/querybuilder/StartsWithStringQueryBuilder.java
@@ -0,0 +1,53 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.querybuilder;

+

+import org.w3c.dom.Node;

+

+/**

+ * String query builder to use fn:starts-with() XPath function.

+ * 

+ */

+public class StartsWithStringQueryBuilder extends AbstractStringQueryBuilder {

+

+	public static IStringQueryBuilder INSTANCE = new StartsWithStringQueryBuilder();

+

+	protected StartsWithStringQueryBuilder() {

+

+	}

+

+	public String getId() {

+		return StartsWithStringQueryBuilder.class.getSimpleName();

+	}

+

+	@Override

+	protected void build(StringBuilder xpath, String[] targetNodes,

+			int startIndex, Object selectedNode) {

+		String attrName = null;

+		for (int i = 0; i < targetNodes.length; i++) {

+			attrName = targetNodes[i];

+			// Attribute exists

+			xpath.append("[");

+			xpath.append(attrName);

+			xpath.append(" and ");

+			// starts-with

+			xpath.append("starts-with(");

+			xpath.append(getTargetNode(attrName));

+			xpath.append(",\"{");

+			xpath.append(i + startIndex);

+			xpath.append("}\")");

+			xpath.append("]");

+		}

+	}

+

+	

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AbstractXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AbstractXMLSearchRequestor.java
new file mode 100644
index 0000000..dc1ac8d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AbstractXMLSearchRequestor.java
@@ -0,0 +1,50 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IFolder;

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IWorkspaceRoot;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+

+public abstract class AbstractXMLSearchRequestor implements IXMLSearchRequestor {

+

+	protected static final String DOT_FOLDER = ".";

+

+	public boolean accept(IResource resource, IResource rootResource) {

+		int resourceType = resource.getType();

+		switch (resourceType) {

+		case IResource.ROOT:

+			return accept((IWorkspaceRoot) resource, rootResource);

+		case IResource.PROJECT:

+			return accept((IProject) resource, rootResource);

+		case IResource.FOLDER:

+			return accept((IFolder) resource, rootResource);

+		case IResource.FILE:

+			return accept((IFile) resource, rootResource);

+		}

+		return false;

+	}

+

+	public boolean accept(IWorkspaceRoot workspaceRoot, IResource rootResource) {

+		return true;

+	}

+

+	public boolean accept(IProject project, IResource rootResource) {

+		if (project.isOpen()) {

+			return true;

+		}

+		return false;

+	}

+

+	public boolean accept(IFolder folder, IResource rootResource) {

+		// ignore .svn folder....

+		return !folder.getName().startsWith(DOT_FOLDER);

+	}

+

+	public boolean accept(IStructuredModel model) {

+		return true;

+	}

+

+	protected abstract boolean accept(IFile file, IResource rootResource);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllFilesXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllFilesXMLSearchRequestor.java
new file mode 100644
index 0000000..17464fe
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllFilesXMLSearchRequestor.java
@@ -0,0 +1,15 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+

+public class AllFilesXMLSearchRequestor extends AbstractXMLSearchRequestor {

+

+	public static final IXMLSearchRequestor INSTANCE = new AllFilesXMLSearchRequestor();

+

+	@Override

+	public boolean accept(IFile file, IResource rootResource) {

+		return true;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllXMLExtensionFilesXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllXMLExtensionFilesXMLSearchRequestor.java
new file mode 100644
index 0000000..df64718
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/AllXMLExtensionFilesXMLSearchRequestor.java
@@ -0,0 +1,16 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+

+public class AllXMLExtensionFilesXMLSearchRequestor extends AbstractXMLSearchRequestor {

+

+	public static final IXMLSearchRequestor INSTANCE = new AllXMLExtensionFilesXMLSearchRequestor();

+	private static final String XML_EXT = "xml";

+	

+	@Override

+	public boolean accept(IFile file, IResource rootResource) {

+		return XML_EXT.equals(file.getFileExtension());

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/ContentTypeXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/ContentTypeXMLSearchRequestor.java
new file mode 100644
index 0000000..2a17369
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/ContentTypeXMLSearchRequestor.java
@@ -0,0 +1,44 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;

+

+import java.util.Collection;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.core.runtime.content.IContentType;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+

+public abstract class ContentTypeXMLSearchRequestor extends

+		AbstractXMLSearchRequestor {

+

+	private Collection<String> supportedContentTypeIds;

+

+	public boolean accept(IFile file, IResource rootResource) {

+		for (String id : internalGetSupportedContentTypeIds()) {

+			IContentType contentType = Platform.getContentTypeManager()

+					.getContentType(id);

+			if (contentType != null) {

+				if (contentType.isAssociatedWith(file.getName())) {

+					return true;

+				}

+			}

+		}

+		return false;

+	}

+

+	public boolean accept(IStructuredModel model) {

+		String contentTypeIdentifier = model.getContentTypeIdentifier();

+		return internalGetSupportedContentTypeIds().contains(

+				contentTypeIdentifier);

+	}

+

+	private Collection<String> internalGetSupportedContentTypeIds() {

+		if (supportedContentTypeIds == null) {

+			supportedContentTypeIds = getSupportedContentTypeIds();

+		}

+		return supportedContentTypeIds;

+	}

+

+	protected abstract Collection<String> getSupportedContentTypeIds();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestor.java
new file mode 100644
index 0000000..c4ca7c3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestor.java
@@ -0,0 +1,48 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+

+/**

+ * XML search requestor interface used to filter XML files and folder when

+ * search is done.

+ * 

+ */

+public interface IXMLSearchRequestor {

+

+	/**

+	 * Returns true if resource (file, folder, project) must be accepted while

+	 * searching and false otherwise. When file is accepted, DOM document from

+	 * the file is loaded and

+	 * {@link IXMLSearchRequestor#accept(IStructuredModel)} is called to know if

+	 * DOM Document is visited to collect Node.

+	 * 

+	 * @param resource

+	 *            the resource to accept

+	 * @param resource

+	 *            the root resource where search start.

+	 * @return

+	 */

+	boolean accept(IResource resource, IResource rootResource);

+

+	/**

+	 * Returns true if DOM Document (file, folder, project) must be accepted

+	 * while searching and false otherwise. When DOM Document is accepted, it is

+	 * visited to collect Node.

+	 * 

+	 * @param model

+	 *            the SSE Model to accept

+	 * @return

+	 */

+	boolean accept(IStructuredModel model);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestorProvider.java
new file mode 100644
index 0000000..92e6b4c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/requestor/IXMLSearchRequestorProvider.java
@@ -0,0 +1,7 @@
+package org.eclipse.wst.xml.search.core.queryspecifications.requestor;

+

+

+public interface IXMLSearchRequestorProvider {

+

+	IXMLSearchRequestor getRequestor();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/AbstractXMLSearchVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/AbstractXMLSearchVisitor.java
new file mode 100644
index 0000000..95bc383
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/AbstractXMLSearchVisitor.java
@@ -0,0 +1,19 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;

+

+/**

+ * Abstract class for {@link IXMLSearchDOMDocumentVisitor}.

+ */

+public abstract class AbstractXMLSearchVisitor implements

+		IXMLSearchDOMDocumentVisitor {

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchDOMDocumentVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchDOMDocumentVisitor.java
new file mode 100644
index 0000000..365ccca
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchDOMDocumentVisitor.java
@@ -0,0 +1,41 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.core.XMLSearchEngineException;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+

+/**

+ * XML search visitor to visit a DOM document and collect DOM Node which follow

+ * the query.

+ * 

+ */

+public interface IXMLSearchDOMDocumentVisitor {

+

+	/**

+	 * Visit the DOM document and collect DOM Node which follow the query XPath.

+	 * 

+	 * @param document

+	 *            the DOM document to visit.

+	 * @param query

+	 *            the query (ex : XPath) to use to retrieve DOM Node to collect.

+	 * @param xpathProcessorId

+	 *            the XPath processor id to use to execute XPath.

+	 * @param collector

+	 *            the collector used to collect DOM Node.

+	 */

+	void visit(IDOMDocument document, String query, String xpathProcessorId,			

+			IXMLSearchDOMNodeCollector collector, Object selectedNode)

+			throws XMLSearchEngineException;

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchVisitorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchVisitorProvider.java
new file mode 100644
index 0000000..5836e4d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/IXMLSearchVisitorProvider.java
@@ -0,0 +1,19 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;

+

+/**

+ * Provider of {@link IXMLSearchDOMDocumentVisitor}.

+ */

+public interface IXMLSearchVisitorProvider {

+

+	IXMLSearchDOMDocumentVisitor getVisitor();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetIgnoreSelectedNodeSearchVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetIgnoreSelectedNodeSearchVisitor.java
new file mode 100644
index 0000000..8ce9ff0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetIgnoreSelectedNodeSearchVisitor.java
@@ -0,0 +1,43 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+/**

+ * Search visitor which execute XPath and collect the resulted nodes and ignore

+ * same nodes.

+ * 

+ */

+public class XPathNodeSetIgnoreSelectedNodeSearchVisitor extends

+		XPathNodeSetSearchVisitor {

+

+	public static IXMLSearchDOMDocumentVisitor INSTANCE = new XPathNodeSetIgnoreSelectedNodeSearchVisitor();

+

+	@Override

+	protected boolean canAddNode(IDOMNode nodeToAdd, Object selectedNode) {

+		if (selectedNode == null) {

+			return true;

+		}

+		if (selectedNode.equals(nodeToAdd)) {

+			return true;

+		}

+		if (!(selectedNode instanceof Node)) {

+			return false;

+		}

+		Element element1 = DOMUtils.getOwnerElement(nodeToAdd);

+		Element element2 = DOMUtils.getOwnerElement((Node) selectedNode);

+		return (!(element1 != null && element1.equals(element2) || (element1 == null && element2 == null)));

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetSearchVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetSearchVisitor.java
new file mode 100644
index 0000000..13a6ca1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/queryspecifications/visitor/XPathNodeSetSearchVisitor.java
@@ -0,0 +1,55 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.queryspecifications.visitor;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.core.XMLSearchEngineException;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.w3c.dom.NodeList;

+

+/**

+ * Search visitor which execute XPath and collect the resulted nodes.

+ * 

+ */

+public class XPathNodeSetSearchVisitor extends AbstractXMLSearchVisitor {

+

+	public static IXMLSearchDOMDocumentVisitor INSTANCE = new XPathNodeSetSearchVisitor();

+

+	public void visit(IDOMDocument document, String query,

+			String xpathProcessorId, 

+			IXMLSearchDOMNodeCollector collector, Object selectedNode)

+			throws XMLSearchEngineException {

+		try {

+			NamespaceInfos namespaceInfos = XPathManager.getManager().getNamespaceInfo(

+					document);

+			NodeList list = XPathManager.getManager().evaluateNodeSet(

+					xpathProcessorId, document, query, namespaceInfos, null);

+			for (int i = 0; i < list.getLength(); i++) {

+				IDOMNode el = (IDOMNode) list.item(i);

+				if (canAddNode(el, selectedNode)) {

+					collector.add(el);

+				}

+			}

+		} catch (XPathExpressionException e) {

+			throw new XMLSearchEngineException(e);

+		}

+	}

+

+	protected boolean canAddNode(IDOMNode nodeToAdd, Object selectedNode) {

+		return true;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/IXMLSearchReporter.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/IXMLSearchReporter.java
new file mode 100644
index 0000000..9924e5c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/IXMLSearchReporter.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.reporter;

+

+import java.util.Collection;

+import java.util.Map;

+

+import org.eclipse.core.resources.IResource;

+

+/**

+ * Search reporter to trace start/end search.

+ *

+ */

+public interface IXMLSearchReporter {

+

+	void beginSearch(int searchId, Map<IResource, Collection<String>> query);

+

+	void endSearch(int searchId, long elapsedTime);

+

+	boolean isEnabled();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/MutliXMLSearchReporter.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/MutliXMLSearchReporter.java
new file mode 100644
index 0000000..b901c86
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/MutliXMLSearchReporter.java
@@ -0,0 +1,53 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.reporter;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Map;

+

+import org.eclipse.core.resources.IResource;

+

+/**

+ * Multi search reporter.

+ * 

+ */

+public class MutliXMLSearchReporter extends ArrayList<IXMLSearchReporter>

+		implements IXMLSearchReporter {

+

+	private static final long serialVersionUID = -4324750000148797136L;

+

+	public void beginSearch(int searchId,

+			Map<IResource, Collection<String>> queries) {

+		IXMLSearchReporter reporter = null;

+		for (int i = 0; i < super.size(); i++) {

+			reporter = super.get(i);

+			if (reporter.isEnabled()) {

+				reporter.beginSearch(searchId, queries);

+			}

+		}

+	}

+

+	public void endSearch(int searchId, long elapsedTime) {

+		IXMLSearchReporter reporter = null;

+		for (int i = 0; i < super.size(); i++) {

+			reporter = super.get(i);

+			if (reporter.isEnabled()) {

+				reporter.endSearch(searchId, elapsedTime);

+			}

+		}

+	}

+

+	public boolean isEnabled() {

+		return !super.isEmpty();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/SysOutSearchReporter.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/SysOutSearchReporter.java
new file mode 100644
index 0000000..b434c2f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/reporter/SysOutSearchReporter.java
@@ -0,0 +1,58 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.reporter;

+

+import java.util.Collection;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.Set;

+

+import org.eclipse.core.resources.IResource;

+

+/**

+ * Search reporter which trace to System.out.

+ * 

+ */

+public class SysOutSearchReporter implements IXMLSearchReporter {

+

+	public static final IXMLSearchReporter INSTANCE = new SysOutSearchReporter();

+

+	public void beginSearch(int searchId,

+			Map<IResource, Collection<String>> queries) {

+		System.out.println("Start search [" + searchId + "]");

+		Set<Entry<IResource, Collection<String>>> entries = queries.entrySet();

+		for (Entry<IResource, Collection<String>> entry : entries) {

+			System.out.print("\tresources=");

+			System.out.println(entry.getKey().getFullPath());

+			System.out.print("\t\tqueries=");

+			Collection<String> q = entry.getValue();

+			boolean first = true;

+			for (String query : q) {

+				if (!first) {

+					System.out.print(", ");

+				}

+				System.out.print(query);

+				first = false;

+			}

+			System.out.println();

+		}

+	}

+

+	public void endSearch(int searchId, long elapsedTime) {

+		System.out.println("End search [" + searchId + "] with " + elapsedTime

+				+ "(ms).");

+	}

+

+	public boolean isEnabled() {

+		return true;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractResourceRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractResourceRequestor.java
new file mode 100644
index 0000000..9180bb7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractResourceRequestor.java
@@ -0,0 +1,77 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IFolder;

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IWorkspaceRoot;

+

+public abstract class AbstractResourceRequestor implements IResourceRequestor {

+

+	protected static final String DOT_FOLDER = ".";

+

+	public boolean accept(Object selectedNode, IResource rootContainer,

+			IResource resource, IURIResolver resolver, String matching,

+			boolean fullMatch) {

+		int resourceType = resource.getType();

+		switch (resourceType) {

+		case IResource.ROOT:

+			return accept(selectedNode, rootContainer,

+					(IWorkspaceRoot) resource, resolver, matching, fullMatch);

+		case IResource.PROJECT:

+			return accept(selectedNode, rootContainer, (IProject) resource,

+					resolver, matching, fullMatch);

+		case IResource.FOLDER:

+			return accept(selectedNode, rootContainer, (IFolder) resource,

+					resolver, matching, fullMatch);

+		case IResource.FILE:

+			return accept(selectedNode, rootContainer, (IFile) resource,

+					resolver, matching, fullMatch);

+		}

+		return false;

+	}

+

+	public boolean accept(Object selectedNode, IResource rootContainer,

+			IWorkspaceRoot workspaceRoot, IURIResolver resolver,

+			String matching, boolean fullMatch) {

+		return true;

+	}

+

+	public boolean accept(Object selectedNode, IResource rootContainer,

+			IProject project, IURIResolver resolver, String matching,

+			boolean fullMatch) {

+		if (project.isOpen()) {

+			return true;

+		}

+		return false;

+	}

+

+	public boolean accept(Object selectedNode, IResource rootContainer,

+			IFolder folder, IURIResolver resolver, String matching,

+			boolean fullMatch) {

+		// ignore .svn folder....

+		return !folder.getName().startsWith(DOT_FOLDER);

+	}

+

+	protected abstract boolean accept(Object selectedNode,

+			IResource rootContainer, IFile file, IURIResolver resolver,

+			String matching, boolean fullMatch);

+	

+	public boolean acceptContainer() {

+		return false;

+	}

+	

+	public boolean acceptFile() {

+		return true;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractURIResolver.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractURIResolver.java
new file mode 100644
index 0000000..5b81a64
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AbstractURIResolver.java
@@ -0,0 +1,48 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IFolder;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.Path;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+public abstract class AbstractURIResolver implements IURIResolver {

+

+	public boolean accept(Object selectedNode, IResource rootContainer,

+			IResource file, String matching, boolean fullMatch) {

+		if (!fullMatch) {

+			matching = matching.toLowerCase();

+			String fileName = file.getName();

+			fileName = fileName.toLowerCase();

+			if (fileName.startsWith(matching)) {

+				return true;

+			}

+			return resolve(selectedNode, rootContainer, file).toLowerCase()

+					.startsWith(matching);

+		}

+		return resolve(selectedNode, rootContainer, file).equals(matching);

+	}

+

+	public <T extends IResource> T getResource(IContainer container,

+			String resourceName, Class<T> clazz) {

+		if (clazz == IFile.class) {

+			return (T) container.getFile(new Path(resourceName));

+		}

+		if (clazz == IFolder.class) {

+			return (T) container.getFolder(new Path(resourceName));

+		}

+		return null;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AllResourcesRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AllResourcesRequestor.java
new file mode 100644
index 0000000..36d607c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/AllResourcesRequestor.java
@@ -0,0 +1,28 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+public class AllResourcesRequestor extends AbstractResourceRequestor {

+

+	public static final IResourceRequestor INSTANCE = new AllResourcesRequestor();

+

+	@Override

+	protected boolean accept(Object selectedNode, IResource rootContainer,

+			IFile file, IURIResolver resolver, String matching,

+			boolean fullMatch) {

+		return true;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DOMNodeBaseURIResolver.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DOMNodeBaseURIResolver.java
new file mode 100644
index 0000000..c57f943
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DOMNodeBaseURIResolver.java
@@ -0,0 +1,33 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+

+public class DOMNodeBaseURIResolver extends AbstractURIResolver {

+

+	public static final IURIResolver INSTANCE = new DOMNodeBaseURIResolver();

+

+	public String resolve(Object selectedNode, IResource rootContainer,

+			IResource file) {

+		IContainer container = DOMUtils.getFile((IDOMNode) selectedNode)

+				.getParent();

+		return file

+				.getProjectRelativePath()

+				.removeFirstSegments(

+						container.getProjectRelativePath().segmentCount())

+				.toString();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultResourceRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultResourceRequestor.java
new file mode 100644
index 0000000..b02dc62
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultResourceRequestor.java
@@ -0,0 +1,28 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+

+public class DefaultResourceRequestor extends AbstractResourceRequestor {

+

+	public static final IResourceRequestor INSTANCE = new DefaultResourceRequestor();

+

+	@Override

+	protected boolean accept(Object selectedNode, IResource rootContainer,

+			IFile file, IURIResolver resolver, String matching,

+			boolean fullMatch) {

+		return resolver.accept(selectedNode, rootContainer, file, matching,

+				fullMatch);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultURIResolverProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultURIResolverProvider.java
new file mode 100644
index 0000000..5f80408
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/DefaultURIResolverProvider.java
@@ -0,0 +1,23 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IFile;

+

+public class DefaultURIResolverProvider implements IURIResolverProvider {

+

+	public static final IURIResolverProvider INSTANCE = new DefaultURIResolverProvider();

+

+	public IURIResolver getURIResolver(IFile file, Object selectedNode) {

+		return ResourceBaseURIResolver.INSTANCE;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceCollector.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceCollector.java
new file mode 100644
index 0000000..71deea2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceCollector.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IResource;

+

+/**

+ * A collector to collect {@link IResource} founded with the search.

+ * 

+ */

+public interface IResourceCollector {

+

+	/**

+	 * This method is called when the resource match the search.

+	 * 

+	 * @param resource

+	 *            which match the search.

+	 * @param rootResource

+	 *            the root (container, file....) used when search is started.

+	 * @param resolver

+	 *            to use to resolve value path fo the {@link IResource}.

+	 * @return

+	 */

+	boolean add(IResource resource, IResource rootResource,

+			IURIResolver resolver);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceQuerySpecification.java
new file mode 100644
index 0000000..070c8f7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceQuerySpecification.java
@@ -0,0 +1,23 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;

+

+public interface IResourceQuerySpecification extends IResourceProvider,

+		IResourceRequestorProvider, IURIResolverProvider, IMultiResourceProvider {

+

+	public static final IResourceQuerySpecification[] EMPTY = new IResourceQuerySpecification[0];

+	

+	boolean isMultiResource();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestor.java
new file mode 100644
index 0000000..096ed7a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestor.java
@@ -0,0 +1,66 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+

+/**

+ * Resource requestor is used when search is started. Search loop for each

+ * container and files and call a requestor to know if the resource is accepted

+ * for the search result or not. If the resource is accepted, it is added by

+ * using a a {@link IResourceCollector}.

+ * 

+ * @author Angelo ZERR

+ * 

+ */

+public interface IResourceRequestor {

+

+	/**

+	 * Returns true if resource can be accepted or not.

+	 * 

+	 * @param selectedNode

+	 *            the selected node which has start the search.

+	 * @param rootResource

+	 *            the root resource where search start (which is returned with

+	 *            {@link IResourceProvider}).

+	 * @param resource

+	 *            the resource to accept or not.

+	 * @param resolver

+	 *            the resolver.

+	 * @param matching

+	 *            the matching string used for the search.

+	 * @param fullMatch

+	 *            true if full match must be done (ex : for validation,

+	 *            hyperlink) and false otherwise (ex : autocompletion).

+	 * @return

+	 */

+	boolean accept(Object selectedNode, IResource rootResource,

+			IResource resource, IURIResolver resolver, String matching,

+			boolean fullMatch);

+

+	/**

+	 * Returns true if files can be added to the collector

+	 * {@link IResourceCollector} and false otherwise.

+	 * 

+	 * @return

+	 */

+	boolean acceptFile();

+

+	/**

+	 * Returns true if container (folder, project...) can be added to the

+	 * collector {@link IResourceCollector} and false otherwise.

+	 * 

+	 * @return

+	 */

+	boolean acceptContainer();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestorProvider.java
new file mode 100644
index 0000000..e8bf375
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceRequestorProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+/**

+ * A provider to returns {@link IResourceRequestor}.

+ * 

+ */

+public interface IResourceRequestorProvider {

+

+	/**

+	 * Resource requestor to use.

+	 * 

+	 * @return

+	 */

+	IResourceRequestor getRequestor();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceSearchEngine.java
new file mode 100644
index 0000000..e7e7f38
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IResourceSearchEngine.java
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+public interface IResourceSearchEngine {

+

+	IStatus search(Object selectedNode, IResource[] containers, IResourceRequestor requestor,

+			IResourceCollector collector, IURIResolver resolver, String matching, boolean fullMatch,

+			IProgressMonitor monitor);

+	

+	IStatus search(Object selectedNode, IResource container, IResourceRequestor requestor,

+			IResourceCollector collector, IURIResolver resolver, String matching, boolean fullMatch,

+			IProgressMonitor monitor);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolver.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolver.java
new file mode 100644
index 0000000..6835b5a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolver.java
@@ -0,0 +1,28 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+public interface IURIResolver {

+

+	String resolve(Object selectedNode, IResource rootContainer,

+			IResource file);

+

+	boolean accept(Object selectedNode, IResource rootContainer,

+			IResource file, String matching, boolean fullMatch);

+

+	<T extends IResource> T getResource(IContainer container,

+			String resourceName, Class<T> clazz);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolverProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolverProvider.java
new file mode 100644
index 0000000..a433fe2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/IURIResolverProvider.java
@@ -0,0 +1,19 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IFile;

+

+public interface IURIResolverProvider {

+

+	IURIResolver getURIResolver(IFile file, Object selectedNode);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceBaseURIResolver.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceBaseURIResolver.java
new file mode 100644
index 0000000..4e35826
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceBaseURIResolver.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+

+public class ResourceBaseURIResolver extends AbstractURIResolver {

+

+	public static final ResourceBaseURIResolver INSTANCE = new ResourceBaseURIResolver();

+

+	public String resolve(Object selectedNode, IResource rootContainer,

+			IResource file) {

+		IContainer container = null;

+		if (rootContainer.getType() == IResource.FILE) {

+			container = ((IFile) rootContainer).getParent();

+		} else {

+			container = ((IContainer) rootContainer);

+		}

+		return file

+				.getProjectRelativePath()

+				.removeFirstSegments(

+						container.getProjectRelativePath().segmentCount())

+				.toString();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceQuerySpecificationManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceQuerySpecificationManager.java
new file mode 100644
index 0000000..98319a0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceQuerySpecificationManager.java
@@ -0,0 +1,119 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.internal.Trace;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.internal.resource.ResourceQuerySpecification;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+

+public class ResourceQuerySpecificationManager extends AbstractRegistryManager {

+

+	private static final ResourceQuerySpecificationManager INSTANCE = new ResourceQuerySpecificationManager();

+	private static final String RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT = "resourceQuerySpecifications";

+	private Map<String, IResourceQuerySpecification> querySpecificationsById = null;

+

+	public static ResourceQuerySpecificationManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (querySpecificationsById == null) // not loaded yet

+			return;

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addQuerySpecifications(querySpecificationsById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	public IResourceQuerySpecification getQuerySpecification(

+			String querySpecificationId) {

+		if (StringUtils.isEmpty(querySpecificationId)) {

+			return ResourceQuerySpecification.DEFAULT;

+		}

+		if (querySpecificationsById == null) {

+			loadQuerySpecifications();

+		}

+

+		IResourceQuerySpecification querySpecification = querySpecificationsById

+				.get(querySpecificationId);

+		if (querySpecification == null) {

+			querySpecification = ResourceQuerySpecification.DEFAULT;

+			querySpecificationsById.put(querySpecificationId, querySpecification);

+		}

+		return querySpecification;

+	}

+

+	private synchronized void loadQuerySpecifications() {

+		if (querySpecificationsById != null) {

+			return;

+		}

+

+		Map<String, IResourceQuerySpecification> querySpecificationsById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchCorePlugin.PLUGIN_ID,

+					RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT);

+			querySpecificationsById = new HashMap<String, IResourceQuerySpecification>(

+					cf.length);

+			addQuerySpecifications(querySpecificationsById, cf);

+		} else {

+			querySpecificationsById = new HashMap<String, IResourceQuerySpecification>();

+		}

+		this.querySpecificationsById = querySpecificationsById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	private synchronized void addQuerySpecifications(

+			Map<String, IResourceQuerySpecification> querySpecificationsById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		IResourceQuerySpecification querySpecification = null;

+		for (IConfigurationElement ce : cf) {

+			// querySpecification declaration,

+			id = ce.getAttribute("id");

+			try {

+				querySpecification = ResourceQuerySpecification

+						.newQuerySpecification(ce

+								.createExecutableExtension("class"));

+				querySpecificationsById.put(id, querySpecification);

+			} catch (Throwable t) {

+				Trace.trace(Trace.SEVERE,

+						"  Could not load querySpecification for id: " + id, t);

+			}

+		}

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchCorePlugin.PLUGIN_ID;

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return RESOURCE_QUERY_SPECIFICATIONS_EXTENSION_POINT;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceSearchEngine.java
new file mode 100644
index 0000000..723407b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/resource/ResourceSearchEngine.java
@@ -0,0 +1,105 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.resource;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.wst.xml.search.core.internal.Trace;

+

+public class ResourceSearchEngine implements IResourceSearchEngine {

+

+	private static final IResourceSearchEngine INSTANCE = new ResourceSearchEngine();

+

+	public static IResourceSearchEngine getDefault() {

+		return INSTANCE;

+	}

+

+	public IStatus search(Object selectedNode, IResource[] containers,

+			IResourceRequestor requestor, IResourceCollector collector,

+			IURIResolver resolver, String matching, boolean fullMatch,

+			IProgressMonitor monitor) {

+		for (int i = 0; i < containers.length; i++) {

+			IResource resource = containers[i];

+			internalSearch(selectedNode, resource, containers[i], requestor,

+					collector, resolver, matching, fullMatch, monitor);

+		}

+		return Status.OK_STATUS;

+	}

+

+	public IStatus search(Object selectedNode, IResource container,

+			IResourceRequestor requestor, IResourceCollector collector,

+			IURIResolver resolver, String matching, boolean fullMatch,

+			IProgressMonitor monitor) {

+		internalSearch(selectedNode, container, container, requestor,

+				collector, resolver, matching, fullMatch, monitor);

+		return Status.OK_STATUS;

+	}

+

+	private void internalSearch(Object selectedNode, IResource rootContainer,

+			IResource container, IResourceRequestor requestor,

+			IResourceCollector collector, IURIResolver resolver,

+			String matching, boolean fullMatch, IProgressMonitor monitor) {

+		if (!requestor.accept(selectedNode, rootContainer, container, resolver,

+				matching, fullMatch))

+			return;

+		int resourceType = container.getType();

+		switch (resourceType) {

+		case IResource.FILE:

+			if (requestor.acceptFile()) {

+				collector.add(container, rootContainer, resolver);

+			}

+			break;

+		case IResource.ROOT:

+		case IResource.PROJECT:

+		case IResource.FOLDER:

+			try {

+				if (requestor.acceptContainer()) {

+					if (!fullMatch) {

+						if (resolver

+								.resolve(selectedNode, rootContainer, container)

+								.toUpperCase()

+								.startsWith(matching.toUpperCase())) {

+							collector.add(container, rootContainer, resolver);

+						}

+					} else {

+						if (resolver.resolve(selectedNode, rootContainer,

+								container).equals(matching)) {

+							collector.add(container, rootContainer, resolver);

+						}

+					}

+				}

+				internalSearch(selectedNode, rootContainer,

+						((IContainer) container).members(), requestor,

+						collector, resolver, matching, fullMatch, monitor);

+			} catch (CoreException e) {

+				Trace.trace(Trace.SEVERE, e.getMessage(), e);

+			}

+			break;

+		}

+	}

+

+	private IStatus internalSearch(Object selectedNode,

+			IResource rootContainer, IResource[] containers,

+			IResourceRequestor requestor, IResourceCollector collector,

+			IURIResolver resolver, String matching, boolean fullMatch,

+			IProgressMonitor monitor) {

+		for (int i = 0; i < containers.length; i++) {

+			internalSearch(selectedNode, rootContainer, containers[i],

+					requestor, collector, resolver, matching, fullMatch,

+					monitor);

+		}

+		return Status.OK_STATUS;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/DefaultStaticValueVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/DefaultStaticValueVisitor.java
new file mode 100644
index 0000000..bb0bb7a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/DefaultStaticValueVisitor.java
@@ -0,0 +1,53 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+import java.util.HashMap;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.Set;

+

+import org.eclipse.core.resources.IFile;

+

+public class DefaultStaticValueVisitor implements IStaticValueVisitor {

+

+	private Map<String, IStaticValue> values = new HashMap<String, IStaticValue>();

+

+	public void registerValue(String key, String description) {

+		registerValue(new StaticValue(key, description));

+	}

+

+	public void registerValue(IStaticValue staticValue) {

+		values.put(staticValue.getKey(), staticValue);

+	}

+

+	public void clearValues() {

+		values.clear();

+	}

+

+	public void visit(Object selectedNode, IFile file, String matching,

+			boolean startsWith, IStaticValueCollector collector) {

+		if (startsWith) {

+			Set<Entry<String, IStaticValue>> entries = values.entrySet();

+			for (Entry<String, IStaticValue> entry : entries) {

+				if (entry.getKey().startsWith(matching)) {

+					collector.add(entry.getValue());

+				}

+			}

+		} else {

+			IStaticValue value = values.get(matching);

+			if (value != null) {

+				collector.add(value);

+			}

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValue.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValue.java
new file mode 100644
index 0000000..eefa491
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValue.java
@@ -0,0 +1,18 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+public interface IStaticValue {

+

+	public String getKey();

+

+	public String getDescription();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueCollector.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueCollector.java
new file mode 100644
index 0000000..d8bc787
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueCollector.java
@@ -0,0 +1,16 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+public interface IStaticValueCollector {

+

+	boolean add(IStaticValue value);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueQuerySpecification.java
new file mode 100644
index 0000000..39b0884
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueQuerySpecification.java
@@ -0,0 +1,15 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+public interface IStaticValueQuerySpecification extends IStaticValueVisitorProvider {

+	

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueSearchEngine.java
new file mode 100644
index 0000000..6411eed
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueSearchEngine.java
@@ -0,0 +1,22 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+

+public interface IStaticValueSearchEngine {

+

+	IStatus search(Object selectedNode, IFile file, IStaticValueVisitor visitor,

+			IStaticValueCollector collector, String matching,

+			boolean startsWith, IProgressMonitor monitor);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitor.java
new file mode 100644
index 0000000..5fec77c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitor.java
@@ -0,0 +1,20 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+import org.eclipse.core.resources.IFile;

+

+public interface IStaticValueVisitor {

+

+	void visit(Object selectedNode, IFile file, String matching, boolean startsWith,

+			IStaticValueCollector collector);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitorProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitorProvider.java
new file mode 100644
index 0000000..884efe9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/IStaticValueVisitorProvider.java
@@ -0,0 +1,18 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+import org.eclipse.core.resources.IFile;

+

+public interface IStaticValueVisitorProvider {

+

+	IStaticValueVisitor getVisitor(Object selectedNode, IFile file);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValue.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValue.java
new file mode 100644
index 0000000..a636de0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValue.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+public class StaticValue implements IStaticValue {

+

+	private final String key;

+	private final String description;

+

+	public StaticValue(String key, String description) {

+		this.key = key;

+		this.description = description;

+	}

+

+	public String getKey() {

+		return key;

+	}

+

+	public String getDescription() {

+		return description;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueQuerySpecificationManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueQuerySpecificationManager.java
new file mode 100644
index 0000000..942c00d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueQuerySpecificationManager.java
@@ -0,0 +1,121 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.internal.Trace;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.internal.statics.StaticValueQuerySpecification;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+

+public class StaticValueQuerySpecificationManager extends

+		AbstractRegistryManager {

+

+	private static final StaticValueQuerySpecificationManager INSTANCE = new StaticValueQuerySpecificationManager();

+	private static final String XML_QUERY_SPECIFICATIONS_EXTENSION_POINT = "staticValueQuerySpecifications";

+	private Map<String, IStaticValueQuerySpecification> querySpecificationsById = null;

+

+	public static StaticValueQuerySpecificationManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (querySpecificationsById == null) // not loaded yet

+			return;

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addQuerySpecifications(querySpecificationsById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	public IStaticValueQuerySpecification getQuerySpecification(

+			String querySpecificationId) {

+		if (StringUtils.isEmpty(querySpecificationId)) {

+			return null;

+		}

+		if (querySpecificationsById == null) {

+			loadQuerySpecifications();

+		}

+

+		IStaticValueQuerySpecification querySpecification = querySpecificationsById

+				.get(querySpecificationId);

+		if (querySpecification == null) {

+			querySpecificationsById.put(querySpecificationId, querySpecification);

+		}

+		return querySpecification;

+	}

+

+	private synchronized void loadQuerySpecifications() {

+		if (querySpecificationsById != null) {

+			return;

+		}

+

+		Map<String, IStaticValueQuerySpecification> querySpecificationsById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchCorePlugin.PLUGIN_ID,

+					XML_QUERY_SPECIFICATIONS_EXTENSION_POINT);

+			querySpecificationsById = new HashMap<String, IStaticValueQuerySpecification>(

+					cf.length);

+			addQuerySpecifications(querySpecificationsById, cf);

+		} else {

+			querySpecificationsById = new HashMap<String, IStaticValueQuerySpecification>();

+		}

+		this.querySpecificationsById = querySpecificationsById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	private synchronized void addQuerySpecifications(

+			Map<String, IStaticValueQuerySpecification> querySpecificationsById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		IStaticValueQuerySpecification querySpecification = null;

+		for (IConfigurationElement ce : cf) {

+			// querySpecification declaration,

+			id = ce.getAttribute("id");

+			try {

+				querySpecification = StaticValueQuerySpecification

+						.newQuerySpecification(ce

+								.createExecutableExtension("class"));

+				if (querySpecification != null) {

+					querySpecificationsById.put(id, querySpecification);

+				}

+			} catch (Throwable t) {

+				Trace.trace(Trace.SEVERE,

+						"  Could not load querySpecification for id: " + id, t);

+			}

+		}

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchCorePlugin.PLUGIN_ID;

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return XML_QUERY_SPECIFICATIONS_EXTENSION_POINT;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueSearchEngine.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueSearchEngine.java
new file mode 100644
index 0000000..fc7e15f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/statics/StaticValueSearchEngine.java
@@ -0,0 +1,31 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.statics;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+

+public class StaticValueSearchEngine implements IStaticValueSearchEngine {

+

+	private static IStaticValueSearchEngine INSTANCE = new StaticValueSearchEngine();

+

+	public IStatus search(Object selectedNode, IFile file, IStaticValueVisitor visitor, IStaticValueCollector collector,

+			String matching, boolean startsWith, IProgressMonitor monitor) {

+		visitor.visit(selectedNode, file, matching, startsWith, collector);

+		return null;

+	}

+

+	public static IStaticValueSearchEngine getDefault() {

+		return INSTANCE;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageLocationProvider.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageLocationProvider.java
new file mode 100644
index 0000000..7def379
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageLocationProvider.java
@@ -0,0 +1,18 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.storage;

+

+import org.eclipse.core.resources.IStorage;

+

+public interface IStorageLocationProvider {

+

+	String getLocation(IStorage storage);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageModelManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageModelManager.java
new file mode 100644
index 0000000..126ec64
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/IStorageModelManager.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.storage;

+

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+

+public interface IStorageModelManager {

+

+	IStructuredModel getModel(IStorage storage);

+	

+	IStructuredModel loadModel(IStorage storage);

+	

+	IStorage getStorage(IStructuredModel model);

+	

+	void setStorageLocationProvider(IStorageLocationProvider locationProvider);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/StructuredStorageModelManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/StructuredStorageModelManager.java
new file mode 100644
index 0000000..9170508
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/storage/StructuredStorageModelManager.java
@@ -0,0 +1,33 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.storage;

+

+import org.eclipse.wst.xml.search.core.internal.storage.StorageModelManager;

+

+final public class StructuredStorageModelManager {

+

+	/**

+	 * Do not allow instances to be created.

+	 */

+	private StructuredStorageModelManager() {

+		super();

+	}

+

+	/**

+	 * Provides access to the instance of {@link IStorageModelManager}.

+	 * 

+	 * @return {@link IStorageModelManager} - returns the one model manager for

+	 *         structured model

+	 */

+	public static IStorageModelManager getModelManager() {

+		return StorageModelManager.INSTANCE;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/DOMUtils.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/DOMUtils.java
new file mode 100644
index 0000000..181a87a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/DOMUtils.java
@@ -0,0 +1,565 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.util;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Collections;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IWorkspaceRoot;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IPath;

+import org.eclipse.core.runtime.Path;

+import org.eclipse.jface.text.IDocument;

+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.IStructuredDocumentRegion;

+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;

+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.NamedNodeMap;

+import org.w3c.dom.Node;

+import org.w3c.dom.NodeList;

+import org.w3c.dom.Text;

+

+/**

+ * Utilities for SSE DOM node {@link IDOMNode}.

+ * 

+ */

+public class DOMUtils {

+

+	/**

+	 * Returns the SSE DOM Node {@link IDOMNode} by offset from the

+	 * {@link IDocument} document and null if not found.

+	 * 

+	 * @param document

+	 *            the document.

+	 * @param offset

+	 *            the offset.

+	 * @return

+	 */

+	public static final IDOMNode getNodeByOffset(IDocument document, int offset) {

+		IStructuredModel model = null;

+		try {

+			model = StructuredModelManager.getModelManager()

+					.getExistingModelForRead(document);

+			return getNodeByOffset(model, offset);

+		} finally {

+			if (model != null)

+				model.releaseFromRead();

+		}

+	}

+

+	/**

+	 * Returns the SSE DOM Node {@link IDOMNode} by offset from the

+	 * {@link IStructuredModel} SSE mode and null if not found.

+	 * 

+	 * @param model

+	 *            the SSE model.

+	 * @param offset

+	 *            the offset.

+	 * @return

+	 */

+	public static final IDOMNode getNodeByOffset(IStructuredModel model,

+			int offset) {

+		if (model != null) {

+			IndexedRegion node = model.getIndexedRegion(offset);

+			if (node instanceof IDOMNode) {

+				return (IDOMNode) node;

+			}

+		}

+		return null;

+	}

+

+	/**

+	 * Returns the SSE DOM Attribute {@link IDOMAttr} by region from the SSE DOM

+	 * element {@link IDOMElement}.

+	 * 

+	 * @param element

+	 *            the SSE DOM element {@link IDOMElement}.

+	 * @param region

+	 *            the region.

+	 * @return

+	 */

+	public static IDOMAttr getAttrByRegion(IDOMNode element, ITextRegion region) {

+		IStructuredDocumentRegion structuredDocumentRegionElement = element

+				.getFirstStructuredDocumentRegion();

+

+		// 1) Get attribute name region

+		ITextRegionList elementRegions = structuredDocumentRegionElement

+				.getRegions();

+		int index = elementRegions.indexOf(region);

+		if (index < 0) {

+			return null;

+		}

+

+		ITextRegion attrNameRegion = null;

+		while (index >= 0) {

+			attrNameRegion = elementRegions.get(index--);

+			if (attrNameRegion.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {

+				break;

+			}

+		}

+		if (attrNameRegion == null) {

+			return null;

+		}

+		String attrName = structuredDocumentRegionElement

+				.getText(attrNameRegion);

+		return (IDOMAttr) element.getAttributes().getNamedItem(attrName);

+	}

+

+	/**

+	 * Returns the SSE DOM Attribute {@link IDOMAttr} by offset from the SSE DOM

+	 * node {@link IDOMNode}.

+	 * 

+	 * @param element

+	 *            the SSE DOM element {@link IDOMElement}.

+	 * @param region

+	 *            the region.

+	 * @return

+	 */

+	public static final IDOMAttr getAttrByOffset(Node node, int offset) {

+		if ((node instanceof IndexedRegion)

+				&& ((IndexedRegion) node).contains(offset)

+				&& node.hasAttributes()) {

+			NamedNodeMap attrs = node.getAttributes();

+			for (int i = 0; i < attrs.getLength(); i++) {

+				IndexedRegion attRegion = (IndexedRegion) attrs.item(i);

+				if (attRegion.contains(offset))

+					return (IDOMAttr) attrs.item(i);

+			}

+

+		}

+		return null;

+	}

+

+	/**

+	 * Returns the owner file of the SSE DOM Node {@link IDOMNode}.

+	 * 

+	 * @param node

+	 *            the SSE DOM Node.

+	 * @return

+	 */

+	public static final IFile getFile(IDOMNode node) {

+		return getFile(node.getModel());

+	}

+

+	/**

+	 * Returns the owner file of the JFace document {@link IDocument}.

+	 * 

+	 * @param document

+	 * @return

+	 */

+	public static final IFile getFile(IDocument document) {

+		if (document == null) {

+			return null;

+		}

+		IStructuredModel model = null;

+		try {

+			model = StructuredModelManager.getModelManager()

+					.getExistingModelForRead(document);

+			if (model != null) {

+				return getFile(model);

+			}

+		} finally {

+			if (model != null)

+				model.releaseFromRead();

+		}

+		return null;

+	}

+

+	/**

+	 * Returns the owner file of the SSE model {@link IStructuredModel}.

+	 * 

+	 * @param node

+	 *            the SSE model.

+	 * @return

+	 */

+	public static final IFile getFile(IStructuredModel model) {

+		String baselocation = model.getBaseLocation();

+		if (baselocation != null) {

+			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();

+			IPath filePath = new Path(baselocation);

+			if (filePath.segmentCount() > 1) {

+				return root.getFile(filePath);

+			}

+		}

+		return null;

+	}

+

+	/**

+	 * Returns the owner file name of the SSE model {@link IDOMNode}.

+	 * 

+	 * @param node

+	 * @return

+	 */

+	public static final String getFileName(IDOMNode node) {

+		return getFileName(node.getModel());

+	}

+

+	/**

+	 * Returns the owner file name of the SSE model {@link IStructuredModel}.

+	 * 

+	 * @param model

+	 * @return

+	 */

+	public static final String getFileName(IStructuredModel model) {

+		String baselocation = model.getBaseLocation();

+		if (baselocation != null) {

+			int index = baselocation.lastIndexOf('/');

+			if (index == -1) {

+				index = baselocation.lastIndexOf('\\');

+			}

+			if (index == -1) {

+				return baselocation;

+			}

+			return baselocation.substring(index + 1, baselocation.length());

+		}

+		return null;

+	}

+

+	/**

+	 * Returns the node value from the DOM NOde.

+	 * 

+	 * @param node

+	 * @return

+	 */

+	public static String getNodeValue(Node node) {

+		if (node == null) {

+			return null;

+		}

+		short nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			return ((Attr) node).getValue();

+		case Node.TEXT_NODE:

+			return getTextContent((Text) node);

+		}

+		return node.getNodeValue();

+	}

+

+	/**

+	 * Returns the normalized text content of DOM text node.

+	 * 

+	 * @param text

+	 * @return

+	 */

+	public static String getTextContent(Text text) {

+		return getTextContent(text, true);

+	}

+

+	/**

+	 * Returns the text content of DOM text node.

+	 * 

+	 * @param text

+	 * @return

+	 */

+	public static String getTextContent(Text text, boolean normalize) {

+		if (normalize) {

+			return StringUtils.normalizeSpace(text.getData());

+		}

+		return text.getData();

+	}

+

+	/**

+	 * Returns the first child element retrieved by tag name from the parent

+	 * node and null otherwise.

+	 * 

+	 * @param parentNode

+	 *            parent node.

+	 * @param elementName

+	 *            element name to found.

+	 * @return the first child element

+	 */

+	public static Element getFirstChildElementByTagName(Node parentNode,

+			String elementName) {

+		Element result = null;

+

+		if (parentNode.getNodeType() == Node.DOCUMENT_NODE) {

+			result = ((Document) parentNode).getDocumentElement();

+			if (!result.getNodeName().equals(elementName)) {

+				result = null;

+			}

+		} else {

+			NodeList nodes = parentNode.getChildNodes();

+			Node node;

+			for (int i = 0; i < nodes.getLength(); i++) {

+				node = nodes.item(i);

+				if (node.getNodeType() == Node.ELEMENT_NODE

+						&& node.getNodeName().equals(elementName)) {

+					result = (Element) node;

+					break;

+				}

+			}

+		}

+		return result;

+	}

+

+	/**

+	 * Returns list of the first child element retrieved by tag name from the

+	 * parent node and null otherwise.

+	 * 

+	 * @param parentNode

+	 *            parent node.

+	 * @param elementName

+	 *            element name to found.

+	 * @return list of the first child element

+	 */

+	public static Collection<Element> getFirstChildElementsByTagName(

+			Node contextNode, String elementName) {

+		Collection<Element> elements = null;

+		Element result = null;

+

+		if (contextNode.getNodeType() == Node.DOCUMENT_NODE) {

+			result = ((Document) contextNode).getDocumentElement();

+			if (!result.getNodeName().equals(elementName)) {

+				result = null;

+			}

+		} else {

+			NodeList nodes = contextNode.getChildNodes();

+			Node node;

+			for (int i = 0; i < nodes.getLength(); i++) {

+				node = nodes.item(i);

+				if (node.getNodeType() == Node.ELEMENT_NODE

+						&& node.getNodeName().equals(elementName)) {

+					if (elements == null) {

+						elements = new ArrayList<Element>();

+					}

+					result = (Element) node;

+					elements.add(result);

+				}

+			}

+		}

+		if (elements == null) {

+			return Collections.emptyList();

+		}

+		return elements;

+	}

+

+	/**

+	 * Returns the SSE DOM attribute by name from the ownner element.

+	 * 

+	 * @param element

+	 * @param attrName

+	 * @return

+	 */

+	public static IDOMAttr getAttr(IDOMElement element, String attrName) {

+		if (StringUtils.isEmpty(attrName)) {

+			return null;

+		}

+		String prefix = element.getPrefix();

+		if (!StringUtils.isEmpty(prefix)) {

+			String namespaceURI = element.getNamespaceURI();

+			IDOMAttr attr = (IDOMAttr) element.getAttributeNodeNS(namespaceURI,

+					attrName);

+			if (attr != null) {

+				return attr;

+			}

+		}

+		return (IDOMAttr) element.getAttributeNode(attrName);

+	}

+

+	/**

+	 * Returns the first child Text node from the parentNode and null otherwise.

+	 * 

+	 * @param parentNode

+	 * @return

+	 */

+	public static Text getTextNode(Node parentNode) {

+		if (parentNode == null)

+			return null;

+

+		Node result = null;

+		parentNode.normalize();

+		NodeList nodeList;

+		if (parentNode.getNodeType() == Node.DOCUMENT_NODE) {

+			nodeList = ((Document) parentNode).getDocumentElement()

+					.getChildNodes();

+		} else {

+			nodeList = parentNode.getChildNodes();

+		}

+		int len = nodeList.getLength();

+		if (len == 0) {

+			return null;

+		}

+		for (int i = 0; i < len; i++) {

+			result = nodeList.item(i);

+			if (result.getNodeType() == Node.TEXT_NODE) {

+				return (Text) result;

+			} else if (result.getNodeType() == Node.CDATA_SECTION_NODE) {

+				return /* (CDATASection) */(Text) result;

+			}

+		}

+		return null;

+	}

+

+	/**

+	 * Returns the content of the the first child Text node from the parentNode

+	 * and null otherwise.

+	 * 

+	 * @param node

+	 * @return

+	 */

+	public static String getTextNodeAsString(Node parentNode) {

+		if (parentNode == null)

+			return null;

+

+		Node txt = getTextNode(parentNode);

+		if (txt == null)

+			return null;

+

+		return txt.getNodeValue();

+	}

+

+	/**

+	 * Returns the content type id of the SSE DOM Node.

+	 * 

+	 * @param node

+	 * @return

+	 */

+	public static String getContentTypeId(IDOMNode node) {

+		if (node == null) {

+			return null;

+		}

+		return node.getModel().getContentTypeIdentifier();

+	}

+

+	/**

+	 * Returns true if content type id of the SSE DOM Node match a

+	 * contentTypeId.

+	 * 

+	 * @param node

+	 * @param contentTypeId

+	 * @return

+	 */

+	public static boolean isContentTypeId(IDOMNode selectedNode,

+			String[] contentTypeIds) {

+		for (int i = 0; i < contentTypeIds.length; i++) {

+			if (DOMUtils.isContentTypeId(selectedNode, contentTypeIds[i])) {

+				return true;

+			}

+		}

+		return false;

+	}

+	

+	/**

+	 * Returns true if content type id of the SSE DOM Node match a

+	 * contentTypeId.

+	 * 

+	 * @param node

+	 * @param contentTypeId

+	 * @return

+	 */

+	public static boolean isContentTypeId(IDOMNode node, String contentTypeId) {

+		if (contentTypeId == null) {

+			return false;

+		}

+		String nodeContentTypeId = getContentTypeId(node);

+		return contentTypeId.equals(nodeContentTypeId);

+	}

+

+	/**

+	 * Returns the content type id of the file by using SSE DOM Model.

+	 * 

+	 * @param file

+	 * @return

+	 */

+	public static String getStructuredModelContentTypeId(IFile file) {

+		IStructuredModel model = null;

+		try {

+			model = StructuredModelManager.getModelManager()

+					.getExistingModelForRead(file);

+			if (model == null) {

+				model = StructuredModelManager.getModelManager()

+						.getModelForRead(file);

+			}

+			if (model != null) {

+				return model.getContentTypeIdentifier();

+			}

+		} catch (IOException e) {

+			return null;

+		} catch (CoreException e) {

+			return null;

+		} finally {

+			if (model != null) {

+				model.releaseFromRead();

+			}

+		}

+		return null;

+	}

+

+	/**

+	 * Returns true if file match an item of the contentTypeIds list and false

+	 * otherwise.

+	 * 

+	 * @param file

+	 * @param contentTypeIds

+	 * @return

+	 */

+	public static boolean isContentTypeId(IFile file,

+			Collection<String> contentTypeIds) {

+		if (contentTypeIds == null) {

+			return false;

+		}

+		String structuredModelContentTypeId = getStructuredModelContentTypeId(file);

+		if (structuredModelContentTypeId == null) {

+			return false;

+		}

+		return contentTypeIds.contains(structuredModelContentTypeId);

+	}

+

+	/**

+	 * Returns true if file match the contentTypeId and false otherwise.

+	 * 

+	 * @param file

+	 * @param contentTypeId

+	 * @return

+	 */

+	public static boolean isContentTypeId(IFile file, String contentTypeId) {

+		if (contentTypeId == null) {

+			return false;

+		}

+		String structuredModelContentTypeId = getStructuredModelContentTypeId(file);

+		if (structuredModelContentTypeId == null) {

+			return false;

+		}

+		return contentTypeId.equals(structuredModelContentTypeId);

+	}

+

+	/**

+	 * Returns the owner element of the node and null if not found.

+	 * 

+	 * @param node

+	 * @return

+	 */

+	public static Element getOwnerElement(Node node) {

+		int nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			return ((Attr) node).getOwnerElement();

+		case Node.TEXT_NODE:

+			return (Element) ((Text) node).getParentNode();

+		case Node.ELEMENT_NODE:

+			return (Element) node;

+		}

+		return null;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/FileUtils.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/FileUtils.java
new file mode 100644
index 0000000..009ebfd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/FileUtils.java
@@ -0,0 +1,72 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.util;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.core.runtime.content.IContentDescription;

+import org.eclipse.core.runtime.content.IContentType;

+import org.eclipse.wst.xml.core.internal.provisional.contenttype.ContentTypeIdForXML;

+

+/**

+ * 

+ * Utilities for {@link IFile}.

+ * 

+ */

+public class FileUtils {

+

+	/**

+	 * Returns true if file name is associated with XML content type

+	 * "org.eclipse.core.runtime.xml" and false otherwise.

+	 * 

+	 * @param filename

+	 *            file name to test.

+	 * @return true if file name is associated with XML content type and false

+	 *         otherwise.

+	 */

+	public static boolean isXMLFile(String fileName) {

+		IContentType contentType = Platform.getContentTypeManager()

+				.getContentType(ContentTypeIdForXML.ContentTypeID_XML);

+		return contentType.isAssociatedWith(fileName);

+	}

+

+	/**

+	 * Returns true if file is associated with XML content type

+	 * "org.eclipse.core.runtime.xml" and false otherwise.

+	 * 

+	 * @param file

+	 *            file to test.

+	 * @return true if file is associated with XML content type and false

+	 *         otherwise.

+	 */

+	public static boolean isXMLFile(IFile file) {

+		return isXMLFile(file.getName());

+	}

+

+	public static String getContentTypeId(IFile file) {

+		try {

+			IContentDescription contentDescription = file

+					.getContentDescription();

+			if (contentDescription == null) {

+				return null;

+			}

+			IContentType contentType = contentDescription.getContentType();

+			if (contentType == null) {

+				return null;

+			}

+			return contentType.getId();

+

+		} catch (CoreException e) {

+		}

+		return null;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/StringUtils.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/StringUtils.java
new file mode 100644
index 0000000..58c8ebd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/util/StringUtils.java
@@ -0,0 +1,95 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.util;

+

+/**

+ * 

+ * Utilities for {@link String}.

+ * 

+ */

+public class StringUtils {

+

+	public static final String[] EMPTY_ARRAY = new String[0];

+

+	public static boolean isEmpty(String str) {

+		return str == null || str.length() == 0;

+	}

+

+	public static boolean hasLength(CharSequence str) {

+		return str != null && str.length() > 0;

+	}

+

+	public static boolean hasLength(String str) {

+		return hasLength(((CharSequence) (str)));

+	}

+

+	public static boolean hasText(CharSequence str) {

+		if (!hasLength(str))

+			return false;

+		int strLen = str.length();

+		for (int i = 0; i < strLen; i++)

+			if (!Character.isWhitespace(str.charAt(i)))

+				return true;

+

+		return false;

+	}

+

+	public static boolean hasText(String str) {

+		return hasText(((CharSequence) (str)));

+	}

+

+	public static boolean isQuoted(String string) {

+		if (string == null || string.length() < 2)

+			return false;

+		int lastIndex = string.length() - 1;

+		char firstChar = string.charAt(0);

+		char lastChar = string.charAt(lastIndex);

+		return firstChar == '\'' && lastChar == '\'' || firstChar == '"'

+				&& lastChar == '"';

+	}

+

+	public static String normalizeSpace(String s) {

+		if (s == null) {

+			return null;

+		}

+		int len = s.length();

+		if (len < 1) {

+			return "";

+		}

+		int st = 0;

+		int off = 0;      /* avoid getfield opcode */

+		char[] val = s.toCharArray();    /* avoid getfield opcode */

+		int count = s.length();

+		

+		boolean parse = true;

+		char c;

+		while (parse) {

+			c = val[off + st];

+			parse = isParse(len, st, c);

+			if (parse) {

+				st++;

+			}

+		}

+		parse = true;

+		while ((st < len) && (val[off + len - 1] <= ' ')) {

+			c = val[off + len - 1];

+			parse = isParse(len, st, c);

+			if (parse) {

+				len--;

+			}

+		}

+		return ((st > 0) || (len < count)) ? s.substring(st, len) : s;

+	}

+

+	private static boolean isParse(int len, int st, char c) {

+		return (st < len) && (c == ' ' || c == '\r' || c == '\n' || c == '\t');

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessor.java
new file mode 100644
index 0000000..61a1e98
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessor.java
@@ -0,0 +1,32 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath;

+

+import java.text.MessageFormat;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+

+public abstract class AbstractXPathProcessor implements IXPathProcessor {

+

+	public String computeXPath(String xpath, String... args) {

+		if (args == null || args.length < 1) {

+			return xpath;

+		}

+		return MessageFormat.format(xpath, (Object[]) args);

+	}

+	

+	protected IStatus createStatusForXPathNotValid(String xpath, String pluginId, Throwable e) {

+		return new Status(IStatus.ERROR, pluginId, "Error XPath parsing",

+				e);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessorForXPathFactory.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessorForXPathFactory.java
new file mode 100644
index 0000000..ae293db
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/AbstractXPathProcessorForXPathFactory.java
@@ -0,0 +1,122 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import javax.xml.namespace.QName;

+import javax.xml.xpath.XPath;

+import javax.xml.xpath.XPathConstants;

+import javax.xml.xpath.XPathExpression;

+import javax.xml.xpath.XPathExpressionException;

+import javax.xml.xpath.XPathFactory;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.w3c.dom.Node;

+import org.w3c.dom.NodeList;

+

+public abstract class AbstractXPathProcessorForXPathFactory extends

+		AbstractXPathProcessor {

+

+	/**

+	 * XPath expressions cache

+	 */

+	private Map<String, XPathExpression> expressions = new HashMap<String, XPathExpression>();

+

+	private XPathFactory factory;

+

+	public NodeList evaluateNodeSet(Object source, String xpath,

+			NamespaceInfos namespaceInfo, String... criteria)

+			throws XPathExpressionException {

+		return (NodeList) evaluate(source, XPathConstants.NODESET, xpath,

+				namespaceInfo, criteria);

+	}

+

+	public String evaluateString(Object source, String xpath,

+			NamespaceInfos namespaceInfo, String... criteria) throws XPathExpressionException {

+		return (String) evaluate(source, XPathConstants.STRING, xpath,

+				namespaceInfo, criteria);

+	}

+//	public Node evaluateNode(Object source, String xpath, String... criteria)

+//			throws XPathExpressionException {

+//		return (Node) evaluate(source, XPathConstants.NODE, xpath, criteria);

+//	}

+//

+//	public Boolean evaluateBoolean(Object source, String xpath,

+//			String... criteria) throws XPathExpressionException {

+//		return (Boolean) evaluate(source, XPathConstants.BOOLEAN, xpath,

+//				criteria);

+//	}

+//

+//	public Number evaluateNumber(Object source, String xpath,

+//			String... criteria) throws XPathExpressionException {

+//		return (Number) evaluate(source, XPathConstants.NUMBER, xpath, criteria);

+//	}

+//

+//	public String evaluateString(Object source, String xpath,

+//			NamespaceInfos namespaceInfo, String... criteria)

+//			throws XPathExpressionException {

+//		return (String) evaluate(source, XPathConstants.STRING, xpath,

+//				namespaceInfo, criteria);

+//	}

+

+	public Object evaluate(Object source, QName name, String xpath,

+			NamespaceInfos namespaceInfo, String... criteria)

+			throws XPathExpressionException {

+		XPathExpression expr = getXPathExpression(xpath, namespaceInfo,

+				criteria);

+		return expr.evaluate(source, name);

+	}

+

+	protected XPathExpression getXPathExpression(String xpath,

+			NamespaceInfos namespaceInfo, String... args)

+			throws XPathExpressionException {

+		xpath = computeXPath(xpath, args);

+		XPathExpression exp = expressions.get(xpath);

+		if (exp == null) {

+			exp = createXPathExpression(xpath, namespaceInfo);

+			// expressions.put(xpath, exp);

+		}

+		return exp;

+	}

+

+	protected XPathExpression createXPathExpression(String expression,

+			NamespaceInfos namespaceInfo) throws XPathExpressionException {

+		XPath xpath = getFactory().newXPath();

+		if (namespaceInfo != null && namespaceInfo.size() > 0) {

+			xpath.setNamespaceContext(namespaceInfo);

+		}

+		XPathExpression expr = xpath.compile(expression);

+		return expr;

+	}

+

+	public IStatus validateXPath(String xpath) {

+		try {

+			createXPathExpression(xpath, null);

+		} catch (XPathExpressionException e) {

+			return createStatusForXPathNotValid(xpath,

+					XMLSearchCorePlugin.PLUGIN_ID, e);

+		}

+		return Status.OK_STATUS;

+	}

+

+	public XPathFactory getFactory() {

+		if (factory == null) {

+			factory = createFactory();

+		}

+		return factory;

+	}

+

+	protected abstract XPathFactory createFactory();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/DefaultXPathProcessor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/DefaultXPathProcessor.java
new file mode 100644
index 0000000..75acba7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/DefaultXPathProcessor.java
@@ -0,0 +1,27 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath;

+

+import javax.xml.xpath.XPathFactory;

+

+

+public class DefaultXPathProcessor extends

+		AbstractXPathProcessorForXPathFactory {

+

+	public static final IXPathProcessor INSTANCE = new DefaultXPathProcessor();

+	

+	public static final String ID = "org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor";

+

+	@Override

+	protected XPathFactory createFactory() {

+		return XPathFactory.newInstance();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathManager.java
new file mode 100644
index 0000000..0ffbc96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathManager.java
@@ -0,0 +1,60 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;

+import org.w3c.dom.Node;

+import org.w3c.dom.NodeList;

+

+public interface IXPathManager {

+

+	NodeList evaluateNodeSet(String xpathFactoryProviderId, Object source,

+			String xpath, NamespaceInfos namespaceInfo, String... criteria)

+			throws XPathExpressionException;

+

+	String evaluateString(String xpathFactoryProviderId, Object source,

+			String xpath, NamespaceInfos namespaceInfo, String... criteria)

+			throws XPathExpressionException;

+

+	NamespaceInfos getNamespaceInfo(Node node);

+

+	NamespaceInfos getNamespaceInfo(IDOMDocument document);

+

+	//

+	// Node evaluateNode(String xpathFactoryProviderId, Object source,

+	// String xpath, String... criteria) throws XPathExpressionException;

+	//

+	// Boolean evaluateBoolean(String xpathFactoryProviderId, Object source,

+	// String xpath, String... criteria) throws XPathExpressionException;

+	//

+	// Number evaluateNumber(String xpathFactoryProviderId, Object source,

+	// String xpath, String... criteria) throws XPathExpressionException;

+	//

+	// String evaluateString(String xpathFactoryProviderId, Object source,

+	// String xpath, String... criteria) throws XPathExpressionException;

+	//

+	// XPathExpression getXPathExpression(String xpathFactoryProviderId,

+	// String xpath, String... args) throws XPathExpressionException;

+	//

+	// XPathExpression createXPathExpression(String xpathFactoryProviderId,

+	// String expression) throws XPathExpressionException;

+	//

+	IStatus validateXPath(String xpathFactoryProviderId, String xpath);

+

+	String getXPath(String xpath, String... args);

+

+	//

+	String computeBasicXPath(Node node, NamespaceInfos namespaceInfos);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessor.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessor.java
new file mode 100644
index 0000000..e1cc17d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessor.java
@@ -0,0 +1,32 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.runtime.IStatus;

+import org.w3c.dom.NodeList;

+

+public interface IXPathProcessor {

+

+	String computeXPath(String xpath, String... args);

+

+	NodeList evaluateNodeSet(Object source, String xpath,

+			NamespaceInfos namespaceInfo, String... criteria)

+			throws XPathExpressionException;

+

+	String evaluateString(Object source, String xpath,

+			NamespaceInfos namespaceInfo, String... criteria)

+			throws XPathExpressionException;

+

+	IStatus validateXPath(String xpath);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessorType.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessorType.java
new file mode 100644
index 0000000..4ad1a6c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/IXPathProcessorType.java
@@ -0,0 +1,26 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath;

+

+public interface IXPathProcessorType {

+

+	public static final IXPathProcessorType[] EMPTY = new IXPathProcessorType[0];

+

+	String getId();

+

+	String getName();

+

+	IXPathProcessor getProcessor();

+

+	boolean isContributed();

+

+	String getSource();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/NamespaceInfos.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/NamespaceInfos.java
new file mode 100644
index 0000000..c830274
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/NamespaceInfos.java
@@ -0,0 +1,59 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath;

+

+import java.util.ArrayList;

+import java.util.Iterator;

+

+import javax.xml.namespace.NamespaceContext;

+

+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;

+

+public class NamespaceInfos extends ArrayList<NamespaceInfo> implements

+		NamespaceContext {

+

+	public String getPrefix(String namespaceURI) {

+		int size = super.size();

+		for (int i = 0; i < size; i++) {

+			NamespaceInfo namespaceInfo = super.get(i);

+			if (namespaceURI.equals(namespaceInfo.uri)) {

+				return getPrefix(namespaceInfo);

+			}

+		}

+		return null;

+	}

+

+	public String getNamespaceURI(String prefix) {

+		if ("ns".equals(prefix)) {

+			prefix = "";

+		}

+		int size = super.size();

+		for (int i = 0; i < size; i++) {

+			NamespaceInfo namespaceInfo = super.get(i);

+			if (prefix.equals(namespaceInfo.prefix)) {				

+				return namespaceInfo.uri;

+			}

+		}

+		return null;

+	}

+

+	public Iterator getPrefixes(String arg0) {

+		// TODO Auto-generated method stub

+		return null;

+	}

+	

+	public String getPrefix(NamespaceInfo namespaceInfo) {

+		if ("".equals(namespaceInfo.prefix)) {

+			return "ns";

+		}

+		return namespaceInfo.prefix;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathManager.java
new file mode 100644
index 0000000..d32cd5b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathManager.java
@@ -0,0 +1,279 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath;

+

+import java.text.MessageFormat;

+import java.util.Collection;

+import java.util.Map;

+import java.util.concurrent.ConcurrentHashMap;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;

+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceTable;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+import org.w3c.dom.NodeList;

+import org.w3c.dom.Text;

+

+/**

+ * XPath manager used to cache XPath expression.

+ * 

+ */

+public class XPathManager implements IXPathManager {

+

+	private static final IXPathManager INSTANCE = new XPathManager();

+

+	private Map<String, NamespaceInfos> namespaceInfo = new ConcurrentHashMap<String, NamespaceInfos>();

+

+	public static IXPathManager getManager() {

+		return INSTANCE;

+	}

+

+	public NodeList evaluateNodeSet(String xpathFactoryProviderId,

+			Object source, String xpath, NamespaceInfos namespaceInfo,

+			String... criteria) throws XPathExpressionException {

+		return getProcessor(xpathFactoryProviderId).evaluateNodeSet(source,

+				xpath, namespaceInfo, criteria);

+	}

+

+	// public Node evaluateNode(String xpathFactoryProviderId, Object source,

+	// String xpath, String... criteria) throws XPathExpressionException {

+	// return getManager(xpathFactoryProviderId).evaluateNode(source, xpath,

+	// criteria);

+	// }

+	//

+	// public Boolean evaluateBoolean(String xpathFactoryProviderId,

+	// Object source, String xpath, String... criteria)

+	// throws XPathExpressionException {

+	// return getManager(xpathFactoryProviderId).evaluateBoolean(source,

+	// xpath, criteria);

+	// }

+	//

+	// public Number evaluateNumber(String xpathFactoryProviderId, Object

+	// source,

+	// String xpath, String... criteria) throws XPathExpressionException {

+	// return getManager(xpathFactoryProviderId).evaluateNumber(source, xpath,

+	// criteria);

+	// }

+	//

+	public String evaluateString(String xpathFactoryProviderId, Object source,

+			String xpath, NamespaceInfos namespaceInfo, String... criteria)

+			throws XPathExpressionException {

+		return getProcessor(xpathFactoryProviderId).evaluateString(source,

+				xpath, namespaceInfo, criteria);

+	}

+

+	//

+	// public XPathExpression getXPathExpression(String xpathFactoryProviderId,

+	// String xpath, String... args) throws XPathExpressionException {

+	// return getManager(xpathFactoryProviderId).getXPathExpression(xpath,

+	// args);

+	// }

+	//

+	// public XPathExpression createXPathExpression(String

+	// xpathFactoryProviderId,

+	// String expression) throws XPathExpressionException {

+	// return getManager(xpathFactoryProviderId).createXPathExpression(

+	// expression);

+	// }

+

+	public String getXPath(String xpath, String... args) {

+		if (args == null || args.length < 1) {

+			return xpath;

+		}

+		return MessageFormat.format(xpath, (Object[]) args);

+	}

+

+	public String computeBasicXPath(Node node, NamespaceInfos namespaceInfos) {

+		if (node == null) {

+			return null;

+		}

+		StringBuilder xpath = new StringBuilder();

+		computeBasicXPath(node, xpath, namespaceInfos);

+		return xpath.toString();

+	}

+

+	private Node computeBasicXPath(Node node, StringBuilder xpath,

+			NamespaceInfos namespaceInfos) {

+		int nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			computeBasicXPath((Attr) node, xpath, namespaceInfos);

+			return null;

+		case Node.TEXT_NODE:

+			computeBasicXPath((Text) node, xpath, namespaceInfos);

+			return null;

+		case Node.ELEMENT_NODE:

+			return computeBasicXPath((Element) node, xpath, namespaceInfos);

+		}

+		return null;

+	}

+

+	private Node computeBasicXPath(Element element, StringBuilder xpath,

+			NamespaceInfos namespaceInfos) {

+		xpath.insert(0, element.getLocalName());

+		if (!StringUtils.isEmpty(element.getNamespaceURI())

+				&& namespaceInfos != null) {

+			String prefix = namespaceInfos.getPrefix(element.getNamespaceURI());

+			if (prefix != null) {

+				xpath.insert(0, ":");

+				xpath.insert(0, prefix);

+			}

+		}

+		xpath.insert(0, "/");

+		Node parentNode = element;

+		while (parentNode != null

+				&& parentNode.getNodeType() != Node.DOCUMENT_NODE) {

+			parentNode = parentNode.getParentNode();

+			parentNode = computeBasicXPath(parentNode, xpath, namespaceInfos);

+		}

+		return parentNode;

+	}

+

+	private void computeBasicXPath(Attr attr, StringBuilder xpath,

+			NamespaceInfos namespaceInfos) {

+		computeBasicXPath(attr.getOwnerElement(), xpath, namespaceInfos);

+		xpath.append("[@");

+		xpath.append(attr.getName());

+		xpath.append("=");

+		addXPathConditionValue(attr.getValue(), xpath);

+		xpath.append("]");

+		xpath.append("/@");

+		xpath.append(attr.getName());

+	}

+

+	private void computeBasicXPath(Text text, StringBuilder xpath,

+			NamespaceInfos namespaceInfos) {

+		computeBasicXPath(text.getParentNode(), xpath, namespaceInfos);

+		xpath.append("[text()=");

+		addXPathConditionValue(text.getData(), xpath);

+		xpath.append("]");

+		xpath.append("/text()");

+	}

+

+	private void addXPathConditionValue(String value, StringBuilder xpath) {

+		char c = getEnclosingXPathCondition(value);

+		xpath.append(c);

+		xpath.append(value);

+		xpath.append(c);

+

+	}

+

+	private char getEnclosingXPathCondition(String value) {

+		if (value.indexOf("\"") != -1) {

+			return '\'';

+		}

+		return '\"';

+	}

+

+	private IXPathProcessor getProcessor(String id) {

+		if (id == null) {

+			return DefaultXPathProcessor.INSTANCE;

+		}

+		IXPathProcessorType processorType = XPathProcessorManager.getDefault()

+				.getProcessor(id);

+		if (processorType == null) {

+			throw new RuntimeException(

+					"Cannot retrieve XPath processor type with id=" + id);

+		}

+		IXPathProcessor processor = processorType.getProcessor();

+		if (processor == null) {

+			throw new RuntimeException(

+					"Null XPath processor for XPath processor with id=" + id);

+		}

+		return processor;

+	}

+

+	// private synchronized XPathManagerForXPathProcessor registerManager(String

+	// id) {

+	// XPathManagerForXPathProcessor manager = managers.get(id);

+	// if (manager != null) {

+	// return manager;

+	// }

+	// IXPathProcessorType processor = XPathProcessorManager.getDefault()

+	// .getProcessor(id);

+	// if (processor == null) {

+	// throw new RuntimeException(

+	// "Cannot retrieve XPath processor with id=" + id);

+	// }

+	// manager = new XPathManagerForXPathProcessor(processor.getProcessor());

+	// managers.put(id, manager);

+	// return manager;

+	// }

+

+	public IStatus validateXPath(String xpathFactoryProviderId, String xpath) {

+		IXPathProcessor processor = null;

+		try {

+			processor = getProcessor(xpathFactoryProviderId);

+		} catch (Throwable e) {

+			return XMLSearchCorePlugin.createStatus(IStatus.ERROR, "", e);

+		}

+		return processor.validateXPath(xpath);

+	}

+

+	// public String escapeForXPathAttrCondition(String value,

+	// boolean enclosedByDoubleQuote) {

+	// if (value == null) {

+	// return "";

+	// }

+	// if (enclosedByDoubleQuote) {

+	// if (value.indexOf("\"") != -1) {

+	// return value.replaceAll("\"", "&quot;");

+	// }

+	// } else {

+	// if (value.indexOf("'") != -1) {

+	// return value.replaceAll("\'", "&pos;");

+	// }

+	// }

+	// return value;

+	// }

+

+	public NamespaceInfos getNamespaceInfo(Node node) {

+		if (node.getNodeType() == Node.DOCUMENT_NODE) {

+			return getNamespaceInfo((IDOMDocument) node);

+		}

+		return getNamespaceInfo((IDOMDocument) node.getOwnerDocument());

+	}

+

+	public NamespaceInfos getNamespaceInfo(IDOMDocument document) {

+		String modelID = document.getModel().getId();

+		Map<String, NamespaceInfos> namespaceInfo = getNamespaceInfo();

+		NamespaceInfos info = namespaceInfo.get(modelID);

+

+		if (info == null) {

+			if (document.getDocumentElement() != null) {

+				info = new NamespaceInfos();

+				NamespaceTable namespaceTable = new NamespaceTable(document);

+				namespaceTable.visitElement(document.getDocumentElement());

+				Collection<?> namespaces = namespaceTable

+						.getNamespaceInfoCollection();

+				info.addAll((Collection<NamespaceInfo>) namespaces);

+				namespaceInfo.put(modelID, info);

+				setNamespaceInfo(namespaceInfo);

+			}

+		}

+		return info;

+	}

+

+	public void setNamespaceInfo(Map<String, NamespaceInfos> namespaceInfo) {

+		this.namespaceInfo = namespaceInfo;

+	}

+

+	public Map<String, NamespaceInfos> getNamespaceInfo() {

+		return namespaceInfo;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathProcessorManager.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathProcessorManager.java
new file mode 100644
index 0000000..ba77537
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/XPathProcessorManager.java
@@ -0,0 +1,156 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.internal.Trace;

+import org.eclipse.wst.xml.search.core.internal.XMLSearchCorePlugin;

+import org.eclipse.wst.xml.search.core.internal.preferences.PreferenceInitializer;

+import org.eclipse.wst.xml.search.core.internal.xpath.XPathProcessorType;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+

+public class XPathProcessorManager extends AbstractRegistryManager {

+

+	private static final XPathProcessorManager INSTANCE = new XPathProcessorManager();

+	private static final String XPATH_EVALUATORS_EXTENSION_POINT = "xpathProcessors";

+	private Map<String, IXPathProcessorType> processorsById = null;

+

+	private static final String PROCESSOR_ELT = "processor";

+	private static final String ID_ATTR = "id";

+	private static final String CLASS_ATTR = "class";

+	private static final String NAME_ATTR = "name";

+

+	private IXPathProcessorType processorType;

+

+	public static XPathProcessorManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (processorsById == null) {// not loaded yet

+			return;

+		}

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addProcessors(processorsById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	private synchronized void addProcessors(

+			Map<String, IXPathProcessorType> processorsById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		String name = null;

+		String source = null;

+		for (IConfigurationElement ce : cf) {

+			source = ce.getContributor().getName();

+			// loop for to get processor declaration

+			if (PROCESSOR_ELT.equals(ce.getName())) {

+				try {

+					id = ce.getAttribute(ID_ATTR);

+					name = ce.getAttribute(NAME_ATTR);

+					IXPathProcessor processor = (IXPathProcessor) ce

+							.createExecutableExtension(CLASS_ATTR);

+					processorsById.put(id, new XPathProcessorType(id, name,

+							source, true, processor));

+				} catch (Throwable t) {

+					Trace.trace(Trace.SEVERE,

+							"  Could not load XPath processor for id: " + id, t);

+				}

+			}

+		}

+	}

+

+	public IXPathProcessorType getProcessor(String id) {

+		if (StringUtils.isEmpty(id)) {

+			return null;

+		}

+		if (processorsById == null) {

+			loadProcessors();

+		}

+

+		return processorsById.get(id);

+	}

+

+	private synchronized void loadProcessors() {

+		if (processorsById != null) {

+			return;

+		}

+		Map<String, IXPathProcessorType> processorsById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					getPluginId(), getExtensionPoint());

+			processorsById = new HashMap<String, IXPathProcessorType>(cf.length);

+			addProcessors(processorsById, cf);

+		} else {

+			processorsById = new HashMap<String, IXPathProcessorType>();

+		}

+		this.processorsById = processorsById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return XPATH_EVALUATORS_EXTENSION_POINT;

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchCorePlugin.PLUGIN_ID;

+	}

+

+	public IXPathProcessorType[] getProcessors() {

+		if (processorsById == null) {

+			loadProcessors();

+		}

+		return processorsById.values().toArray(IXPathProcessorType.EMPTY);

+	}

+

+	public void setDefaultProcessor(IXPathProcessorType processorType) {

+		this.processorType = processorType;

+		if (processorType == null) {

+			XMLSearchCorePlugin

+					.getDefault()

+					.getPluginPreferences()

+					.setValue(PreferenceInitializer.DEFAULT_XPATH_PROCESSOR, "");

+		} else {

+			XMLSearchCorePlugin

+					.getDefault()

+					.getPluginPreferences()

+					.setValue(PreferenceInitializer.DEFAULT_XPATH_PROCESSOR,

+							processorType.getId());

+		}

+		XMLSearchCorePlugin.getDefault().savePluginPreferences();

+	}

+

+	public IXPathProcessorType getDefaultProcessor() {

+		if (processorType == null) {

+			String id = XMLSearchCorePlugin.getDefault().getPluginPreferences()

+					.getString(PreferenceInitializer.DEFAULT_XPATH_PROCESSOR);

+			processorType = getProcessor(id);

+		}

+		return processorType;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/AbstractXPathNodeMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/AbstractXPathNodeMatcher.java
new file mode 100644
index 0000000..881244d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/AbstractXPathNodeMatcher.java
@@ -0,0 +1,35 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath.matcher;

+

+/**

+ * Abstract class for XPath node matcher.

+ * 

+ */

+public abstract class AbstractXPathNodeMatcher implements IXPathNodeMatcher {

+

+	private XPathMatcher ownerMatcher;

+

+	public AbstractXPathNodeMatcher(XPathMatcher ownerMatcher) {

+		this.ownerMatcher = ownerMatcher;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @seeorg.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#

+	 * getOwnerMatcher()

+	 */

+	public XPathMatcher getOwnerMatcher() {

+		return ownerMatcher;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/IXPathNodeMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/IXPathNodeMatcher.java
new file mode 100644
index 0000000..53f03f6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/IXPathNodeMatcher.java
@@ -0,0 +1,64 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath.matcher;

+

+import java.util.Collection;

+

+import org.w3c.dom.Node;

+

+/**

+ * XPath node matcher tests if {@link Node} match a fragment of XPath.

+ * 

+ * 

+ */

+public interface IXPathNodeMatcher {

+

+	public static final IXPathNodeMatcher[] EMPTY_NODE_MATCHER = new IXPathNodeMatcher[0];

+

+	public enum MatcherType {

+		ELEMENT, ATTRIBUTE

+	}

+

+	/**

+	 * Returns the owner matcher.

+	 * 

+	 * @return

+	 */

+	XPathMatcher getOwnerMatcher();

+

+	/**

+	 * Returns matcher type.

+	 * 

+	 * @return

+	 */

+	MatcherType getType();

+

+	/**

+	 * Match the {@link Node} and fill wildcard values if node matcher define

+	 * widcard.

+	 * 

+	 * @param testNode

+	 *            node to test.

+	 * @param wildcardValues

+	 *            wildcard values if node matcher define widcard.

+	 * @return

+	 */

+	boolean match(Node testNode, Collection<String> wildcardValues);

+

+	/**

+	 * Returns true if matcher is any (Node is every time matched) and false

+	 * otherwise.

+	 * 

+	 * @return

+	 */

+	boolean isAny();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathAttributeMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathAttributeMatcher.java
new file mode 100644
index 0000000..039b2c2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathAttributeMatcher.java
@@ -0,0 +1,134 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath.matcher;

+

+import java.util.Collection;

+

+import org.w3c.dom.Attr;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+/**

+ * XPath attribute matcher matches {@link Attr} of {@link Element}.

+ * 

+ * 

+ */

+public class XPathAttributeMatcher extends AbstractXPathNodeMatcher {

+

+	private final String attrName;

+	private final String attrValue;

+	private int indexWildcard = -1;

+

+	public XPathAttributeMatcher(String attrName, String attrValue,

+			XPathMatcher matcher) {

+		super(matcher);

+		this.attrName = attrName;

+		this.attrValue = attrValue;

+		if (attrValue.startsWith("$")) {

+			// attribute value has wilcard (ex : [@id='$0'])

+			try {

+				// get the wildcard index (ex : 0 for [@id='$0']).

+				indexWildcard = Integer.parseInt(attrValue.substring(1,

+						attrValue.length()));

+			} catch (NumberFormatException e) {

+

+			}

+		}

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#getType()

+	 */

+	public MatcherType getType() {

+		return MatcherType.ATTRIBUTE;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#match

+	 * (org.w3c.dom.Node, java.util.Collection)

+	 */

+	public boolean match(Node testNode, Collection<String> wildcardValues) {

+		if (testNode.getNodeType() == Node.ELEMENT_NODE) {

+			// Node to test is element

+			Element element = (Element) testNode;

+			if (indexWildcard != -1) {

+				// wildcard is defined in the attribute matcher.

+				if (element.hasAttribute(attrName)) {

+					// element define, attribute, match is OK.

+					if (wildcardValues != null) {

+						// wildcard values is filled, add the attribute value

+						wildcardValues.add(element.getAttribute(attrName));

+					}

+					// element tested define the attribute, match is OK

+					return true;

+				}

+				return false;

+			}

+			// No wildcard defined, test if element has attribute attrName and

+			// if value is OK.

+			String testAttrValue = element.getAttribute(attrName);

+			return attrValue.equals(testAttrValue);

+		}

+		return false;

+	}

+

+	/**

+	 * Returns the attribute name to match.

+	 * 

+	 * @return

+	 */

+	public String getAttrName() {

+		return attrName;

+	}

+

+	/**

+	 * Returns the attribute value to match.

+	 * 

+	 * @return

+	 */

+	public String getAttrValue() {

+		return attrValue;

+	}

+

+	/**

+	 * Returns true if attrValue is wilcard or false otherwise.

+	 * 

+	 * @return

+	 */

+	public boolean hasWildcard() {

+		return indexWildcard != -1;

+	}

+

+	/**

+	 * Returns the wildcard index and -1 if no wildcard is defined.

+	 * 

+	 * @return

+	 */

+	public int getIndexWildcard() {

+		return indexWildcard;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#isAny()

+	 */

+	public boolean isAny() {

+		return false;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathElementMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathElementMatcher.java
new file mode 100644
index 0000000..264de09
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathElementMatcher.java
@@ -0,0 +1,158 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath.matcher;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.List;

+

+import org.w3c.dom.Attr;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+/**

+ * XPath element matcher matches {@link Attr} of {@link Element} and element

+ * name.

+ * 

+ */

+public class XPathElementMatcher extends AbstractXPathNodeMatcher {

+

+	public static final String ANY_ELEMENT_NAME = "*";

+	private List<XPathAttributeMatcher> attributes = null;

+

+	private final String prefix;

+	private final String localName;

+	private final boolean anyElementName;

+

+	public XPathElementMatcher(String prefix, String localName,

+			XPathMatcher matcher) {

+		super(matcher);

+		this.prefix = prefix;

+		this.localName = localName;

+		this.anyElementName = ANY_ELEMENT_NAME.equals(localName);

+	}

+

+	public MatcherType getType() {

+		return MatcherType.ELEMENT;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#match

+	 * (org.w3c.dom.Node, java.util.Collection)

+	 */

+	public boolean match(Node testNode, Collection<String> wildcardValues) {

+		// test match for element name.

+		if (!matchElement(testNode)) {

+			return false;

+		}

+		// element name is matched, test match for element attributes.

+		return matchAttributes(testNode, wildcardValues);

+	}

+

+	/**

+	 * Returns true if element (name) is matched and false otherwise.

+	 * 

+	 * @param testNode

+	 * @return

+	 */

+	private boolean matchElement(Node testNode) {

+		String LocalName = testNode.getLocalName();

+		if (LocalName == null) {

+			LocalName = testNode.getNodeName();

+		}

+		return matchElement(LocalName);

+	}

+

+	/**

+	 * Returns true if element name is matched and false otherwise.

+	 * 

+	 * @param testNode

+	 * @return

+	 */

+	private boolean matchElement(String localName) {

+		if (anyElementName) {

+			// any (//) is defined, element is matched.

+			return true;

+		}

+		// test if element name of teh element match the element name matcher.

+		return this.localName.equals(localName);

+	}

+

+	/**

+	 * Returns true if attributes of the element match the list of attribute

+	 * matcher.

+	 * 

+	 * @param testNode

+	 * @param wildcardValues

+	 * @return

+	 */

+	private boolean matchAttributes(Node testNode,

+			Collection<String> wildcardValues) {

+		if (attributes == null) {

+			// No attributes matcher defined, match is OK.

+			return true;

+		}

+		// Loop for each attributes matcher

+		for (XPathAttributeMatcher attribute : attributes) {

+			if (!attribute.match(testNode, wildcardValues)) {

+				// on eattribuete is not matched.

+				return false;

+			}

+		}

+		// teh whole attributes are matched.

+		return true;

+	}

+

+	/**

+	 * Returns the prefix.

+	 * 

+	 * @return

+	 */

+	public String getPrefix() {

+		return prefix;

+	}

+

+	/**

+	 * Returns the element name to match.

+	 * 

+	 * @return

+	 */

+	public String getLocalName() {

+		return localName;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.core.xpath.matcher.IXPathNodeMatcher#isAny()

+	 */

+	public boolean isAny() {

+		return anyElementName;

+	}

+

+	/**

+	 * Add XPath attribute matcher.

+	 * 

+	 * @param matcher

+	 */

+	public void add(XPathAttributeMatcher matcher) {

+		if (attributes == null) {

+			attributes = new ArrayList<XPathAttributeMatcher>();

+		}

+		attributes.add(matcher);

+

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcher.java b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcher.java
new file mode 100644
index 0000000..8b03ced
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.core/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcher.java
@@ -0,0 +1,323 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath.matcher;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.List;

+

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Node;

+import org.w3c.dom.Text;

+

+/**

+ * 

+ * XPath matcher is used to match if a DOM Node match a XPath expression. It is

+ * initialized with an XPath expression :

+ * 

+ * <ul>

+ * <li>static expression like //element</li>

+ * <li>expression with wildcard like //element[@id='$0']</li>

+ * </ul>

+ * 

+ */

+public class XPathMatcher extends ArrayList<XPathElementMatcher> {

+

+	private static final long serialVersionUID = 3057263917768550928L;

+

+	private int nbWildCard = -1;

+

+	/**

+	 * Constructor of XPath Matcher with a XPath expression.

+	 * 

+	 * @param xpathExpression

+	 */

+	public XPathMatcher(String xpathExpression) {

+		// initialize XPath Matcher with XPath expression.

+		parse(xpathExpression);

+	}

+

+	/**

+	 * Parse the given XPath expression.

+	 * 

+	 * @param xpathExpression

+	 *            XPath expression.

+	 */

+	private void parse(String xpathExpression) {

+		String prefix = null;

+		String localName = null;

+		if (xpathExpression.startsWith("/")) {

+			xpathExpression = xpathExpression.substring(1,

+					xpathExpression.length());

+		}

+		boolean endsWithAny = false;

+		if (xpathExpression.endsWith("//")) {

+			endsWithAny = true;

+			xpathExpression = xpathExpression.substring(0,

+					xpathExpression.length() - 2);

+		}

+		XPathElementMatcher elementmatcher = null;

+		String[] paths = xpathExpression.split("/");

+		for (int i = 0; i < paths.length; i++) {

+			localName = paths[i];

+			if (StringUtils.isEmpty(localName)) {

+				this.createElementMatcher();

+			} else {

+				int indexNS = localName.indexOf(':');

+				if (indexNS != -1) {

+					prefix = localName.substring(0, indexNS);

+					localName = localName.substring(indexNS + 1,

+							localName.length());

+				}

+				int indexSquareBracket = localName.indexOf("[");

+				if (indexSquareBracket == -1) {

+					// Element name condition

+					// ex : p=pipeline

+					this.createElementMatcher(prefix, localName);

+				} else {

+					// ex : p=transformer[@type='pipeline'][@src='p1']

+					String elementName = localName.substring(0,

+							indexSquareBracket);

+					elementmatcher = this.createElementMatcher(prefix,

+							elementName);

+

+					String attributesCondition = localName.substring(

+							indexSquareBracket, localName.length());

+					// ex : attributesCondition=[@type='pipeline'][@src='p1']

+

+					char c;

+					StringBuilder attrName = null;

+					StringBuilder attrValue = null;

+					boolean firstQuote = false;

+					boolean attrCondition = false;

+					char[] chars = attributesCondition.toCharArray();

+					for (int j = 0; j < chars.length; j++) {

+						c = chars[j];

+						if (attrName == null) {

+							if (c == '[' || /* c == '@' || */c == ']') {

+								continue;

+							}

+							attrName = new StringBuilder();

+							attrName.append(c);

+							attrCondition = (c == '@');

+						} else {

+							if (attrValue == null) {

+								if (c != '=') {

+									attrName.append(c);

+								} else {

+									attrValue = new StringBuilder();

+								}

+							} else {

+								if (c == '\'') {

+									if (!firstQuote) {

+										firstQuote = true;

+										continue;

+									} else {

+										// second quote, add attribute name

+										// condition

+										if (attrCondition) {

+											XPathAttributeMatcher attributematcher = this

+													.createAttributeMatcher(

+															elementmatcher,

+															attrName.toString()

+																	.substring(

+																			1,

+																			attrName.length()),

+															attrValue

+																	.toString());

+											if (attributematcher.hasWildcard()) {

+												int index = attributematcher

+														.getIndexWildcard();

+												if (index > nbWildCard) {

+													nbWildCard = index;

+												}

+											}

+										}

+										attrName = null;

+										attrValue = null;

+										firstQuote = false;

+										attrCondition = false;

+									}

+								} else {

+									attrValue.append(c);

+								}

+							}

+						}

+					}

+				}

+			}

+		}

+		if (endsWithAny) {

+			this.createElementMatcher();

+		}

+	}

+

+	/**

+	 * Returns true if the given DOM Node match the XPath expression of this

+	 * XPath matcher and false otherwise.

+	 * 

+	 * @param node

+	 *            the DOM Node to match.

+	 * @return

+	 */

+	public boolean match(final Node node) {

+		return match(node, null);

+	}

+

+	/**

+	 * Returns true if the given DOM Node match the XPath expression of this

+	 * XPath matcher and false otherwise. This method use wilcard values if

+	 * XPath expression contains wildcard (like [@id='$0'].

+	 * 

+	 * @param node

+	 *            the DOM Node to match.

+	 * @param wildcardValues

+	 *            the list of wildcard values and null otherwise.

+	 * @return

+	 */

+	public boolean match(final Node node,

+			final Collection<String> wildcardValues) {

+		if (node == null) {

+			return false;

+		}

+		Node testNode = node;

+		XPathElementMatcher condition = null;

+		for (int i = super.size() - 1; i >= 0; i--) {

+			condition = super.get(i);

+			if (condition.isAny()) {

+				if (i > 0) {

+					boolean previousConditionFounded = false;

+					XPathElementMatcher previousElementCondition = super

+							.get(i - 1);

+					if (previousElementCondition == null) {

+						return true;

+					}

+					while (testNode != null

+							&& testNode.getNodeType() != Node.DOCUMENT_NODE) {

+						if (previousElementCondition.match(testNode,

+								wildcardValues)) {

+							previousConditionFounded = true;

+							break;

+						}

+						testNode = testNode.getParentNode();

+					}

+

+					if (!previousConditionFounded) {

+						return false;

+					} else {

+						i--;

+					}

+

+				} else {

+					return true;

+				}

+			} else {

+				if (!condition.match(testNode, wildcardValues)) {

+					return false;

+				}

+			}

+			testNode = testNode.getParentNode();

+		}

+		return true;

+	}

+

+	/**

+	 * Returns list of wildcard values of the given DOM Node.

+	 * 

+	 * @param selectedNode

+	 * @return

+	 */

+	public List<String> getWildcardValues(Node selectedNode) {

+		List<String> wildcardValues = new ArrayList<String>();

+		if (nbWildCard == -1 || selectedNode == null) {

+			// No wildcard in the XPath expression of this matcher or DOM node

+			// is null

+			return wildcardValues;

+		}

+		Node testNode = getTestNode(selectedNode);

+		match(testNode, wildcardValues);

+		return wildcardValues;

+	}

+

+	/**

+	 * Returns the DOM Node to test to match.

+	 * 

+	 * @param node

+	 * @return

+	 */

+	private Node getTestNode(Node node) {

+		short nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			return ((Attr) node).getOwnerElement();

+		case Node.TEXT_NODE:

+			return ((Text) node).getParentNode();

+		}

+		return node;

+	}

+

+	/**

+	 * Returns the number of wilcard used in the XPath expression and -1 if

+	 * there is no wildcard.

+	 * 

+	 * @return

+	 */

+	public int getNbWildCard() {

+		return nbWildCard;

+	}

+

+	// ------------ XPath node matcher factory.

+

+	/***

+	 * Create XPath element matcher.

+	 * 

+	 * @param elementName

+	 * @return

+	 */

+	protected XPathElementMatcher createElementMatcher(String prefix,

+			String localName) {

+		XPathElementMatcher matcher = new XPathElementMatcher(prefix,

+				localName, this);

+		super.add(matcher);

+		return matcher;

+	}

+

+	/**

+	 * Create XPath any element matcher.

+	 * 

+	 * @return

+	 */

+	protected XPathElementMatcher createElementMatcher() {

+		XPathElementMatcher matcher = new XPathElementMatcher(null,

+				XPathElementMatcher.ANY_ELEMENT_NAME, this);

+		super.add(matcher);

+		return matcher;

+	}

+

+	/**

+	 * Create XPath attribute matcher.

+	 * 

+	 * @param elementmatcher

+	 * @param attrName

+	 * @param attrValue

+	 * @return

+	 */

+	protected XPathAttributeMatcher createAttributeMatcher(

+			XPathElementMatcher elementmatcher, String attrName,

+			String attrValue) {

+		XPathAttributeMatcher matcher = new XPathAttributeMatcher(attrName,

+				attrValue, this);

+		elementmatcher.add(matcher);

+		return matcher;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/.classpath b/plugins/org.eclipse.wst.xml.search.editor/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/.options b/plugins/org.eclipse.wst.xml.search.editor/.options
new file mode 100644
index 0000000..6950726
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/.options
@@ -0,0 +1,4 @@
+org.eclipse.wst.xml.search.editor/debug/reporter=false

+org.eclipse.wst.xml.search.editor/debug/validator=false

+org.eclipse.wst.xml.search.editor/debug/indexmanager=false

+org.eclipse.wst.xml.search.editor/debug/search=false
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/.project b/plugins/org.eclipse.wst.xml.search.editor/.project
new file mode 100644
index 0000000..fe01790
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.wst.xml.search.editor</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.xml.search.editor/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..3e9f6bb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Wed Nov 24 15:00:56 CET 2010

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

+org.eclipse.jdt.core.compiler.compliance=1.5

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.5

diff --git a/plugins/org.eclipse.wst.xml.search.editor/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.xml.search.editor/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e1c3af0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/META-INF/MANIFEST.MF
@@ -0,0 +1,47 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.editor;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.jface.text,
+ org.eclipse.wst.sse.core,
+ org.eclipse.wst.xml.core,
+ org.eclipse.wst.xml.ui,
+ org.eclipse.wst.sse.ui,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.wst.xml.search.ui;bundle-version="1.0.0",
+ org.eclipse.core.resources,
+ org.eclipse.ui.ide,
+ org.eclipse.wst.validation,
+ org.eclipse.jdt.core,
+ org.eclipse.jdt.ui,
+ org.eclipse.search
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.wst.xml.search.editor,
+ org.eclipse.wst.xml.search.editor.contentassist,
+ org.eclipse.wst.xml.search.editor.hover,
+ org.eclipse.wst.xml.search.editor.hyperlink,
+ org.eclipse.wst.xml.search.editor.java,
+ org.eclipse.wst.xml.search.editor.queryspecifications,
+ org.eclipse.wst.xml.search.editor.queryspecifications.visitor,
+ org.eclipse.wst.xml.search.editor.references,
+ org.eclipse.wst.xml.search.editor.references.filters,
+ org.eclipse.wst.xml.search.editor.references.validators,
+ org.eclipse.wst.xml.search.editor.searchers,
+ org.eclipse.wst.xml.search.editor.searchers.expressions,
+ org.eclipse.wst.xml.search.editor.searchers.java,
+ org.eclipse.wst.xml.search.editor.searchers.javamethod,
+ org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider,
+ org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor,
+ org.eclipse.wst.xml.search.editor.searchers.resource,
+ org.eclipse.wst.xml.search.editor.searchers.statics,
+ org.eclipse.wst.xml.search.editor.searchers.xml,
+ org.eclipse.wst.xml.search.editor.statics,
+ org.eclipse.wst.xml.search.editor.util,
+ org.eclipse.wst.xml.search.editor.validation
diff --git a/plugins/org.eclipse.wst.xml.search.editor/build.properties b/plugins/org.eclipse.wst.xml.search.editor/build.properties
new file mode 100644
index 0000000..1cb217c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/build.properties
@@ -0,0 +1,7 @@
+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .,\

+               plugin.properties,\

+               plugin.xml,\

+               icons/

diff --git a/plugins/org.eclipse.wst.xml.search.editor/icons/obj16/property_obj.gif b/plugins/org.eclipse.wst.xml.search.editor/icons/obj16/property_obj.gif
new file mode 100644
index 0000000..fdde5fb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/icons/obj16/property_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.editor/plugin.properties b/plugins/org.eclipse.wst.xml.search.editor/plugin.properties
new file mode 100644
index 0000000..8e2ca7a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/plugin.properties
@@ -0,0 +1,38 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+pluginName=WST XML Search Editor

+providerName=Angelo ZERR

+

+# Extension Point

+referencesContributionName=XML references contribution.

+contentAssistsContributionName=XML content assists contribution.

+searchersContributionName=XML searchers contribution.

+referenceValidatorsContributionName=XML reference validators.

+referenceFiltersContributionName=XML reference filters.

+javaQuerySpecificationsContributionName=Java query specification contribution.

+javaMethodQuerySpecificationsContributionName=Java method query specification contribution.

+expressionParsersContributionName=XML Expression parser.

+javaReferencesContributionName=Java references contribution.

+javaReferencesMatchersContributionName=Java references matchers contribution.

+

+# JDT search particpant

+queryParticipant.name.0=XML Search Java Search Participant

+

+#--- Search menu

+ActionDefinition.referencesInContainer.name= References in Container

+ActionDefinition.referencesInContainer.description= Search for references to the selected element in the container

+

+XMLReferencesBatchValidator_description= XML References Validator

+_validationMarker.name=XML References Problem

+

+# XML search Editor preferences page

+XML_Source.name=Editor

+XML_Syntax_Coloring=Syntax Coloring

diff --git a/plugins/org.eclipse.wst.xml.search.editor/plugin.xml b/plugins/org.eclipse.wst.xml.search.editor/plugin.xml
new file mode 100644
index 0000000..7667f7c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/plugin.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.4"?>

+<plugin>

+		

+	<extension-point id="xmlReferences" name="%referencesContributionName"

+		schema="schema/xml2x/xmlReferences.exsd" />

+	<extension-point id="referenceFilters" name="%referenceFiltersContributionName"

+		schema="schema/referenceFilters.exsd" />		

+	<extension-point id="referenceValidators" name="%referenceValidatorsContributionName"

+		schema="schema/referenceValidators.exsd" />						

+	<extension-point id="contentAssists" name="%contentAssistsContributionName"

+		schema="schema/contentAssists.exsd" />

+	<extension-point id="searchers" name="%searchersContributionName"

+		schema="schema/searchers.exsd" />		

+	<extension-point id="javaQuerySpecifications" name="%javaQuerySpecificationsContributionName"

+		schema="schema/javaQuerySpecifications.exsd" />						

+	<extension-point id="javaMethodQuerySpecifications" name="%javaMethodQuerySpecificationsContributionName"

+		schema="schema/javaMethodQuerySpecifications.exsd" />		

+	<extension-point id="expressionParsers" name="%expressionParsersContributionName"

+		schema="schema/expressionParsers.exsd" />		

+	<extension-point id="javaReferences" name="%javaReferencesContributionName"

+		schema="schema/javaReferences.exsd" />

+	<extension-point id="javaReferencesMatchers" name="%javaReferencesMatchersContributionName"

+		schema="schema/javaReferencesMatchers.exsd" />												

+				 

+   <extension

+         point="org.eclipse.wst.xml.search.editor.expressionParsers">

+         <parser

+               id="org.eclipse.wst.xml.search.editor.expressions.multiattrvalues"

+               class="org.eclipse.wst.xml.search.editor.searchers.expressions.MultiAttrValuesExpressionParser"               >

+         </parser>

+   </extension>

+   		 

+	<extension

+         point="org.eclipse.jdt.ui.queryParticipants">

+      <queryParticipant

+            class="org.eclipse.wst.xml.search.editor.internal.jdt.search.XMLReferenceJavaSearchParticipant"

+            id="org.eclipse.wst.xml.search.editor.jdt.search.ClassSearchParticipant"

+            name="%queryParticipant.name.0"

+            nature="org.eclipse.jdt.core.javanature"/>

+   </extension>

+   		          

+   <extension

+         point="org.eclipse.wst.xml.search.editor.searchers">

+         <searcher

+               id="org.eclipse.wst.xml.search.editor.searcher.resource"

+               class="org.eclipse.wst.xml.search.editor.searchers.resource.XMLSearcherForResource" >

+         </searcher>

+         <searcher

+               id="org.eclipse.wst.xml.search.editor.searcher.java"

+               class="org.eclipse.wst.xml.search.editor.searchers.java.XMLSearcherForJava" >

+         </searcher>

+         <searcher

+               id="org.eclipse.wst.xml.search.editor.searcher.javamethod"

+               class="org.eclipse.wst.xml.search.editor.searchers.javamethod.XMLSearcherForJavaMethod" >

+         </searcher>

+         <searcher

+               id="org.eclipse.wst.xml.search.editor.searcher.properties"

+               class="org.eclipse.wst.xml.search.editor.searchers.properties.XMLSearcherForProperties" >

+         </searcher>         

+         <searcher

+               id="org.eclipse.wst.xml.search.editor.searcher.statics"

+               class="org.eclipse.wst.xml.search.editor.searchers.statics.XMLSearcherForStatic" >

+         </searcher>

+         <searcher

+               id="org.eclipse.wst.xml.search.editor.searcher.xml"

+               class="org.eclipse.wst.xml.search.editor.searchers.xml.XMLSearcherForXML" >

+         </searcher>

+       <searcher

+               id="org.eclipse.wst.xml.search.editor.searcher.expression"

+               class="org.eclipse.wst.xml.search.editor.searchers.expressions.XMLSearcherForExpression" >

+         </searcher>         

+   </extension>                  			        

+

+   <extension

+         point="org.eclipse.wst.xml.search.editor.referenceValidators">

+         <validator

+               id="org.eclipse.wst.xml.search.editor.referenceValidators.default"

+               class="org.eclipse.wst.xml.search.editor.references.validators.DefaultDOMNodeValidator" >

+         </validator>

+   </extension>                  			        

+     

+	<extension point="org.eclipse.ui.commands">

+		<command

+            name="%ActionDefinition.referencesInContainer.name"

+            description="%ActionDefinition.referencesInContainer.description"

+			categoryId="org.eclipse.search.ui.category.search"

+			id="org.eclipse.wst.xml.search.references.in.container">

+		</command>

+   </extension> 

+		            	

+   <extension

+       point="org.eclipse.ui.handlers">

+       <handler

+             class="org.eclipse.wst.xml.search.editor.internal.handlers.ReferencesInContainerHandler"

+             commandId="org.eclipse.wst.xml.search.references.in.container">

+       </handler>

+   </extension> 

+   

+	<!--<extension point="org.eclipse.ui.menus">   

+	     <menuContribution

+	           locationURI="popup:sourcePopupMenuId?after=sourceBegin">

+				<command

+			           commandId="org.eclipse.wst.xml.search.references.in.container"

+			           id="ReferencesInContainer"

+			           style="push">

+					<visibleWhen checkEnabled="false">

+						<reference definitionId="org.eclipse.wst.sse.ui.sseActiveContext.definition"></reference>

+					</visibleWhen>

+			    </command>

+	     </menuContribution>			    

+   </extension>--> 

+

+   <extension

+         point="org.eclipse.ui.bindings">

+      <!--  win32:  M1=CTRL,    M2=SHIFT, M3=ALT, M4=-

+            carbon: M1=COMMAND, M2=SHIFT, M3=ALT, M4=CTRL -->

+

+<!-- search -->

+      <key

+            sequence="M1+M2+G"

+            contextId="org.eclipse.wst.sse.ui.structuredTextEditorScope"

+            commandId="org.eclipse.wst.xml.search.references.in.container"

+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>

+   </extension>    

+  

+  <!-- XML references batch validator -->

+

+  <extension

+         id="validationMarker"

+         name="%_validationMarker.name"

+         point="org.eclipse.core.resources.markers">

+      <super type="org.eclipse.wst.validation.problemmarker"/>

+      <persistent value="true"/>

+ </extension>

+    

+	<extension id="xmlReferncesBatchValidator" name="%XMLReferencesBatchValidator_description" point="org.eclipse.wst.validation.validatorV2">

+      <validator

+            build="true"

+            class="org.eclipse.wst.xml.search.editor.validation.XMLReferencesBatchValidator"

+            manual="true"            

+            version="1"

+            markerId="org.eclipse.wst.xml.search.editor.validationMarker">

+         <include>

+            <rules>

+               <fileext

+                     caseSensitive="false"

+                     ext="xml">

+               </fileext>

+            </rules>

+         </include>

+         <exclude>

+            <rules>

+				<projectNature id="org.eclipse.jst.j2ee.ejb.EJBNature"/>

+				<projectNature id="org.eclipse.jst.j2ee.EARNature"/>

+    			<file caseSensitive="true" name=".project" type="file"/>

+    			<file caseSensitive="true" name=".classpath" type="file"/>

+    			<file caseSensitive="true" name=".settings"  type="folder"/>

+            </rules>

+         </exclude>

+      </validator>

+   </extension>    

+     

+	<!-- initialize xml search editor preferences -->

+	<extension point="org.eclipse.core.runtime.preferences">

+		<initializer

+			class="org.eclipse.wst.xml.search.editor.internal.preferences.XMLSearchEditorPreferenceInitializer" />

+	</extension>

+	     

+	<extension point="org.eclipse.ui.preferencePages">

+		<page

+			name="%XML_Source.name"

+			category="org.eclipse.wst.xml.search.references"

+			class="org.eclipse.wst.xml.search.editor.internal.preferences.XMLSourcePreferencePage"

+			id="org.eclipse.wst.xml.search.editor.source">

+		</page>	

+		<page category="org.eclipse.wst.xml.search.editor.source"

+			class="org.eclipse.wst.xml.search.editor.internal.preferences.XMLReferencesSyntaxColoringPage"

+			id="org.eclipse.wst.xml.search.editor.internal.preferences.XMLReferencesSyntaxColoringPage" 

+			name="%XML_Syntax_Coloring">

+		</page>	

+	</extension>	     

+	     

+<!-- Define theme -->

+	<extension

+		point="org.eclipse.ui.themes">

+		<theme

+			id="org.eclipse.ui.ide.systemDefault">

+			<colorOverride

+				id="tagReferencedAttributeValue"

+				value="COLOR_LIST_FOREGROUND">

+			</colorOverride>			

+		</theme>

+		<colorDefinition

+			id="tagReferencedAttributeValue"

+			isEditable="false"

+			label="%Colors.tagAttributeValue"

+			value="42, 0, 255">

+		</colorDefinition>

+	</extension>

+	     

+	<extension point="org.eclipse.jdt.ui.javaCompletionProposalComputer"

+			id="SearchJavaNoTypeCompletionProposalComputer"

+			name="SearchJavaNoTypeCompletionProposalComputer">

+		<proposalCategory 

+			icon="jdt_search.png"

+			id="org.eclipse.jdt.search.editor"

+			name="JDT Search" />

+		<javaCompletionProposalComputer

+			class="org.eclipse.wst.xml.search.editor.internal.jdt.search2.SearchJavaNoTypeCompletionProposalComputer"

+			categoryId="org.eclipse.jdt.search.editor">

+			<partition type="__java_string"/>

+		</javaCompletionProposalComputer>

+	</extension>

+		     

+	<extension point="org.eclipse.ui.workbench.texteditor.hyperlinkDetectors">

+		<hyperlinkDetector

+			class="org.eclipse.wst.xml.search.editor.java.hyperlink.Java2XHyperLinkDetectetor"

+			id="org.eclipse.wst.xml.search.editor.java.hyperlink.Java2XHyperLinkDetectetor"

+			name="WTP/XML Search - Java Hyperlinker"

+			targetId="org.eclipse.jdt.ui.javaCode">

+		</hyperlinkDetector>

+	</extension>

+			     

+	<extension point="org.eclipse.jdt.ui.javaEditorTextHovers">

+		<hover

+			class="org.eclipse.wst.xml.search.editor.java.hover.Java2XHover"

+			id="org.eclipse.wst.xml.search.editor.java.hover.Java2XHover"

+			label="WTP/XML Search - Java Hover"/>

+	</extension>

+					     

+</plugin>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/contentAssists.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/contentAssists.exsd
new file mode 100644
index 0000000..728da94
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/contentAssists.exsd
@@ -0,0 +1,92 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="contentAssisits" name="XML Editor Content Assist Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML Editor Content Assist.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="additionalProposalInfoProvider" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="additionalProposalInfoProvider">

+      <complexType>

+         <sequence>

+         </sequence>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/expressionParsers.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/expressionParsers.exsd
new file mode 100644
index 0000000..24e10b8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/expressionParsers.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="expressionParsers" name="XML Editor parsers Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML Parsers.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="parser" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="parser">

+      <complexType>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.parsers.IXMLExpressionParser"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/javaMethodQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/javaMethodQuerySpecifications.exsd
new file mode 100644
index 0000000..080eda8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/javaMethodQuerySpecifications.exsd
@@ -0,0 +1,92 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="javaMethodQuerySpecifications" name="XML Editor Java Method Query specification Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML Editor Java Method Query specification.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="querySpecification">

+      <complexType>

+         <sequence>

+         </sequence>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/javaQuerySpecifications.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/javaQuerySpecifications.exsd
new file mode 100644
index 0000000..92b77d0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/javaQuerySpecifications.exsd
@@ -0,0 +1,92 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="javaQuerySpecifications" name="XML Editor Java Query specification Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML Editor Java Query specification.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="querySpecification" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="querySpecification">

+      <complexType>

+         <sequence>

+         </sequence>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferences.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferences.exsd
new file mode 100644
index 0000000..dfdb53e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferences.exsd
@@ -0,0 +1,427 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="javaReferences" name="Java Reference Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide Java Reference Node.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="references" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="references">

+      <complexType>

+         <sequence>

+            <element ref="reference" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+      </complexType>

+   </element>

+

+   <element name="reference">

+      <complexType>

+         <sequence>

+            <element ref="from"/>

+            <element ref="to" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toJava" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toJavaMethod" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toProperty" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toResource" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toStatic" minOccurs="0" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="parserId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.expressionParsers/parser/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.expression">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="from">

+      <complexType>

+         <attribute name="matcherId" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaReferencesMatchers/matcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="to">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.xml">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="path" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="targetNodes" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.querySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="additionalProposalInfoProviderId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="namespacesId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.namespaces/namespaces/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toJava">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.java">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="extends" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toJavaMethod">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="pathForClass" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaMethodQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.javamethod">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toProperty">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.properties">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.propertiesQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toResource">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.resource">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.resourceQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="additionalProposalInfoProviderId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toStatic">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.statics">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.staticValueQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="additionalProposalInfoProviderId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferencesMatchers.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferencesMatchers.exsd
new file mode 100644
index 0000000..51e483a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/javaReferencesMatchers.exsd
@@ -0,0 +1,92 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="javaReferencesMatchers" name="Java References Matchers Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide Java Matchers.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="matcher" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="matcher">

+      <complexType>

+         <sequence>

+         </sequence>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.java.IJavaElementMatcher"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/referenceFilters.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/referenceFilters.exsd
new file mode 100644
index 0000000..864fb09
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/referenceFilters.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="referenceFilters" name="XML Editor Filters Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML Reference Filters.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="filter" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="filter">

+      <complexType>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.references.filter.IXMLReferenceFilter"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/referenceValidators.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/referenceValidators.exsd
new file mode 100644
index 0000000..c74e6b4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/referenceValidators.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="referenceValidators" name="XML Reference Editor Validators Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML Reference Validators.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="validator" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="validator">

+      <complexType>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/searchers.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/searchers.exsd
new file mode 100644
index 0000000..8988b6b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/searchers.exsd
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="searchers" name="XML Editor Searchers Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML Editor Searchers.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="searcher" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="searcher">

+      <complexType>

+         <attribute name="id" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="class" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="java" basedOn=":org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/schema/xml2x/xmlReferences.exsd b/plugins/org.eclipse.wst.xml.search.editor/schema/xml2x/xmlReferences.exsd
new file mode 100644
index 0000000..32125eb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/schema/xml2x/xmlReferences.exsd
@@ -0,0 +1,485 @@
+<?xml version='1.0' encoding='UTF-8'?>

+<!-- Schema file written by PDE -->

+<schema targetNamespace="org.eclipse.wst.xml.search.editor" xmlns="http://www.w3.org/2001/XMLSchema">

+<annotation>

+      <appinfo>

+         <meta.schema plugin="org.eclipse.wst.xml.search.editor" id="xmlReferences" name="XML References Contribution"/>

+      </appinfo>

+      <documentation>

+         Extension point for provide XML References Node.

+      </documentation>

+   </annotation>

+

+   <element name="extension">

+      <annotation>

+         <appinfo>

+            <meta.element />

+         </appinfo>

+      </annotation>

+      <complexType>

+         <sequence minOccurs="1" maxOccurs="unbounded">

+            <element ref="references" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="point" type="string" use="required">

+            <annotation>

+               <documentation>

+                  a fully-qualified name of the target extension point

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  an optional id

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="name" type="string">

+            <annotation>

+               <documentation>

+                  an optional name

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="references">

+      <complexType>

+         <sequence>

+            <element ref="reference" minOccurs="1" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="contentTypeIds" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="xpathFactoryId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="reference">

+      <complexType>

+         <sequence>

+            <element ref="from"/>

+            <element ref="to" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toJava" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toJavaMethod" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toProperty" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toResource" minOccurs="0" maxOccurs="unbounded"/>

+            <element ref="toStatic" minOccurs="0" maxOccurs="unbounded"/>

+         </sequence>

+         <attribute name="validatorId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.referenceValidators/validator/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="parserId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.expressionParsers/parser/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.expression">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="from">

+      <complexType>

+         <attribute name="path" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="targetNodes" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.querySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="filterId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.referenceFilters/filter/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="namespacesId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.namespaces/namespaces/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="to">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.xml">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="path" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="targetNodes" type="string" use="required">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.querySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="additionalProposalInfoProviderId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="namespacesId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.namespaces/namespaces/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toJava">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.java">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="extends" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toJavaMethod">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="pathForClass" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.javaMethodQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.javamethod">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toProperty">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.properties">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.propertiesQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toResource">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.resource">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.resourceQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="additionalProposalInfoProviderId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <element name="toStatic">

+      <complexType>

+         <attribute name="id" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+         <attribute name="searcherId" type="string" use="default" value="org.eclipse.wst.xml.search.editor.searcher.statics">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.searchers/searchers/searcher/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="querySpecificationId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.core.staticValueQuerySpecifications/querySpecification/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="additionalProposalInfoProviderId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+               <appinfo>

+                  <meta.attribute kind="identifier" basedOn="org.eclipse.wst.xml.search.editor.contentAssists/additionalProposalInfoProvider/@id"/>

+               </appinfo>

+            </annotation>

+         </attribute>

+         <attribute name="tokenId" type="string">

+            <annotation>

+               <documentation>

+                  

+               </documentation>

+            </annotation>

+         </attribute>

+      </complexType>

+   </element>

+

+   <annotation>

+      <appinfo>

+         <meta.section type="since"/>

+      </appinfo>

+      <documentation>

+         2.0

+      </documentation>

+   </annotation>

+

+

+

+   <annotation>

+      <appinfo>

+         <meta.section type="implementation"/>

+      </appinfo>

+      <documentation>

+         This plugin itself does not have any predefined builders.

+      </documentation>

+   </annotation>

+

+

+</schema>

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/XMLReferencesStructuredTextViewerConfiguration.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/XMLReferencesStructuredTextViewerConfiguration.java
new file mode 100644
index 0000000..ed4ff11
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/XMLReferencesStructuredTextViewerConfiguration.java
@@ -0,0 +1,172 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.jface.text.ITextHover;

+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;

+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;

+import org.eclipse.jface.text.source.ISourceViewer;

+import org.eclipse.wst.sse.core.StructuredModelManager;

+import org.eclipse.wst.sse.core.text.IStructuredPartitions;

+import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder;

+import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;

+import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;

+import org.eclipse.wst.sse.ui.internal.provisional.style.LineStyleProvider;

+import org.eclipse.wst.sse.ui.internal.taginfo.AnnotationHoverProcessor;

+import org.eclipse.wst.sse.ui.internal.taginfo.BestMatchHover;

+import org.eclipse.wst.sse.ui.internal.taginfo.ProblemAnnotationHoverProcessor;

+import org.eclipse.wst.sse.ui.internal.taginfo.TextHoverManager;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;

+import org.eclipse.wst.xml.core.text.IXMLPartitions;

+import org.eclipse.wst.xml.search.editor.hover.XMLReferencesInfoHoverProcessor;

+import org.eclipse.wst.xml.search.editor.hyperlink.XMLReferencesHyperlinkDetector;

+import org.eclipse.wst.xml.search.editor.internal.contentassist.XMLReferencesContentAssistProcessor;

+import org.eclipse.wst.xml.search.editor.internal.style.LineStyleProviderForXMLReferences;

+import org.eclipse.wst.xml.ui.StructuredTextViewerConfigurationXML;

+import org.eclipse.wst.xml.ui.internal.style.LineStyleProviderForXML;

+

+public class XMLReferencesStructuredTextViewerConfiguration extends

+		StructuredTextViewerConfigurationXML {

+

+	private static final IHyperlinkDetector[] IHYPERLINK_DETECTOR_EMPTY = new IHyperlinkDetector[0];

+

+	private LineStyleProvider fLineStyleProviderForXML;

+

+	@Override

+	public IContentAssistProcessor[] getContentAssistProcessors(

+			ISourceViewer sourceViewer, String partitionType) {

+		IContentAssistProcessor processors[];

+		if (partitionType == IStructuredPartitions.DEFAULT_PARTITION

+				|| partitionType == IXMLPartitions.XML_DEFAULT)

+			processors = (new IContentAssistProcessor[] { createContentAssistProcessor() });

+		else

+			processors = super.getContentAssistProcessors(sourceViewer,

+					partitionType);

+		return processors;

+	}

+

+	@Override

+	public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {

+		if (sourceViewer == null

+				|| !fPreferenceStore.getBoolean("hyperlinksEnabled"))

+			return null;

+		List<IHyperlinkDetector> allDetectors = new ArrayList<IHyperlinkDetector>();

+		allDetectors.add(createHyperlinkDetector());

+		IHyperlinkDetector superDetectors[] = super

+				.getHyperlinkDetectors(sourceViewer);

+		IHyperlinkDetector aihyperlinkdetector[];

+		int j = (aihyperlinkdetector = superDetectors).length;

+		for (int i = 0; i < j; i++) {

+			IHyperlinkDetector detector = aihyperlinkdetector[i];

+			if (!allDetectors.contains(detector))

+				allDetectors.add(detector);

+		}

+		return allDetectors.toArray(IHYPERLINK_DETECTOR_EMPTY);

+	}

+

+	@Override

+	public ITextHover getTextHover(ISourceViewer sourceViewer,

+			String contentType, int stateMask) {

+		ITextHover textHover = null;

+

+		/*

+		 * Returns a default problem, annotation, and best match hover depending

+		 * on stateMask

+		 */

+		TextHoverManager.TextHoverDescriptor[] hoverDescs = SSEUIPlugin

+				.getDefault().getTextHoverManager().getTextHovers();

+		int i = 0;

+		while (i < hoverDescs.length && textHover == null) {

+			if (hoverDescs[i].isEnabled()

+					&& computeStateMask(hoverDescs[i].getModifierString()) == stateMask) {

+				String hoverType = hoverDescs[i].getId();

+				if (TextHoverManager.PROBLEM_HOVER.equalsIgnoreCase(hoverType))

+					textHover = new ProblemAnnotationHoverProcessor();

+				else if (TextHoverManager.ANNOTATION_HOVER

+						.equalsIgnoreCase(hoverType))

+					textHover = new AnnotationHoverProcessor();

+				else if (TextHoverManager.COMBINATION_HOVER

+						.equalsIgnoreCase(hoverType))

+					textHover = new BestMatchHover(

+							createDocumentationHover(contentType));

+				else if (TextHoverManager.DOCUMENTATION_HOVER

+						.equalsIgnoreCase(hoverType)) {

+					textHover = createDocumentationHover(contentType);

+				}

+			}

+			i++;

+		}

+		return textHover;

+	}

+

+	protected ITextHover createDocumentationHover(String partitionType) {

+		ITextHover textHover = null;

+		if (partitionType == IStructuredPartitions.DEFAULT_PARTITION

+				|| partitionType == IXMLPartitions.XML_DEFAULT) {

+			return new XMLReferencesInfoHoverProcessor();

+		}

+		Object extendedTextHover = ExtendedConfigurationBuilder.getInstance()

+				.getConfiguration(

+						ExtendedConfigurationBuilder.DOCUMENTATIONTEXTHOVER,

+						partitionType);

+		if (extendedTextHover instanceof ITextHover) {

+			textHover = (ITextHover) extendedTextHover;

+		}

+		return textHover;

+	}

+

+	protected IContentAssistProcessor createContentAssistProcessor() {

+		return new XMLReferencesContentAssistProcessor();

+	}

+

+	protected IHyperlinkDetector createHyperlinkDetector() {

+		return new XMLReferencesHyperlinkDetector();

+	}

+

+	@Override

+	public LineStyleProvider[] getLineStyleProviders(

+			ISourceViewer sourceViewer, String partitionType) {

+		LineStyleProvider[] providers = null;

+		if ((partitionType == IXMLPartitions.XML_DEFAULT)

+				|| (partitionType == IXMLPartitions.XML_CDATA)

+				|| (partitionType == IXMLPartitions.XML_COMMENT)

+				|| (partitionType == IXMLPartitions.XML_DECLARATION)

+				|| (partitionType == IXMLPartitions.XML_PI)) {

+			providers = new LineStyleProvider[] { getLineStyleProviderForXML(sourceViewer) };

+		}

+		return providers;

+	}

+

+	private LineStyleProvider getLineStyleProviderForXML(

+			ISourceViewer sourceViewer) {

+		if (fLineStyleProviderForXML == null) {

+			if (isColorReferencedNodes()) {

+				IDOMModel model = (IDOMModel) StructuredModelManager

+						.getModelManager().getExistingModelForRead(

+								((StructuredTextViewer) sourceViewer)

+										.getDocument());

+				fLineStyleProviderForXML = new LineStyleProviderForXMLReferences(

+						model);

+			} else {

+				fLineStyleProviderForXML = new LineStyleProviderForXML();

+			}

+		}

+		return fLineStyleProviderForXML;

+	}

+

+	protected boolean isColorReferencedNodes() {

+		return true;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrCompletionProposal.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrCompletionProposal.java
new file mode 100644
index 0000000..c1bb7fd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrCompletionProposal.java
@@ -0,0 +1,321 @@
+/*******************************************************************************

+ * Copyright (c) 2001, 2007 IBM Corporation and others

+ * Copyright (c) 2005, 2007 Spring IDE Developers    

+ * 

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *     

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.jface.text.BadLocationException;

+import org.eclipse.jface.text.DocumentEvent;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.jface.text.ITextViewer;

+import org.eclipse.jface.text.ITextViewerExtension5;

+import org.eclipse.jface.text.contentassist.CompletionProposal;

+import org.eclipse.jface.text.contentassist.ICompletionProposal;

+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension;

+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;

+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;

+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5;

+import org.eclipse.jface.text.contentassist.IContextInformation;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.swt.graphics.Point;

+import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceCompletionProposal;

+import org.w3c.dom.Attr;

+

+/**

+ * 

+ * JFace {@link ICompletionProposal} completion proposal for DOM {@link Attr}.

+ */

+class DOMAttrCompletionProposal implements ICompletionProposal,

+		ICompletionProposalExtension, ICompletionProposalExtension2,

+		ICompletionProposalExtension4, ICompletionProposalExtension5,

+		IRelevanceCompletionProposal {

+

+	private IContextInformation fContextInformation;

+	private int fCursorPosition;

+	private String fDisplayString;

+	private Image fImage;

+	private int fOriginalReplacementLength;

+	private int fRelevance;

+	private int fReplacementLength;

+	private int fReplacementOffset;

+	private String fReplacementString;

+	private char fTriggers[];

+	private boolean fUpdateLengthOnValidate;

+	private Object proposedObject;

+

+	public DOMAttrCompletionProposal(String replacementString,

+			int replacementOffset, int replacementLength, int cursorPosition,

+			Image image, String displayString,

+			IContextInformation contextInformation, int relevance,

+			boolean updateReplacementLengthOnValidate, Object proposedObject) {

+		fCursorPosition = 0;

+		fRelevance = 0;

+		fReplacementLength = 0;

+		fReplacementOffset = 0;

+		fReplacementString = null;

+		this.proposedObject = null;

+		fReplacementString = (new StringBuilder("\""))

+				.append(replacementString).toString();

+		fReplacementOffset = replacementOffset;

+		fReplacementLength = replacementLength;

+		fCursorPosition = cursorPosition + 1;

+		fImage = image;

+		fDisplayString = displayString;

+		fContextInformation = contextInformation;

+		fRelevance = relevance;

+		fUpdateLengthOnValidate = updateReplacementLengthOnValidate;

+		fOriginalReplacementLength = fReplacementLength;

+		this.proposedObject = proposedObject;

+	}

+

+	public DOMAttrCompletionProposal(String replacementString,

+			int replacementOffset, int replacementLength, int cursorPosition,

+			Image image, String displayString,

+			IContextInformation contextInformation, int relevance,

+			Object proposedObject) {

+		this(replacementString, replacementOffset, replacementLength,

+				cursorPosition, image, displayString, contextInformation,

+				relevance, true, proposedObject);

+	}

+

+	public void apply(IDocument document) {

+		String charBeforeCursor = "";

+		try {

+			charBeforeCursor = document.get(getReplacementOffset() - 1, 1);

+		} catch (BadLocationException _ex) {

+		}

+		if ("\"".equals(charBeforeCursor)) {

+			CompletionProposal proposal = new CompletionProposal(

+					getReplacementString(), getReplacementOffset() - 1,

+					getReplacementLength(), getCursorPosition() + 1,

+					getImage(), getDisplayString(), getContextInformation(),

+					getAdditionalProposalInfo());

+			proposal.apply(document);

+		} else {

+			CompletionProposal proposal = new CompletionProposal(

+					(new StringBuilder(String.valueOf(getReplacementString())))

+							.append("\"").toString(), getReplacementOffset(),

+					getReplacementLength(), getCursorPosition() + 1,

+					getImage(), getDisplayString(), getContextInformation(),

+					getAdditionalProposalInfo());

+			proposal.apply(document);

+		}

+	}

+

+	public void apply(IDocument document, char trigger, int offset) {

+		try {

+			document.get(getReplacementOffset(), 1);

+		} catch (BadLocationException _ex) {

+		}

+		CompletionProposal proposal = new CompletionProposal(

+				(new StringBuilder(String.valueOf(getReplacementString())))

+						.append("\"").toString(), getReplacementOffset(),

+				getReplacementLength(), getCursorPosition() + 1, getImage(),

+				getDisplayString(), getContextInformation(),

+				getAdditionalProposalInfo());

+		proposal.apply(document);

+	}

+

+	public void apply(ITextViewer viewer, char trigger, int stateMask,

+			int offset) {

+		IDocument document = viewer.getDocument();

+		int caretOffset = viewer.getTextWidget().getCaretOffset();

+		if (viewer instanceof ITextViewerExtension5) {

+			ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;

+			caretOffset = extension.widgetOffset2ModelOffset(caretOffset);

+		} else {

+			caretOffset = viewer.getTextWidget().getCaretOffset()

+					+ viewer.getVisibleRegion().getOffset();

+		}

+		if (caretOffset == getReplacementOffset())

+			apply(document);

+		else

+			try {

+				int endOffsetOfChanges = getReplacementString().length()

+						+ getReplacementOffset();

+				if (endOffsetOfChanges >= caretOffset) {

+					int postCaretReplacementLength = (getReplacementOffset() + getReplacementLength())

+							- caretOffset;

+					int preCaretReplacementLength = getReplacementString()

+							.length() - (endOffsetOfChanges - caretOffset);

+					if (postCaretReplacementLength < 0)

+						postCaretReplacementLength = 0;

+					String charAfterCursor = document.get(caretOffset, 1);

+					if ("\"".equals(charAfterCursor))

+						document.replace(

+								caretOffset,

+								postCaretReplacementLength - 1 >= 0 ? postCaretReplacementLength - 1

+										: postCaretReplacementLength,

+								getReplacementString().substring(

+										preCaretReplacementLength));

+					else

+						document.replace(

+								caretOffset,

+								postCaretReplacementLength,

+								(new StringBuilder(

+										String.valueOf(getReplacementString()

+												.substring(

+														preCaretReplacementLength))))

+										.append("\"").toString());

+				}

+				if (caretOffset > getReplacementOffset()) {

+					int preCaretTextLength = caretOffset

+							- getReplacementOffset();

+					document.replace(getReplacementOffset(),

+							preCaretTextLength, getReplacementString()

+									.substring(0, preCaretTextLength));

+				}

+			} catch (BadLocationException _ex) {

+				apply(document);

+			} catch (StringIndexOutOfBoundsException _ex) {

+				apply(document);

+			}

+	}

+

+	public String getAdditionalProposalInfo() {

+		Object o = getProposedObject();

+		if (o instanceof String) {

+			return (String) o;

+		}

+		return "";

+		// SIDocEditorUtils.createAdditionalProposalInfo(

+		// getProposedObject(), new NullProgressMonitor());

+	}

+

+	public Object getAdditionalProposalInfo(IProgressMonitor monitor) {

+		Object o = getProposedObject();

+		if (o instanceof String) {

+			return (String) o;

+		}

+		return "";

+	}

+

+	public IContextInformation getContextInformation() {

+		return fContextInformation;

+	}

+

+	public int getContextInformationPosition() {

+		return getCursorPosition();

+	}

+

+	public int getCursorPosition() {

+		return fCursorPosition;

+	}

+

+	public String getDisplayString() {

+		return fDisplayString;

+	}

+

+	public Image getImage() {

+		return fImage;

+	}

+

+	public Object getProposedObject() {

+		return proposedObject;

+	}

+

+	public int getRelevance() {

+		return fRelevance;

+	}

+

+	public int getReplacementLength() {

+		return fReplacementLength;

+	}

+

+	public int getReplacementOffset() {

+		return fReplacementOffset;

+	}

+

+	public String getReplacementString() {

+		return fReplacementString;

+	}

+

+	public Point getSelection(IDocument document) {

+		CompletionProposal proposal = new CompletionProposal(

+				getReplacementString(), getReplacementOffset(),

+				getReplacementLength(), getCursorPosition(), getImage(),

+				getDisplayString(), getContextInformation(), null);

+		return proposal.getSelection(document);

+	}

+

+	public char[] getTriggerCharacters() {

+		return fTriggers;

+	}

+

+	public boolean isAutoInsertable() {

+		return true;

+	}

+

+	public boolean isValidFor(IDocument document, int offset) {

+		return validate(document, offset, null);

+	}

+

+	public void selected(ITextViewer itextviewer, boolean flag) {

+	}

+

+	public void setContextInformation(IContextInformation contextInfo) {

+		fContextInformation = contextInfo;

+	}

+

+	public void setCursorPosition(int pos) {

+		fCursorPosition = pos;

+	}

+

+	public void setRelevance(int relevance) {

+		fRelevance = relevance;

+	}

+

+	public void setReplacementOffset(int replacementOffset) {

+		fReplacementOffset = replacementOffset;

+	}

+

+	public void setReplacementString(String replacementString) {

+		fReplacementString = replacementString;

+	}

+

+	public void setTriggerCharacters(char triggers[]) {

+		fTriggers = triggers;

+	}

+

+	protected boolean startsWith(IDocument document, int offset, String word) {

+		int wordLength = word != null ? word.length() : 0;

+		if (offset > fReplacementOffset + wordLength)

+			return false;

+		try {

+			int length = offset - fReplacementOffset;

+			String start = document.get(fReplacementOffset, length);

+			start = start.replaceAll("\"", "");

+			String wordTemp = word.replaceAll("\"", "").substring(0,

+					start.length());

+			return wordTemp.equalsIgnoreCase(start);

+		} catch (BadLocationException _ex) {

+			return false;

+		}

+	}

+

+	public void unselected(ITextViewer itextviewer) {

+	}

+

+	public boolean validate(IDocument document, int offset, DocumentEvent event) {

+		if (offset < fReplacementOffset)

+			return false;

+		boolean validated = startsWith(document, offset, fReplacementString);

+		boolean validatedClass = startsWith(document, offset, fDisplayString);

+		if (fUpdateLengthOnValidate) {

+			int newLength = offset - getReplacementOffset();

+			int delta = newLength - fOriginalReplacementLength;

+			fReplacementLength = delta + fOriginalReplacementLength;

+		}

+		return validated || validatedClass;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrContentAssistProposalRecorder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrContentAssistProposalRecorder.java
new file mode 100644
index 0000000..0e8f98f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMAttrContentAssistProposalRecorder.java
@@ -0,0 +1,81 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;

+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;

+

+@SuppressWarnings("restriction")

+public class DOMAttrContentAssistProposalRecorder implements

+		IContentAssistProposalRecorder {

+

+	private static final String ICONS_FULL_OBJ16_ENUM_GIF = "icons/full/obj16/enum.gif";

+

+	private final ContentAssistRequest request;

+

+	/**

+	 * 

+	 * Creates a new {@link DOMAttrContentAssistProposalRecorder}.

+	 */

+

+	public DOMAttrContentAssistProposalRecorder(ContentAssistRequest request) {

+		this.request = request;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.editor.contentassist.

+	 * IContentAssistProposalRecorder

+	 * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,

+	 * java.lang.String)

+	 */

+	public void recordProposal(Image image, int relevance, String displayText,

+			String replaceText) {

+		recordProposal(image, relevance, displayText, replaceText, null);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.editor.contentassist.

+	 * IContentAssistProposalRecorder

+	 * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,

+	 * java.lang.String, java.lang.Object)

+	 */

+	public void recordProposal(Image image, int relevance, String displayText,

+			String replaceText, Object proposedObject) {

+		recordProposal(image, relevance, displayText, replaceText,

+				replaceText.length(), proposedObject);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.editor.contentassist.

+	 * IContentAssistProposalRecorder

+	 * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,

+	 * java.lang.String, int, java.lang.Object)

+	 */

+	public void recordProposal(Image image, int relevance, String displayText,

+			String replaceText, int cursorPosition, Object proposedObject) {

+		if (image == null) {

+			image = XMLEditorPluginImageHelper.getInstance().getImage(

+					ICONS_FULL_OBJ16_ENUM_GIF);

+		}

+		request.addProposal(new DOMAttrCompletionProposal(replaceText, request

+				.getReplacementBeginPosition(), request.getReplacementLength(),

+				cursorPosition, image, displayText, null, relevance,

+				proposedObject));

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMNodeContentAssistContext.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMNodeContentAssistContext.java
new file mode 100644
index 0000000..77e04ff
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMNodeContentAssistContext.java
@@ -0,0 +1,83 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;

+import org.w3c.dom.Node;

+

+/**

+ * 

+ * Default implementation of {@link IContentAssistContext} that is used on the

+ * WTP XML editor

+ * 

+ * environment.

+ * 

+ * <p>

+ * 

+ * This implementation wraps the WTP internal class {@link ContentAssistRequest}.

+ * 

+ * 

+ * @since 2.2.1

+ */

+

+@SuppressWarnings("restriction")

+public class DOMNodeContentAssistContext implements IContentAssistContext {

+

+	private final String matchString;

+

+	private final ContentAssistRequest request;

+

+	/**

+	 * 

+	 * Creates a new {@link DOMNodeContentAssistContext}

+	 */

+	public DOMNodeContentAssistContext(ContentAssistRequest request, String matchString) {

+		this.request = request;

+		this.matchString = matchString;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.editor.contentassist.IContentAssistContext

+	 * #getFile()

+	 */

+	public IFile getFile() {

+		return DOMUtils.getFile((IDOMNode) getNode());

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.editor.contentassist.IContentAssistContext

+	 * #getMatchString()

+	 */

+	public String getMatchString() {

+		return matchString;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.wst.xml.search.editor.contentassist.IContentAssistContext

+	 * #getNode()

+	 */

+	public Node getNode() {

+		return request.getNode();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextCompletionProposal.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextCompletionProposal.java
new file mode 100644
index 0000000..cec8bb4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextCompletionProposal.java
@@ -0,0 +1,304 @@
+/*******************************************************************************

+ * Copyright (c) 2001, 2007 IBM Corporation and others

+ * Copyright (c) 2005, 2007 Spring IDE Developers    

+ * 

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.jface.text.BadLocationException;

+import org.eclipse.jface.text.DocumentEvent;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.jface.text.ITextViewer;

+import org.eclipse.jface.text.ITextViewerExtension5;

+import org.eclipse.jface.text.contentassist.CompletionProposal;

+import org.eclipse.jface.text.contentassist.ICompletionProposal;

+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension;

+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;

+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;

+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5;

+import org.eclipse.jface.text.contentassist.IContextInformation;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.swt.graphics.Point;

+import org.eclipse.wst.sse.ui.internal.contentassist.IRelevanceCompletionProposal;

+import org.w3c.dom.Text;

+

+/**

+ * 

+ * JFace {@link ICompletionProposal} completion proposal for DOM {@link Text}.

+ */

+public class DOMTextCompletionProposal implements ICompletionProposal,

+		ICompletionProposalExtension, ICompletionProposalExtension2,

+		ICompletionProposalExtension4, ICompletionProposalExtension5,

+		IRelevanceCompletionProposal {

+

+	private IContextInformation fContextInformation;

+	private int fCursorPosition;

+	private String fDisplayString;

+	private Image fImage;

+	private int fOriginalReplacementLength;

+	private int fRelevance;

+	private int fReplacementLength;

+	private int fReplacementOffset;

+	private String fReplacementString;

+	private char fTriggers[];

+	private boolean fUpdateLengthOnValidate;

+	private Object proposedObject;

+

+	public DOMTextCompletionProposal(String replacementString,

+			int replacementOffset, int replacementLength, int cursorPosition,

+			Image image, String displayString,

+			IContextInformation contextInformation, int relevance,

+			boolean updateReplacementLengthOnValidate, Object proposedObject) {

+		fCursorPosition = 0;

+		fRelevance = 0;

+		fReplacementLength = 0;

+		fReplacementOffset = 0;

+		fReplacementString = null;

+		this.proposedObject = null;

+		fReplacementString = replacementString;

+		fReplacementOffset = replacementOffset;

+		fReplacementLength = replacementLength;

+		fCursorPosition = cursorPosition + 1;

+		fImage = image;

+		fDisplayString = displayString;

+		fContextInformation = contextInformation;

+		fRelevance = relevance;

+		fUpdateLengthOnValidate = updateReplacementLengthOnValidate;

+		fOriginalReplacementLength = fReplacementLength;

+		this.proposedObject = proposedObject;

+	}

+

+	public DOMTextCompletionProposal(String replacementString,

+			int replacementOffset, int replacementLength, int cursorPosition,

+			Image image, String displayString,

+			IContextInformation contextInformation, int relevance,

+			Object proposedObject) {

+		this(replacementString, replacementOffset, replacementLength,

+				cursorPosition, image, displayString, contextInformation,

+				relevance, true, proposedObject);

+	}

+

+	public void apply(IDocument document) {

+		try {

+			document.get(getReplacementOffset() - 1, 1);

+		} catch (BadLocationException _ex) {

+		}

+		CompletionProposal proposal = new CompletionProposal(

+				getReplacementString(), getReplacementOffset(),

+				getReplacementLength(), getCursorPosition() + 1, getImage(),

+				getDisplayString(), getContextInformation(),

+				getAdditionalProposalInfo());

+		proposal.apply(document);

+	}

+

+	public void apply(IDocument document, char trigger, int offset) {

+		try {

+			document.get(getReplacementOffset(), 1);

+		} catch (BadLocationException _ex) {

+		}

+		CompletionProposal proposal = new CompletionProposal(

+				(new StringBuilder(String.valueOf(getReplacementString())))

+						.append("\"").toString(), getReplacementOffset(),

+				getReplacementLength(), getCursorPosition() + 1, getImage(),

+				getDisplayString(), getContextInformation(),

+				getAdditionalProposalInfo());

+		proposal.apply(document);

+	}

+

+	public void apply(ITextViewer viewer, char trigger, int stateMask,

+			int offset) {

+		IDocument document = viewer.getDocument();

+		int caretOffset = viewer.getTextWidget().getCaretOffset();

+		if (viewer instanceof ITextViewerExtension5) {

+			ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;

+			caretOffset = extension.widgetOffset2ModelOffset(caretOffset);

+		} else {

+			caretOffset = viewer.getTextWidget().getCaretOffset()

+					+ viewer.getVisibleRegion().getOffset();

+		}

+		if (caretOffset == getReplacementOffset())

+			apply(document);

+		else

+			try {

+				int endOffsetOfChanges = getReplacementString().length()

+						+ getReplacementOffset();

+				if (endOffsetOfChanges >= caretOffset) {

+					int postCaretReplacementLength = (getReplacementOffset() + getReplacementLength())

+							- caretOffset;

+					int preCaretReplacementLength = getReplacementString()

+							.length()

+							- (endOffsetOfChanges - caretOffset);

+					if (postCaretReplacementLength < 0)

+						postCaretReplacementLength = 0;

+					// String charAfterCursor = document.get(caretOffset, 1);

+					// if ("\"".equals(charAfterCursor))

+					document.replace(caretOffset, postCaretReplacementLength,

+							getReplacementString().substring(

+									preCaretReplacementLength));

+					// else

+					// document.replace(caretOffset,

+					// postCaretReplacementLength,

+					// getReplacementString());

+				}

+				// if (caretOffset > getReplacementOffset()) {

+				// int preCaretTextLength = caretOffset

+				// - getReplacementOffset();

+				// document.replace(getReplacementOffset(),

+				// preCaretTextLength, getReplacementString()

+				// .substring(0, preCaretTextLength));

+				// }

+			} catch (BadLocationException _ex) {

+				apply(document);

+			} catch (StringIndexOutOfBoundsException _ex) {

+				apply(document);

+			}

+	}

+

+	public String getAdditionalProposalInfo() {

+		Object o = getProposedObject();

+		if (o instanceof String) {

+			return (String) o;

+		}

+		return "";

+		// SIDocEditorUtils.createAdditionalProposalInfo(

+		// getProposedObject(), new NullProgressMonitor());

+	}

+

+	public Object getAdditionalProposalInfo(IProgressMonitor monitor) {

+		Object o = getProposedObject();

+		if (o instanceof String) {

+			return (String) o;

+		}

+		return "";

+		// SIDocEditorUtils.createAdditionalProposalInfo(

+		// getProposedObject(), monitor);

+	}

+

+	public IContextInformation getContextInformation() {

+		return fContextInformation;

+	}

+

+	public int getContextInformationPosition() {

+		return getCursorPosition();

+	}

+

+	public int getCursorPosition() {

+		return fCursorPosition;

+	}

+

+	public String getDisplayString() {

+		return fDisplayString;

+	}

+

+	public Image getImage() {

+		return fImage;

+	}

+

+	public Object getProposedObject() {

+		return proposedObject;

+	}

+

+	public int getRelevance() {

+		return fRelevance;

+	}

+

+	public int getReplacementLength() {

+		return fReplacementLength;

+	}

+

+	public int getReplacementOffset() {

+		return fReplacementOffset;

+	}

+

+	public String getReplacementString() {

+		return fReplacementString;

+	}

+

+	public Point getSelection(IDocument document) {

+		CompletionProposal proposal = new CompletionProposal(

+				getReplacementString(), getReplacementOffset(),

+				getReplacementLength(), getCursorPosition(), getImage(),

+				getDisplayString(), getContextInformation(), null);

+		return proposal.getSelection(document);

+	}

+

+	public char[] getTriggerCharacters() {

+		return fTriggers;

+	}

+

+	public boolean isAutoInsertable() {

+		return true;

+	}

+

+	public boolean isValidFor(IDocument document, int offset) {

+		return validate(document, offset, null);

+	}

+

+	public void selected(ITextViewer itextviewer, boolean flag) {

+	}

+

+	public void setContextInformation(IContextInformation contextInfo) {

+		fContextInformation = contextInfo;

+	}

+

+	public void setCursorPosition(int pos) {

+		fCursorPosition = pos;

+	}

+

+	public void setRelevance(int relevance) {

+		fRelevance = relevance;

+	}

+

+	public void setReplacementOffset(int replacementOffset) {

+		fReplacementOffset = replacementOffset;

+	}

+

+	public void setReplacementString(String replacementString) {

+		fReplacementString = replacementString;

+	}

+

+	public void setTriggerCharacters(char triggers[]) {

+		fTriggers = triggers;

+	}

+

+	protected boolean startsWith(IDocument document, int offset, String word) {

+		int wordLength = word != null ? word.length() : 0;

+		if (offset > fReplacementOffset + wordLength)

+			return false;

+		try {

+			int length = offset - fReplacementOffset;

+			String start = document.get(fReplacementOffset, length);

+			start = start.replaceAll("\"", "");

+			String wordTemp = word.replaceAll("\"", "").substring(0,

+					start.length());

+			return wordTemp.equalsIgnoreCase(start);

+		} catch (BadLocationException _ex) {

+			return false;

+		}

+	}

+

+	public void unselected(ITextViewer itextviewer) {

+	}

+

+	public boolean validate(IDocument document, int offset, DocumentEvent event) {

+		if (offset < fReplacementOffset)

+			return false;

+		boolean validated = startsWith(document, offset, fReplacementString);

+		boolean validatedClass = startsWith(document, offset, fDisplayString);

+		if (fUpdateLengthOnValidate) {

+			int newLength = offset - getReplacementOffset();

+			int delta = newLength - fOriginalReplacementLength;

+			fReplacementLength = delta + fOriginalReplacementLength;

+		}

+		return validated || validatedClass;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextContentAssistProposalRecorder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextContentAssistProposalRecorder.java
new file mode 100644
index 0000000..8ac74fd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DOMTextContentAssistProposalRecorder.java
@@ -0,0 +1,75 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;

+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;

+

+@SuppressWarnings("restriction")

+public class DOMTextContentAssistProposalRecorder implements

+		IContentAssistProposalRecorder {

+

+	private static final String ICONS_FULL_OBJ16_ENUM_GIF = "icons/full/obj16/enum.gif";

+	

+	private final ContentAssistRequest request;

+

+	private final String textContent;

+

+	private final int startOffset;

+

+	/**

+	 * 

+	 * Creates a new {@link DOMTextContentAssistProposalRecorder}.

+	 */

+

+	public DOMTextContentAssistProposalRecorder(ContentAssistRequest request,

+			String textContent, int startOffset) {

+		this.request = request;

+		this.textContent = textContent;

+		this.startOffset = startOffset;

+	}

+

+	/**

+	 * 

+	 * {@inheritDoc}

+	 */

+

+	public void recordProposal(Image image, int relevance, String displayText,

+			String replaceText) {

+		recordProposal(image, relevance, displayText, replaceText, null);

+	}

+

+	/**

+	 * 

+	 * {@inheritDoc}

+	 */

+

+	public void recordProposal(Image image, int relevance, String displayText,

+			String replaceText, Object proposedObject) {

+		int newLength = replaceText.length() - 1;

+		recordProposal(image, relevance, displayText, replaceText, newLength,

+				proposedObject);

+	}

+

+	public void recordProposal(Image image, int relevance, String displayText,

+			String replaceText, int cursorPosition, Object proposedObject) {

+		if (image == null) {

+			image = XMLEditorPluginImageHelper.getInstance().getImage(

+					ICONS_FULL_OBJ16_ENUM_GIF);

+		}

+		int oldLength = textContent.length();

+		request.addProposal(new DOMTextCompletionProposal(replaceText,

+				startOffset, oldLength, cursorPosition, image, displayText,

+				null, relevance, proposedObject));

+

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DefaultDOMContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DefaultDOMContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..9a9da76
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/DefaultDOMContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,105 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.eclipse.wst.xml.search.ui.ImageResource;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Element;

+import org.w3c.dom.NamedNodeMap;

+import org.w3c.dom.Node;

+import org.w3c.dom.Text;

+

+/**

+ * Default content assist additionnal proposal for {@link Node}.

+ *

+ */

+public class DefaultDOMContentAssistAdditionalProposalInfoProvider extends

+		NodeContentAssistAdditionalProposalInfoProvider {

+

+	public static final IContentAssistAdditionalProposalInfoProvider<Node> INSTANCE = new DefaultDOMContentAssistAdditionalProposalInfoProvider();

+

+	public Image getImage(Node node) {

+		if (node == null) {

+			return null;

+		}

+		int nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			return ImageResource.getImage(ImageResource.IMG_ATTRIBUTE_OBJ);

+		case Node.TEXT_NODE:

+			return ImageResource.getImage(ImageResource.IMG_TEXT_OBJ);

+		case Node.ELEMENT_NODE:

+			return ImageResource.getImage(ImageResource.IMG_ELEMENT_OBJ);

+		}

+		return null;

+	}

+

+	@Override

+	public String getDisplayText(String displayText, Node node) {

+		String fileName = DOMUtils.getFileName((IDOMNode) node);

+		return super

+				.getDisplayText(displayText + " - [" + fileName + "]", node);

+	}

+

+	public String getTextInfo(Node node) {

+		int nodeType = node.getNodeType();

+		StringBuilder buf = new StringBuilder();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			Attr attr = (Attr) node;

+			buf.append("<b>Node type:</b> Attribute");

+			buf.append("<br><b>Attr name: </b>");

+			buf.append(attr.getName());

+			buf.append("<br><b>Attr value: </b>");

+			buf.append(attr.getValue());

+			break;

+		case Node.TEXT_NODE:

+			Text text = (Text) node;

+			buf.append("<b>Node type:</b> Text");

+			buf.append("<br><b>Text content: </b>");

+			buf.append(DOMUtils.getTextContent(text));

+			break;

+		case Node.ELEMENT_NODE:

+			Element element = (Element) node;

+			buf.append("<b>Node type:</b> Element");

+			buf.append("<br><b>Element name: </b>");

+			buf.append(element.getNodeName());

+			break;

+		}

+		Element element = DOMUtils.getOwnerElement(node);

+		if (element != null) {

+			buf.append("<br><b>Owner element:</b><ul> ");

+			Attr attr = null;

+			NamedNodeMap attributes = element.getAttributes();

+			for (int i = 0; i < attributes.getLength(); i++) {

+				attr = (Attr) attributes.item(i);

+				buf.append("<li><b>@");

+				buf.append(attr.getName());

+				buf.append(": </b>");

+				buf.append(attr.getValue());

+				buf.append("</li>");

+			}

+			buf.append("</ul>");

+		}

+		buf.append("<br><b>XPath:</b> ");

+		buf.append(XPathManager.getManager().computeBasicXPath(node,

+				XPathManager.getManager().getNamespaceInfo(node)));

+		buf.append("<br><b>File:</b> ");

+		String baseLocation = ((IDOMNode) node).getModel().getBaseLocation();

+		buf.append(baseLocation);

+		return buf.toString();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ElementContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ElementContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..1ca3941
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ElementContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+/**

+ * Content assist additionnal proposal for {@link Element}.

+ * 

+ */

+public abstract class ElementContentAssistAdditionalProposalInfoProvider extends

+		NodeContentAssistAdditionalProposalInfoProvider {

+

+	public String getTextInfo(Node node) {

+		if (node == null) {

+			return null;

+		}

+		Element element = DOMUtils.getOwnerElement(node);

+		if (element != null) {

+			return doGetTextInfo((IDOMElement) element);

+		}

+		return null;

+

+	}

+

+	protected abstract String doGetTextInfo(IDOMElement element);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..3b7ed37
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,27 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.swt.graphics.Image;

+

+/**

+ * Content assist additional proposal info provider.

+ * 

+ * @param <T>

+ */

+public interface IContentAssistAdditionalProposalInfoProvider<T> {

+

+	String getDisplayText(String displayText, T node);

+

+	Image getImage(T node);

+

+	String getTextInfo(T node);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistCalculator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistCalculator.java
new file mode 100644
index 0000000..135c18e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistCalculator.java
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+public interface IContentAssistCalculator {

+

+	/**

+	 * 

+	 * Calculate content assist proposals under the given context.

+	 * 

+	 * @param context

+	 *            the current context of the content assist proposal request

+	 * 

+	 * @param recorder

+	 *            the recorder to record calculated proposals

+	 */

+

+	void computeProposals(IContentAssistContext context,

+			IContentAssistProposalRecorder recorder);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistContext.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistContext.java
new file mode 100644
index 0000000..b09a6f3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistContext.java
@@ -0,0 +1,24 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.core.resources.IFile;

+import org.w3c.dom.Node;

+

+public interface IContentAssistContext {

+

+	String getMatchString();

+

+	IFile getFile();

+

+	Node getNode();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistProposalRecorder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistProposalRecorder.java
new file mode 100644
index 0000000..12df16f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/IContentAssistProposalRecorder.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.swt.graphics.Image;

+

+public interface IContentAssistProposalRecorder {

+

+	void recordProposal(Image image, int relevance, String displayText,

+			String replaceText);

+

+	void recordProposal(Image image, int relevance, String displayText,

+			String replaceText, Object proposedObject);

+

+	void recordProposal(Image image, int relevance, String displayText,

+			String replaceText, int cursorPosition, Object proposedObject);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/NodeContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/NodeContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..d68a197
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/NodeContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,21 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.w3c.dom.Node;

+

+public abstract class NodeContentAssistAdditionalProposalInfoProvider implements

+		IContentAssistAdditionalProposalInfoProvider<Node> {

+

+	public String getDisplayText(String displayText, Node node) {

+		return displayText;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/PropertyContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/PropertyContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..d685a64
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/PropertyContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.search.editor.internal.ImageResource;

+import org.eclipse.wst.xml.search.editor.searchers.properties.PropertyInfo;

+

+public class PropertyContentAssistAdditionalProposalInfoProvider implements

+		IContentAssistAdditionalProposalInfoProvider<PropertyInfo> {

+

+	public static final IContentAssistAdditionalProposalInfoProvider<PropertyInfo> INSTANCE = new PropertyContentAssistAdditionalProposalInfoProvider();

+

+	public String getDisplayText(String displayText, PropertyInfo node) {

+		String fileName = node.getPropertiesFile().getName();

+		return displayText + " - [" + fileName + "]";

+	}

+

+	public Image getImage(PropertyInfo node) {

+		return ImageResource.getImage(ImageResource.IMG_PROPERTY_OBJ);

+	}

+

+	public String getTextInfo(PropertyInfo node) {

+		StringBuilder buf = new StringBuilder();

+		buf.append("<b>Property name:</b> ");

+		buf.append(node.getKey());

+		buf.append("<br><b>Property value:</b> ");

+		buf.append(node.getName());

+		IStorage propertiesFiles = node.getPropertiesFile();

+		buf.append("<br><b>File name:</b> ");

+		buf.append(propertiesFiles.getName().toString());

+		buf.append("<br><b>Location:</b> ");

+		buf.append(propertiesFiles.getFullPath().toString());

+		return buf.toString();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ResourceContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ResourceContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..4a7d2ea
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/ResourceContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,83 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.content.IContentDescription;

+import org.eclipse.core.runtime.content.IContentType;

+import org.eclipse.jface.viewers.ILabelProvider;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.ui.model.WorkbenchLabelProvider;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+

+public class ResourceContentAssistAdditionalProposalInfoProvider implements

+		IContentAssistAdditionalProposalInfoProvider<IResource> {

+

+	private static ILabelProvider WORKBENCH_LABEL_PROVIDER = null;

+	public static final IContentAssistAdditionalProposalInfoProvider<IResource> INSTANCE = new ResourceContentAssistAdditionalProposalInfoProvider();

+

+	public Image getImage(IResource resource) {

+		if (WORKBENCH_LABEL_PROVIDER == null) {

+			WORKBENCH_LABEL_PROVIDER = new WorkbenchLabelProvider();

+		}

+		return WORKBENCH_LABEL_PROVIDER.getImage(resource);

+	}

+

+	public String getDisplayText(String displayText, IResource resource) {

+		return displayText;

+	}

+

+	public String getTextInfo(IResource resource) {

+		StringBuilder buf = new StringBuilder();

+		buf.append("<b>Path:</b> ");

+		buf.append("/" + resource.getProject().getName() + "/"

+				+ resource.getProjectRelativePath().toString());

+		buf.append("<br><b>Type:</b> ");

+		switch (resource.getType()) {

+		case IResource.FILE:

+			buf.append("File");

+			String type = getType((IFile) resource);

+			if (!StringUtils.isEmpty(type)) {

+				buf.append(" (");

+				buf.append(type);

+				buf.append(")");

+			}

+			break;

+		case IResource.PROJECT:

+			buf.append("Project");

+			break;

+		case IResource.FOLDER:

+			buf.append("Folder");

+			break;

+		}

+		buf.append("<br><b>Location:</b> ");

+		buf.append(resource.getLocation().toString());

+		return buf.toString();

+	}

+

+	protected String getType(IFile file) {

+		try {

+			IContentDescription contentDescription = file

+					.getContentDescription();

+			if (contentDescription != null) {

+				IContentType contentType = contentDescription.getContentType();

+				if (contentType != null) {

+					return contentType.getName();

+				}

+			}

+		} catch (CoreException e) {

+			// ignore error

+		}

+		return null;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..c3c485e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.wst.xml.search.core.statics.IStaticValue;

+

+public abstract class StaticValueContentAssistAdditionalProposalInfoProvider<T extends IStaticValue>

+		implements IContentAssistAdditionalProposalInfoProvider<T> {

+

+	public String getDisplayText(String displayText, T value) {

+		return value.getKey();

+	}

+

+	public String getTextInfo(T value) {

+		return value.getDescription();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueDocumentContentAssistAdditionalProposalInfoProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueDocumentContentAssistAdditionalProposalInfoProvider.java
new file mode 100644
index 0000000..e287f3a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/StaticValueDocumentContentAssistAdditionalProposalInfoProvider.java
@@ -0,0 +1,15 @@
+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.wst.xml.search.editor.statics.StaticValueDocument;

+

+public abstract class StaticValueDocumentContentAssistAdditionalProposalInfoProvider

+		extends

+		StaticValueContentAssistAdditionalProposalInfoProvider<StaticValueDocument> {

+

+	@Override

+	public String getDisplayText(String displayText, StaticValueDocument value) {

+		String fileName = value.getResource().getName();

+		return displayText + " - [" + fileName + "]";

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/XMLReferencesContentAssistUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/XMLReferencesContentAssistUtils.java
new file mode 100644
index 0000000..a001866
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/contentassist/XMLReferencesContentAssistUtils.java
@@ -0,0 +1,121 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.contentassist;

+

+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.internal.contentassist.XMLReferencesContentAssistCalculator;

+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;

+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;

+import org.w3c.dom.Node;

+

+public class XMLReferencesContentAssistUtils {

+

+	public static void addAttributeValueProposals(ContentAssistRequest request) {

+		IDOMNode node = (IDOMNode) request.getNode();

+

+		// Find the attribute

+		IDOMAttr selectedNode = DOMUtils.getAttrByRegion(node,

+				request.getRegion());

+		if (selectedNode == null) {

+			return;

+		}

+		String matchString = EditorUtils.prepareMatchString(request);

+		IXMLReference reference = XMLReferencesUtil.getXMLReference(

+				selectedNode, selectedNode.getModel()

+						.getContentTypeIdentifier());

+		if (reference != null) {

+			IContentAssistCalculator calculator = new XMLReferencesContentAssistCalculator(

+					reference, selectedNode);

+			if (calculator != null) {

+				IContentAssistContext context = new DOMNodeContentAssistContext(

+						request, matchString);

+				IContentAssistProposalRecorder recorder = new DOMAttrContentAssistProposalRecorder(

+						request);

+				calculator.computeProposals(context, recorder);

+			}

+		}

+	}

+

+	public static void addEntityProposals(

+			IContentAssistProcessor delegatingContentAssistProcessor,

+			ContentAssistRequest request) {

+

+		String textContent = "";

+		IDOMNode node = (IDOMNode) request.getNode();

+		IDOMText text = getDOMText(node);

+		String matchString = "";

+		int startOffset = request.getStartOffset();

+		if (text != null) {

+			matchString = text.getData();

+			textContent = matchString;

+			int replacementBeginPosition = request

+					.getReplacementBeginPosition();

+			startOffset = text.getStartOffset();

+			int l = replacementBeginPosition - startOffset;

+			matchString = matchString.replaceAll("\r", "");

+			matchString = matchString.trim();

+			if (matchString.length() > l) {

+				matchString = matchString.substring(0, l);

+			}

+

+			node = text;

+		}

+

+		String prefix = null;

+		String namespace = null;

+		if (prefix == null && namespace == null) {

+			prefix = node.getPrefix();

+			namespace = node.getNamespaceURI();

+		}

+		computeDOMTextProposals(request, node, matchString, namespace, prefix,

+				textContent, startOffset);

+	}

+

+	private static IDOMText getDOMText(IDOMNode node) {

+		if (node == null) {

+			return null;

+		}

+		if (node.getNodeType() == Node.TEXT_NODE) {

+			return (IDOMText) node;

+		}

+		if (node.getNodeType() == Node.ELEMENT_NODE) {

+			IDOMNode firstChild = (IDOMNode) node.getFirstChild();

+			return getDOMText(firstChild);

+		}

+		return null;

+	}

+

+	private static void computeDOMTextProposals(ContentAssistRequest request,

+			IDOMNode node, String matchString, String namespace, String prefix,

+			String textContent, int startOffset) {

+		IDOMNode selectedNode = node;

+		IXMLReference reference = XMLReferencesUtil.getXMLReference(

+				selectedNode, EditorUtils.getFile(request));

+		if (reference != null) {

+			IContentAssistCalculator calculator = new XMLReferencesContentAssistCalculator(

+					reference, selectedNode);

+			if (calculator != null) {

+				IContentAssistContext context = new DOMNodeContentAssistContext(

+						request, matchString);

+				IContentAssistProposalRecorder recorder = new DOMTextContentAssistProposalRecorder(

+						request, textContent, startOffset);

+				calculator.computeProposals(context, recorder);

+			}

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hover/XMLReferencesInfoHoverProcessor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hover/XMLReferencesInfoHoverProcessor.java
new file mode 100644
index 0000000..9040036
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hover/XMLReferencesInfoHoverProcessor.java
@@ -0,0 +1,224 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.hover;

+

+import java.util.Collection;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jface.text.BadLocationException;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.ITextViewer;

+import org.eclipse.jface.text.Region;

+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;

+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;

+import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.ui.internal.Logger;

+import org.eclipse.wst.xml.ui.internal.taginfo.XMLTagInfoHoverProcessor;

+import org.w3c.dom.Node;

+

+public class XMLReferencesInfoHoverProcessor extends XMLTagInfoHoverProcessor {

+

+	/**

+	 * Retrieves documentation to display in the hover help popup.

+	 * 

+	 * @return String any documentation information to display <code>null</code>

+	 *         if there is nothing to display.

+	 * 

+	 */

+	protected String computeHoverHelp(ITextViewer textViewer,

+			int documentPosition) {

+		String result = null;

+

+		IndexedRegion treeNode = ContentAssistUtils.getNodeAt(textViewer,

+				documentPosition);

+		if (treeNode == null) {

+			return null;

+		}

+		Node node = (Node) treeNode;

+

+		while ((node != null) && (node.getNodeType() == Node.TEXT_NODE)

+				&& (node.getParentNode() != null)) {

+			node = node.getParentNode();

+		}

+		IDOMNode parentNode = (IDOMNode) node;

+

+		IStructuredDocumentRegion flatNode = ((IStructuredDocument) textViewer

+				.getDocument()).getRegionAtCharacterOffset(documentPosition);

+		if (flatNode != null) {

+			ITextRegion region = flatNode

+					.getRegionAtCharacterOffset(documentPosition);

+			if (region != null) {

+				result = computeRegionHelp(treeNode, parentNode, flatNode,

+						region, documentPosition);

+			}

+		}

+

+		return result;

+	}

+

+	/**

+	 * Computes the hoverhelp based on region

+	 * 

+	 * @return String hoverhelp

+	 */

+	// @Override

+	protected String computeRegionHelp(IndexedRegion treeNode,

+			IDOMNode parentNode, IStructuredDocumentRegion flatNode,

+			ITextRegion region, int documentPosition) {

+		String result = null;

+		if (region == null) {

+			return null;

+		}

+		String regionType = region.getType();

+		if (regionType == DOMRegionContext.XML_TAG_NAME) {

+			result = computeTagNameHelp((IDOMNode) treeNode, parentNode,

+					flatNode, region);

+		} else if (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {

+			result = computeTagAttNameHelp((IDOMNode) treeNode, parentNode,

+					flatNode, region);

+		} else if (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {

+			int offset = documentPosition - flatNode.getStart()

+					- region.getStart();

+			result = computeTagAttValueHelp((IDOMNode) treeNode, parentNode,

+					flatNode, region);

+		}

+		if (regionType == DOMRegionContext.XML_CONTENT) {

+			int offset = documentPosition - flatNode.getStart();

+			result = computeXMLContentValueHelp((IDOMNode) treeNode,

+					parentNode, flatNode, region);

+		}

+		return result;

+	}

+

+	@Override

+	public IRegion getHoverRegion(ITextViewer textViewer, int offset) {

+		if ((textViewer == null) || (textViewer.getDocument() == null)) {

+			return null;

+		}

+

+		IStructuredDocumentRegion flatNode = ((IStructuredDocument) textViewer

+				.getDocument()).getRegionAtCharacterOffset(offset);

+		ITextRegion region = null;

+

+		if (flatNode != null) {

+			region = flatNode.getRegionAtCharacterOffset(offset);

+		}

+

+		if (region != null) {

+			// only supply hoverhelp for tag name, attribute name, or

+			// attribute value

+			String regionType = region.getType();

+			if ((regionType == DOMRegionContext.XML_TAG_NAME)

+					|| (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME)

+					|| (regionType == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE || regionType == DOMRegionContext.XML_CONTENT)) {

+				try {

+					// check if we are at whitespace before or after line

+					IRegion line = textViewer.getDocument()

+							.getLineInformationOfOffset(offset);

+					if ((offset > (line.getOffset()))

+							&& (offset < (line.getOffset() + line.getLength()))) {

+						// check if we are in region's trailing whitespace

+						// (whitespace after relevant info)

+						if (offset < flatNode.getTextEndOffset(region)) {

+							return new Region(flatNode.getStartOffset(region),

+									region.getTextLength());

+						}

+					}

+				} catch (BadLocationException e) {

+					Logger.logException(e);

+				}

+			}

+		}

+		return null;

+	}

+

+	@Override

+	protected String computeTagAttValueHelp(IDOMNode xmlnode,

+			IDOMNode parentNode, IStructuredDocumentRegion flatNode,

+			ITextRegion region) {

+		IDOMAttr attr = DOMUtils.getAttrByRegion(xmlnode, region);

+		if (attr != null) {

+			String textInfo = getTextInfo(attr);

+			if (!StringUtils.isEmpty(textInfo)) {

+				return textInfo;

+			}

+		}

+		return super.computeTagAttValueHelp(xmlnode, parentNode, flatNode,

+				region);

+	}

+

+	private String getTextInfo(IDOMNode selectedNode) {

+		IXMLReference reference = XMLReferencesManager.getInstance()

+				.getXMLReference(selectedNode,

+						selectedNode.getModel().getContentTypeIdentifier());

+		if (reference != null) {

+			StringBuilder infos = null;

+			IFile file = DOMUtils.getFile(selectedNode);

+			if (reference.isExpression()) {

+				IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;

+				IXMLSearcher searcher = expression.getSearcher();

+				if (searcher != null) {

+					String textInfo = searcher.searchForTextHover(selectedNode,

+							-1, DOMUtils.getNodeValue(selectedNode), -1, -1,

+							file, expression);

+					infos = getTextHover(infos, textInfo);

+				}

+			} else {

+				Collection<IXMLReferenceTo> to = reference.getTo();

+				for (IXMLReferenceTo referenceTo : to) {

+					IXMLSearcher searcher = referenceTo.getSearcher();

+					if (searcher != null) {

+						String textInfo = searcher.searchForTextHover(

+								selectedNode, -1,

+								DOMUtils.getNodeValue(selectedNode), -1, -1,

+								file, referenceTo);

+						infos = getTextHover(infos, textInfo);

+					}

+				}

+			}

+

+			if (infos != null && infos.length() > 0) {

+				return infos.toString();

+			}

+		}

+		return null;

+	}

+

+	private StringBuilder getTextHover(StringBuilder infos, String textInfo) {

+		if (!StringUtils.isEmpty(textInfo)) {

+			if (infos == null) {

+				infos = new StringBuilder();

+			} else {

+				infos.append("<br /><br />");

+			}

+			infos.append(textInfo);

+		}

+		return infos;

+	}

+

+	private String computeXMLContentValueHelp(IDOMNode xmlnode,

+			IDOMNode parentNode, IStructuredDocumentRegion flatNode,

+			ITextRegion region) {

+		return getTextInfo(xmlnode);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/HyperlinkUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/HyperlinkUtils.java
new file mode 100644
index 0000000..a15a10e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/HyperlinkUtils.java
@@ -0,0 +1,56 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.hyperlink;

+

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.Region;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.w3c.dom.Node;

+

+public class HyperlinkUtils {

+

+    public static IRegion getHyperlinkRegion(Node node)

+    {

+        if(node != null)

+            switch(node.getNodeType())

+            {

+            case 3: // '\003'

+            case 10: // '\n'

+                IDOMNode docNode = (IDOMNode)node;

+                return new Region(docNode.getStartOffset(), docNode.getEndOffset() - docNode.getStartOffset());

+

+            case 1: // '\001'

+                IDOMElement element = (IDOMElement)node;

+                int endOffset;

+                if(element.hasEndTag() && element.isClosed())

+                    endOffset = element.getStartEndOffset();

+                else

+                    endOffset = element.getEndOffset();

+                return new Region(element.getStartOffset(), endOffset - element.getStartOffset());

+

+            case 2: // '\002'

+                IDOMAttr att = (IDOMAttr)node;

+                int regOffset = att.getValueRegionStartOffset();

+                int regLength = att.getValueRegionText().length();

+                String attValue = att.getValueRegionText();

+                if(StringUtils.isQuoted(attValue))

+                {

+                    regOffset++;

+                    regLength -= 2;

+                }

+                return new Region(regOffset, regLength);

+            }

+        return null;

+    }

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/XMLReferencesHyperlinkDetector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/XMLReferencesHyperlinkDetector.java
new file mode 100644
index 0000000..2a2fcd0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/hyperlink/XMLReferencesHyperlinkDetector.java
@@ -0,0 +1,127 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.hyperlink;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.ITextViewer;

+import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+import org.w3c.dom.Text;

+

+public class XMLReferencesHyperlinkDetector extends AbstractHyperlinkDetector {

+

+	public static final IHyperlink[] EMPTY_HYPERLINK = new IHyperlink[0];

+

+	public IHyperlink[] detectHyperlinks(ITextViewer textViewer,

+			IRegion region, boolean canShowMultipleHyperlinks) {

+		if (region == null || textViewer == null)

+			return EMPTY_HYPERLINK;

+		IDocument document = textViewer.getDocument();

+		// Get the selected Node.

+		Node currentNode = DOMUtils.getNodeByOffset(document,

+				region.getOffset());

+		if (currentNode == null) {

+			return EMPTY_HYPERLINK;

+		}

+		int nodeType = currentNode.getNodeType();

+		switch (nodeType) {

+		case Node.ELEMENT_NODE:

+			// Attribute node from element is selected

+			return detectHyperlinks((Element) currentNode, textViewer, region,

+					canShowMultipleHyperlinks);

+		case Node.TEXT_NODE:

+			// Text node is selected

+			return detectHyperlinks((Text) currentNode, textViewer, region,

+					canShowMultipleHyperlinks);

+		}

+		return EMPTY_HYPERLINK;

+	}

+

+	private IHyperlink[] detectHyperlinks(Element element,

+			ITextViewer textViewer, IRegion region,

+			boolean canShowMultipleHyperlinks) {

+		// Get selected attribute

+		IDOMAttr attr = DOMUtils.getAttrByOffset(element, region.getOffset());

+		if (attr == null) {

+			return EMPTY_HYPERLINK;

+		}

+		return detectHyperlinks(attr, textViewer, region,

+				canShowMultipleHyperlinks);

+	}

+

+	private IHyperlink[] detectHyperlinks(Text text, ITextViewer textViewer,

+			IRegion region, boolean canShowMultipleHyperlinks) {

+		return detectHyperlinks((IDOMNode) text, textViewer, region,

+				canShowMultipleHyperlinks);

+	}

+

+	private IHyperlink[] detectHyperlinks(IDOMNode selectedNode,

+			ITextViewer textViewer, IRegion region,

+			boolean canShowMultipleHyperlinks) {

+		// Get XML reference for the selected attribute

+		IXMLReference reference = XMLReferencesUtil.getXMLReference(

+				selectedNode, selectedNode.getModel()

+						.getContentTypeIdentifier());

+		if (reference == null) {

+			return EMPTY_HYPERLINK;

+		}

+

+		IFile file = DOMUtils.getFile(selectedNode);

+		IRegion hyperlinkRegion = HyperlinkUtils

+				.getHyperlinkRegion(selectedNode);

+		int offset = region.getOffset() - hyperlinkRegion.getOffset();

+		List<IHyperlink> hyperLinks = new ArrayList<IHyperlink>();

+		ITextEditor textEditor = (ITextEditor) getAdapter(ITextEditor.class);

+

+		if (reference.isExpression()) {

+			IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;

+			IXMLSearcher searcher = expression.getSearcher();

+			if (searcher != null) {

+				searcher.searchForHyperlink(selectedNode, offset,

+						DOMUtils.getNodeValue(selectedNode), -1, -1, file,

+						expression, hyperlinkRegion, hyperLinks, textEditor);

+			}

+		} else {

+

+			Collection<IXMLReferenceTo> toPath = reference.getTo();

+			for (IXMLReferenceTo referenceTo : toPath) {

+				IXMLSearcher searcher = referenceTo.getSearcher();

+				if (searcher != null) {

+					searcher.searchForHyperlink(selectedNode, offset,

+							DOMUtils.getNodeValue(selectedNode), -1, -1, file,

+							referenceTo, hyperlinkRegion, hyperLinks,

+							textEditor);

+				}

+			}

+		}

+		if (hyperLinks.size() == 0) {

+			return EMPTY_HYPERLINK;

+		}

+		return hyperLinks.toArray(new IHyperlink[hyperLinks.size()]);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/ImageResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/ImageResource.java
new file mode 100644
index 0000000..ecea1ef
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/ImageResource.java
@@ -0,0 +1,153 @@
+/*******************************************************************************

+ * Copyright (c) 2003, 2011 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

+ *     Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search

+ *     

+ *     Code comes from org.eclipse.jst.server.ui.internal.ImageResource     

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal;

+

+import java.net.URL;

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.jface.resource.ImageRegistry;

+import org.eclipse.swt.graphics.Image;

+

+/**

+ * Utility class to handle image resources.

+ */

+public class ImageResource {

+	// the image registry

+	private static ImageRegistry imageRegistry;

+

+	// map of image descriptors since these

+	// will be lost by the image registry

+	private static Map<String, ImageDescriptor> imageDescriptors;

+

+	// base urls for images

+	private static URL ICON_BASE_URL;

+

+	private static final String URL_OBJ = "obj16/";

+

+	// General Object Images

+	public static final String IMG_PROPERTY_OBJ = "property_obj";

+

+	static {

+		try {

+			String pathSuffix = "icons/";

+			ICON_BASE_URL = XMLSearchEditorPlugin.getDefault().getBundle()

+					.getEntry(pathSuffix);

+		} catch (Exception e) {

+			Trace.trace(Trace.SEVERE, "Images error", e);

+		}

+	}

+

+	/**

+	 * Cannot construct an ImageResource. Use static methods only.

+	 */

+	private ImageResource() {

+		// do nothing

+	}

+

+	/**

+	 * Dispose of element images that were created.

+	 */

+	protected static void dispose() {

+		// do nothing

+	}

+

+	/**

+	 * Return the image with the given key.

+	 * 

+	 * @param key

+	 *            java.lang.String

+	 * @return org.eclipse.swt.graphics.Image

+	 */

+	public static Image getImage(String key) {

+		return getImage(key, null);

+	}

+

+	/**

+	 * Return the image with the given key.

+	 * 

+	 * @param key

+	 *            java.lang.String

+	 * @return org.eclipse.swt.graphics.Image

+	 */

+	public static Image getImage(String key, String keyIfImageNull) {

+		if (imageRegistry == null)

+			initializeImageRegistry();

+		Image image = imageRegistry.get(key);

+		if (image == null) {

+			if (keyIfImageNull != null) {

+				return getImage(keyIfImageNull, null);

+			}

+			imageRegistry.put(key, ImageDescriptor.getMissingImageDescriptor());

+			image = imageRegistry.get(key);

+		}

+		return image;

+	}

+

+	/**

+	 * Return the image descriptor with the given key.

+	 * 

+	 * @param key

+	 *            java.lang.String

+	 * @return org.eclipse.jface.resource.ImageDescriptor

+	 */

+	public static ImageDescriptor getImageDescriptor(String key) {

+		if (imageRegistry == null)

+			initializeImageRegistry();

+		ImageDescriptor id = imageDescriptors.get(key);

+		if (id != null)

+			return id;

+

+		return ImageDescriptor.getMissingImageDescriptor();

+	}

+

+	/**

+	 * Initialize the image resources.

+	 */

+	protected static void initializeImageRegistry() {

+		imageRegistry = new ImageRegistry();

+		imageDescriptors = new HashMap<String, ImageDescriptor>();

+

+		// load general object images

+		registerImage(IMG_PROPERTY_OBJ, URL_OBJ + IMG_PROPERTY_OBJ + ".gif");

+

+		// PlatformUI

+		// .getWorkbench()

+		// .getProgressService()

+		// .registerIconForFamily(getImageDescriptor(IMG_SERVER),

+		// GeneratorUtil.SERVER_JOB_FAMILY);

+	}

+

+	/**

+	 * Register an image with the registry.

+	 * 

+	 * @param key

+	 *            java.lang.String

+	 * @param partialURL

+	 *            java.lang.String

+	 */

+	private static void registerImage(String key, String partialURL) {

+		try {

+			ImageDescriptor id = ImageDescriptor.createFromURL(new URL(

+					ICON_BASE_URL, partialURL));

+			imageRegistry.put(key, id);

+			imageDescriptors.put(key, id);

+		} catch (Exception e) {

+			Trace.trace(Trace.SEVERE, "Error registering image " + key

+					+ " from " + partialURL, e);

+		}

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.java
new file mode 100644
index 0000000..b78c935
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.java
@@ -0,0 +1,59 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal;

+

+import org.eclipse.osgi.util.NLS;

+

+/**

+ * Messages for XML Search Editor.

+ * 

+ */

+public class Messages extends NLS {

+

+	// ReferencesInContainerHandler_

+	public static String ReferencesInContainerHandler_operationUnavailable_title;

+	public static String ReferencesInContainerHandler_operationUnavailable_textEditorUnavailable;

+	public static String ReferencesInContainerHandler_operationUnavailable_fileUnavailable;

+	public static String ReferencesInContainerHandler_operationUnavailable_domNodeUnavailable;

+	public static String ReferencesInContainerHandler_operationUnavailable_noReferencesDefined;

+

+	// Handler search error

+	public static String ExceptionDialog_seeErrorLogMessage;

+

+	public static String Validation_ClassNotFounded;

+	public static String Validation_FileNotFounded;

+	public static String Validation_ElementNotFounded;

+	public static String Validation_ElementNonUnique;

+

+	// JDT search particpant

+	public static String ClassSearchParticipant_taskMessage;

+

+	public static String Search_Error_search_notsuccessful_title;

+	public static String Search_Error_search_notsuccessful_message;

+

+	// XML references preferences

+	public static String XMLSourcePreferencePage_0;

+	public static String Sample_XML_doc;

+	public static String Referenced_Attribute_Values_UI_;

+	public static String Referenced_Content_UI_;

+	public static String XMLReferencesSyntaxColoringPage_0;

+

+	// XML references index

+	public static String XMLReferencesIndexManager_0;

+	public static String XMLReferencesIndexManager_2;

+

+	private static final String BUNDLE_NAME = Messages.class.getName();

+

+	static {

+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.properties b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.properties
new file mode 100644
index 0000000..b6b39e5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Messages.properties
@@ -0,0 +1,40 @@
+###############################################################################

+# Copyright (c) 2011 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+Validation_FileNotFounded=File "{0}" not found.

+Validation_ClassNotFounded=Class "{0}" not found.

+Validation_ElementNotFounded=Element "{0}" not found.

+Validation_ElementNonUnique=Element "{0}" is not unique. It exists "{1}" elements with this id.

+

+ClassSearchParticipant_taskMessage=ClassSearchParticipant_taskMessage=Searching for types and packages in XML references to Java

+

+# ReferencesInContainerHandler

+ReferencesInContainerHandler_operationUnavailable_title= Operation Unavailable

+ReferencesInContainerHandler_operationUnavailable_textEditorUnavailable=text editor is unavailable.

+ReferencesInContainerHandler_operationUnavailable_fileUnavailable=Cannot get file.

+ReferencesInContainerHandler_operationUnavailable_domNodeUnavailable=Cannot get selected DOM node.

+ReferencesInContainerHandler_operationUnavailable_noReferencesDefined=The operation is unavailable on the current selection. Please select a DOM node which defined a XML reference.

+

+# Error

+ExceptionDialog_seeErrorLogMessage= See error log for more details.

+

+Search_Error_search_notsuccessful_message=The search operation has reported problems

+Search_Error_search_notsuccessful_title=Search

+

+# XML references preferences

+XMLSourcePreferencePage_0=XML references editor

+Sample_XML_doc=<?xml version=\"1.0\"?>\n<element simple-attr="Simple attribute" >\n</element>\n<element ref-attr="Referenced attribute" >\n</element>\n<element>Simple Text</element>\n<ref-element>Referenced Text</ref-element>

+Referenced_Attribute_Values_UI_=Referenced Attribute Values

+Referenced_Content_UI_=Referenced Content

+XMLReferencesSyntaxColoringPage_0=Enable XML referenced syntax coloring.

+

+# XML references index

+XMLReferencesIndexManager_0=Updating XML references Index

+XMLReferencesIndexManager_2=XML references Indexer indexing {0} files
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Trace.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Trace.java
new file mode 100644
index 0000000..3b69888
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/Trace.java
@@ -0,0 +1,99 @@
+/*******************************************************************************

+ * Copyright (c) 2003, 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.search.editor.internal;

+

+import java.text.SimpleDateFormat;

+import java.util.Date;

+import java.util.HashSet;

+import java.util.Set;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+

+/**

+ * Helper class to route trace output.

+ */

+public class Trace {

+	public static final byte CONFIG = 0;

+	public static final byte INFO = 1;

+	public static final byte WARNING = 2;

+	public static final byte SEVERE = 3;

+	public static final byte FINEST = 4;

+	public static final byte FINER = 5;

+	public static final byte PERFORMANCE = 6;

+	public static final byte EXTENSION_POINT = 7;

+

+	private static final String[] levelNames = new String[] { "CONFIG ",

+			"INFO   ", "WARNING", "SEVERE ", "FINER  ", "FINEST ", "PERF   ",

+			"EXTENSION" };

+

+	private static final SimpleDateFormat sdf = new SimpleDateFormat(

+			"dd/MM/yy HH:mm.ss.SSS");

+

+	private static Set<String> logged = new HashSet<String>();

+

+	/**

+	 * Trace constructor comment.

+	 */

+	private Trace() {

+		super();

+	}

+

+	/**

+	 * Trace the given text.

+	 * 

+	 * @param level

+	 *            a trace level

+	 * @param s

+	 *            a message

+	 */

+	public static void trace(byte level, String s) {

+		trace(level, s, null);

+	}

+

+	/**

+	 * Trace the given message and exception.

+	 * 

+	 * @param level

+	 *            a trace level

+	 * @param s

+	 *            a message

+	 * @param t

+	 *            a throwable

+	 */

+	public static void trace(byte level, String s, Throwable t) {

+		if (s == null)

+			return;

+

+		if (level == SEVERE) {

+			if (!logged.contains(s)) {

+				XMLSearchEditorPlugin.getDefault().getLog().log(

+						new Status(IStatus.ERROR,

+								XMLSearchEditorPlugin.PLUGIN_ID, s, t));

+				logged.add(s);

+			}

+		}

+

+		if (!XMLSearchEditorPlugin.getDefault().isDebugging())

+			return;

+

+		StringBuilder sb = new StringBuilder(XMLSearchEditorPlugin.PLUGIN_ID);

+		sb.append(" ");

+		sb.append(levelNames[level]);

+		sb.append(" ");

+		sb.append(sdf.format(new Date()));

+		sb.append(" ");

+		sb.append(s);

+		System.out.println(sb.toString());

+		if (t != null)

+			t.printStackTrace();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/XMLSearchEditorPlugin.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/XMLSearchEditorPlugin.java
new file mode 100644
index 0000000..57f5a67
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/XMLSearchEditorPlugin.java
@@ -0,0 +1,133 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal;

+

+import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.IWorkbenchPage;

+import org.eclipse.ui.IWorkbenchWindow;

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.eclipse.wst.xml.search.core.storage.StructuredStorageModelManager;

+import org.eclipse.wst.xml.search.editor.internal.contentassist.ContentAssistsManager;

+import org.eclipse.wst.xml.search.editor.internal.indexing.XMLReferencesIndexManager;

+import org.eclipse.wst.xml.search.editor.internal.jdt.JDTStorageLocationProvider;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;

+import org.eclipse.wst.xml.search.editor.internal.references.filters.XMLReferenceFiltersManager;

+import org.eclipse.wst.xml.search.editor.internal.references.validators.XMLReferenceValidatorsManager;

+import org.eclipse.wst.xml.search.editor.internal.reporter.XMLSearchReporterManager;

+import org.eclipse.wst.xml.search.editor.internal.searchers.expressions.XMLExpressionParserManager;

+import org.eclipse.wst.xml.search.editor.internal.searchers.java.JavaQuerySpecificationrManager;

+import org.eclipse.wst.xml.search.editor.internal.searchers.javamethod.JavaMethodQuerySpecificationrManager;

+import org.eclipse.wst.xml.search.editor.java.JavaReferencesManager;

+import org.eclipse.wst.xml.search.editor.java.JavaReferencesMatchersManager;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class XMLSearchEditorPlugin extends AbstractUIPlugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.editor";

+

+	// The shared instance

+	private static XMLSearchEditorPlugin plugin;

+

+	private JavaElementImageProvider javaElementLabelProvider;

+

+	/**

+	 * The constructor

+	 */

+	public XMLSearchEditorPlugin() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;

+		XMLSearchReporterManager.getDefault().initialize();

+		XMLReferenceFiltersManager.getDefault().initialize();

+		XMLReferenceValidatorsManager.getDefault().initialize();

+		XMLReferencesManager.getInstance().initialize();

+		JavaReferencesMatchersManager.getInstance().initialize();

+		JavaReferencesManager.getInstance().initialize();

+		ContentAssistsManager.getDefault().initialize();

+		JavaQuerySpecificationrManager.getDefault().initialize();

+		JavaMethodQuerySpecificationrManager.getDefault().initialize();

+		XMLReferencesIndexManager.getDefault().initialize();

+		javaElementLabelProvider = new JavaElementImageProvider();

+		StructuredStorageModelManager.getModelManager()

+				.setStorageLocationProvider(new JDTStorageLocationProvider());

+		XMLExpressionParserManager.getDefault().initialize();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void stop(BundleContext context) throws Exception {

+		plugin = null;

+		super.stop(context);

+		XMLSearchReporterManager.getDefault().destroy();

+		XMLReferenceFiltersManager.getDefault().destroy();

+		XMLReferenceValidatorsManager.getDefault().destroy();

+		XMLReferencesManager.getInstance().destroy();

+		JavaReferencesMatchersManager.getInstance().destroy();

+		JavaReferencesManager.getInstance().destroy();

+		ContentAssistsManager.getDefault().destroy();

+		JavaQuerySpecificationrManager.getDefault().destroy();

+		JavaMethodQuerySpecificationrManager.getDefault().destroy();

+		XMLReferencesIndexManager.getDefault().destroy();

+		XMLExpressionParserManager.getDefault().destroy();

+		javaElementLabelProvider = null;

+	}

+

+	/**

+	 * Returns the shared instance

+	 * 

+	 * @return the shared instance

+	 */

+	public static XMLSearchEditorPlugin getDefault() {

+		return plugin;

+	}

+

+	public static IWorkbenchWindow getActiveWorkbenchWindow() {

+		return getDefault().getWorkbench().getActiveWorkbenchWindow();

+	}

+

+	public static Shell getActiveWorkbenchShell() {

+		IWorkbenchWindow window = getActiveWorkbenchWindow();

+		if (window != null) {

+			return window.getShell();

+		}

+		return null;

+	}

+

+	/**

+	 * @return Returns the active workbench window's currrent page.

+	 */

+	public static IWorkbenchPage getActivePage() {

+		return getActiveWorkbenchWindow().getActivePage();

+	}

+

+	public JavaElementImageProvider getJavaElementLabelProvider() {

+		return javaElementLabelProvider;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationProblemRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationProblemRequestor.java
new file mode 100644
index 0000000..3f1951b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationProblemRequestor.java
@@ -0,0 +1,73 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.contentassist;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.jdt.core.IProblemRequestor;

+import org.eclipse.jdt.core.compiler.IProblem;

+

+public class CompilationProblemRequestor implements IProblemRequestor {

+

+	private boolean fIsActive;

+	private boolean fIsRunning;

+	private List<IProblem> fCollectedProblems;

+

+	CompilationProblemRequestor() {

+		fIsActive = false;

+		fIsRunning = false;

+	}

+

+	public void beginReporting() {

+		fIsRunning = true;

+		fCollectedProblems = new ArrayList<IProblem>();

+	}

+

+	public void acceptProblem(IProblem problem) {

+		if (isActive())

+			fCollectedProblems.add(problem);

+	}

+

+	public void endReporting() {

+		fIsRunning = false;

+	}

+

+	public boolean isActive() {

+		return fIsActive && fCollectedProblems != null;

+	}

+

+	public void setIsActive(boolean isActive) {

+		if (fIsActive != isActive) {

+			fIsActive = isActive;

+			if (fIsActive)

+				startCollectingProblems();

+			else

+				stopCollectingProblems();

+		}

+	}

+

+	private void startCollectingProblems() {

+		fCollectedProblems = new ArrayList();

+	}

+

+	private void stopCollectingProblems() {

+	}

+

+	public List getCollectedProblems() {

+		return fCollectedProblems;

+	}

+

+	public boolean isRunning() {

+		return fIsRunning;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationUnitHelper.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationUnitHelper.java
new file mode 100644
index 0000000..789e73d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/CompilationUnitHelper.java
@@ -0,0 +1,54 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.contentassist;

+

+import org.eclipse.jdt.core.WorkingCopyOwner;

+

+class CompilationUnitHelper {

+

+	private CompilationProblemRequestor fProblemRequestor;

+	private WorkingCopyOwner fWorkingCopyOwner;

+	private static CompilationUnitHelper instance;

+

+	private CompilationUnitHelper() {

+		fProblemRequestor = null;

+		fWorkingCopyOwner = null;

+	}

+

+	public static final synchronized CompilationUnitHelper getInstance() {

+		if (instance == null)

+			instance = new CompilationUnitHelper();

+		return instance;

+	}

+

+	public CompilationProblemRequestor getProblemRequestor() {

+		if (fProblemRequestor == null)

+			fProblemRequestor = new CompilationProblemRequestor();

+		return fProblemRequestor;

+	}

+

+	public WorkingCopyOwner getWorkingCopyOwner() {

+		if (fWorkingCopyOwner == null)

+			fWorkingCopyOwner = new WorkingCopyOwner() {

+

+				public String toString() {

+					return "WTP/XML Search Working copy owner";

+				}

+

+				final CompilationUnitHelper this$0;

+				{

+					this$0 = CompilationUnitHelper.this;

+				}

+			};

+		return fWorkingCopyOwner;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/ContentAssistsManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/ContentAssistsManager.java
new file mode 100644
index 0000000..2b52063
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/ContentAssistsManager.java
@@ -0,0 +1,118 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.contentassist;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+

+public class ContentAssistsManager extends AbstractRegistryManager {

+

+	private static final String CLASS_ATTR = "class";

+	private static final String ID_ATTR = "id";

+	private static final String ADDITIONAL_PROPOSAL_INFO_PROVIDER_ELT = "additionalProposalInfoProvider";

+	public static final ContentAssistsManager INSTANCE = new ContentAssistsManager();

+	private static final String CONTENT_ASSISTS_EXTENSION_POINT = "contentAssists";

+

+	private Map<String, IContentAssistAdditionalProposalInfoProvider> providersById = null;

+

+	public static ContentAssistsManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (providersById == null) {// not loaded yet

+			return;

+		}

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addContentAssists(providersById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	private synchronized void addContentAssists(

+			Map<String, IContentAssistAdditionalProposalInfoProvider> providersById,

+			IConfigurationElement[] cf) {

+		IXMLReference reference = null;

+		String id = null;

+		for (IConfigurationElement ce : cf) {

+			// loop for to get additionalProposalInfoProvider declaration

+			if (ADDITIONAL_PROPOSAL_INFO_PROVIDER_ELT.equals(ce.getName())) {

+				id = ce.getAttribute(ID_ATTR);

+				try {

+					IContentAssistAdditionalProposalInfoProvider provider = (IContentAssistAdditionalProposalInfoProvider) ce

+							.createExecutableExtension(CLASS_ATTR);

+					providersById.put(id, provider);

+				} catch (Throwable t) {

+					Trace.trace(Trace.SEVERE,

+							"  Could not load contentAssists for id: " + id, t);

+				}

+			}

+		}

+	}

+

+	public IContentAssistAdditionalProposalInfoProvider getProvider(

+			String referenceId) {

+		if (StringUtils.isEmpty(referenceId)) {

+			return null;

+		}

+		if (providersById == null) {

+			loadContentAssists();

+		}

+

+		return providersById.get(referenceId);

+	}

+

+	private synchronized void loadContentAssists() {

+		if (providersById != null) {

+			return;

+		}

+		Map<String, IContentAssistAdditionalProposalInfoProvider> providersById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchEditorPlugin.PLUGIN_ID,

+					CONTENT_ASSISTS_EXTENSION_POINT);

+			providersById = new HashMap<String, IContentAssistAdditionalProposalInfoProvider>(

+					cf.length);

+			addContentAssists(providersById, cf);

+		} else {

+			providersById = new HashMap<String, IContentAssistAdditionalProposalInfoProvider>();

+		}

+		this.providersById = providersById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return CONTENT_ASSISTS_EXTENSION_POINT;

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchEditorPlugin.PLUGIN_ID;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionProposalCollector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionProposalCollector.java
new file mode 100644
index 0000000..4cdb582
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionProposalCollector.java
@@ -0,0 +1,52 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.contentassist;

+

+import org.eclipse.jdt.core.CompletionProposal;

+import org.eclipse.jdt.core.Flags;

+import org.eclipse.jdt.core.ICompilationUnit;

+import org.eclipse.jdt.ui.text.java.CompletionProposalCollector;

+

+public class JavaCompletionProposalCollector extends

+		CompletionProposalCollector {

+

+	public JavaCompletionProposalCollector(ICompilationUnit cu) {

+		super(cu);

+

+	}

+

+	public void accept(CompletionProposal proposal) {

+		boolean accepted = false;

+

+		int flags = JavaCompletionUtils.FLAG_PACKAGE | JavaCompletionUtils.FLAG_CLASS;

+		if (CompletionProposal.TYPE_REF == proposal.getKind()) {

+			if ((flags & JavaCompletionUtils.FLAG_CLASS) != 0

+					&& !Flags.isInterface(proposal.getFlags())) {

+				super.accept(proposal);

+				accepted = true;

+			}

+			if (!accepted

+					&& (flags & JavaCompletionUtils.FLAG_INTERFACE) != 0

+					&& Flags.isInterface(proposal.getFlags())) {

+				super.accept(proposal);

+				accepted = true;

+			}

+		}

+

+		if (CompletionProposal.PACKAGE_REF == proposal.getKind()) {

+			if (!accepted

+					&& (flags & JavaCompletionUtils.FLAG_PACKAGE) != 0) {

+				super.accept(proposal);

+			}

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionUtils.java
new file mode 100644
index 0000000..54c9c9e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/JavaCompletionUtils.java
@@ -0,0 +1,305 @@
+/*******************************************************************************

+ * Copyright (c) 2005, 2007 Spring IDE Developers 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *         

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.contentassist;

+

+import java.util.Arrays;

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.jdt.core.Flags;

+import org.eclipse.jdt.core.IBuffer;

+import org.eclipse.jdt.core.ICompilationUnit;

+import org.eclipse.jdt.core.IJavaProject;

+import org.eclipse.jdt.core.IMember;

+import org.eclipse.jdt.core.IPackageFragment;

+import org.eclipse.jdt.core.IPackageFragmentRoot;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.ITypeHierarchy;

+import org.eclipse.jdt.core.JavaCore;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;

+import org.eclipse.jdt.internal.corext.util.TypeFilter;

+import org.eclipse.jdt.internal.ui.JavaPluginImages;

+import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal;

+import org.eclipse.jdt.internal.ui.text.java.LazyJavaTypeCompletionProposal;

+import org.eclipse.jdt.internal.ui.text.java.ProposalInfo;

+import org.eclipse.jdt.ui.JavaElementLabelProvider;

+import org.eclipse.jdt.ui.text.java.CompletionProposalComparator;

+import org.eclipse.jface.text.contentassist.ICompletionProposal;

+import org.eclipse.jface.viewers.ILabelProvider;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.internal.jdt.SuperTypeHierarchyCache;

+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;

+import org.eclipse.wst.xml.search.editor.util.JdtUtils;

+

+public class JavaCompletionUtils {

+

+	private static final CompletionProposalComparator COMPARATOR = new CompletionProposalComparator();

+	private static ILabelProvider JAVA_LABEL_PROVIDER;

+	public static final int FLAG_INTERFACE = 4;

+	public static final int FLAG_CLASS = 8;

+	public static final int FLAG_PACKAGE = 16;

+

+	static {

+		JAVA_LABEL_PROVIDER = new JavaElementLabelProvider(

+				JavaElementLabelProvider.SHOW_DEFAULT | 2048);

+	}

+

+	public static void addClassValueProposals(String prefix, IFile file,

+			IContentAssistProposalRecorder recorder) {

+		if (prefix == null || prefix.length() == 0)

+			return;

+

+		try {

+			ICompilationUnit unit = createSourceCompilationUnit(file, prefix);

+			char enclosingChar = prefix.lastIndexOf('$') <= 0 ? '.' : '$';

+			prefix = prefix.replace('$', '.');

+			if (prefix.lastIndexOf('.') > 0) {

+				String rootClass = prefix.substring(0, prefix.lastIndexOf('.'));

+				IType type = JdtUtils.getJavaType(file.getProject(), rootClass);

+				if (type != null) {

+					IType aitype[];

+					int j = (aitype = type.getTypes()).length;

+					for (int i = 0; i < j; i++) {

+						IType innerType = aitype[i];

+						if (Flags.isPrivate(innerType.getFlags())

+								&& innerType.getFullyQualifiedName('.')

+										.startsWith(prefix))

+							recorder

+									.recordProposal(

+											JAVA_LABEL_PROVIDER

+													.getImage(innerType),

+											10,

+											JAVA_LABEL_PROVIDER

+													.getText(innerType),

+											innerType

+													.getFullyQualifiedName(enclosingChar),

+											innerType);

+					}

+

+				}

+			}

+			String sourceStart = (new StringBuilder(

+					"public class _xxx {\n    public void main(String[] args) {\n        "))

+					.append(prefix).toString();

+			String packageName = null;

+			int dot = prefix.lastIndexOf('.');

+			if (dot > -1) {

+				packageName = prefix.substring(0, dot);

+				sourceStart = (new StringBuilder("package ")).append(

+						packageName).append(";\n").append(sourceStart)

+						.toString();

+			}

+			String source = (new StringBuilder(String.valueOf(sourceStart)))

+					.append("\n    }\n}").toString();

+			setContents(unit, source);

+			JavaCompletionProposalCollector collector = new JavaCompletionProposalCollector(

+					unit);

+			unit.codeComplete(sourceStart.length(), collector,

+					DefaultWorkingCopyOwner.PRIMARY);

+			org.eclipse.jdt.ui.text.java.IJavaCompletionProposal props[] = collector

+					.getJavaCompletionProposals();

+			ICompletionProposal proposals[] = order(props);

+			ICompletionProposal aicompletionproposal[];

+			int l = (aicompletionproposal = proposals).length;

+			for (int k = 0; k < l; k++) {

+				ICompletionProposal comProposal = aicompletionproposal[k];

+				processJavaCompletionProposal(recorder, comProposal,

+						packageName, enclosingChar);

+			}

+

+		} catch (JavaModelException e) {

+			e.printStackTrace();

+		}

+	}

+

+	private static ICompilationUnit createSourceCompilationUnit(IFile file,

+			String prefix) throws JavaModelException {

+		IProgressMonitor progressMonitor = EditorUtils.getProgressMonitor();

+		IJavaProject project = JavaCore.create(file.getProject());

+		IPackageFragment root = getPackageFragment(project, prefix);

+		ICompilationUnit unit = root.getCompilationUnit("_xxx.java")

+				.getWorkingCopy(

+						CompilationUnitHelper.getInstance()

+								.getWorkingCopyOwner(),

+						CompilationUnitHelper.getInstance()

+								.getProblemRequestor(), progressMonitor);

+		progressMonitor.done();

+		return unit;

+	}

+

+	private static IPackageFragment getPackageFragment(IJavaProject project,

+			String prefix) throws JavaModelException {

+		int dot = prefix.lastIndexOf('.');

+		if (dot > -1) {

+			String packageName = prefix.substring(0, dot);

+			IPackageFragmentRoot aipackagefragmentroot1[];

+			int l = (aipackagefragmentroot1 = project.getPackageFragmentRoots()).length;

+			for (int j = 0; j < l; j++) {

+				IPackageFragmentRoot root = aipackagefragmentroot1[j];

+				IPackageFragment p = root.getPackageFragment(packageName);

+				if (p != null && p.exists())

+					return p;

+			}

+

+			IPackageFragment packages[] = project.getPackageFragments();

+			IPackageFragment aipackagefragment[];

+			int j1 = (aipackagefragment = packages).length;

+			for (int i1 = 0; i1 < j1; i1++) {

+				IPackageFragment p = aipackagefragment[i1];

+				if (p.getElementName().equals(packageName))

+					return p;

+			}

+

+		} else {

+			IPackageFragmentRoot aipackagefragmentroot[];

+			int k = (aipackagefragmentroot = project

+					.getAllPackageFragmentRoots()).length;

+			for (int i = 0; i < k; i++) {

+				IPackageFragmentRoot p = aipackagefragmentroot[i];

+				if (p.getKind() == 1)

+					return p.getPackageFragment("");

+			}

+

+		}

+		return project.getPackageFragments()[0];

+	}

+

+	private static ICompletionProposal[] order(ICompletionProposal proposals[]) {

+		Arrays.sort(proposals, COMPARATOR);

+		return proposals;

+	}

+

+	private static void processJavaCompletionProposal(

+			IContentAssistProposalRecorder recorder,

+			ICompletionProposal comProposal, String packageName,

+			char enclosingChar) {

+		if (comProposal instanceof JavaCompletionProposal) {

+			JavaCompletionProposal prop = (JavaCompletionProposal) comProposal;

+			recordProposal(recorder, prop.getImage(), prop.getRelevance(), prop

+					.getDisplayString(), prop.getReplacementString(), prop

+					.getJavaElement());

+		} else if (comProposal instanceof LazyJavaTypeCompletionProposal) {

+			LazyJavaTypeCompletionProposal prop = (LazyJavaTypeCompletionProposal) comProposal;

+			if (prop.getQualifiedTypeName().equals(

+					(new StringBuilder(String.valueOf(packageName)))

+							.append(".").append("_xxx").toString())

+					|| prop.getQualifiedTypeName().equals("_xxx"))

+				return;

+			if (prop.getJavaElement() instanceof IType) {

+				if (TypeFilter.isFiltered((IType) prop.getJavaElement()))

+					return;

+				String replacementString = ((IType) prop.getJavaElement())

+						.getFullyQualifiedName(enclosingChar);

+				recordProposal(recorder, prop.getImage(), prop.getRelevance(),

+						prop.getDisplayString(), replacementString, prop

+								.getJavaElement());

+			}

+		}

+	}

+

+	private static void recordProposal(IContentAssistProposalRecorder recorder,

+			Image image, int relevance, String displayText, String replaceText,

+			Object proposedObject) {

+		String s = null;

+		if (proposedObject instanceof IMember) {

+			s = new ProposalInfo((IMember) proposedObject).getInfo(EditorUtils.getProgressMonitor());

+		}

+		recorder.recordProposal(image, relevance, displayText, replaceText, s);

+	}

+

+	private static void setContents(ICompilationUnit cu, String source) {

+		if (cu == null)

+			return;

+		synchronized (cu) {

+			IBuffer buffer;

+			try {

+				buffer = cu.getBuffer();

+			} catch (JavaModelException e) {

+				e.printStackTrace();

+				buffer = null;

+			}

+			if (buffer != null)

+				buffer.setContents(source);

+		}

+	}

+

+	public static void addTypeHierachyAttributeValueProposals(String prefix,

+			IFile file, IContentAssistProposalRecorder recorder, IType type,

+			int flags) {

+		// String prefix = context.getMatchString();

+		// if (prefix == null || prefix.length() == 0)

+		// return;

+		// IType type = JdtUtils.getJavaType(file.getProject(),

+		// typeName);

+		try {

+			if (type != null

+					&& file.getProject().hasNature(

+							"org.eclipse.jdt.core.javanature")

+					&& !TypeFilter.isFiltered(type)) {

+				ITypeHierarchy hierachy = SuperTypeHierarchyCache

+						.getTypeHierarchy(type, EditorUtils

+								.getProgressMonitor());

+				// type.newTypeHierarchy(JavaCore

+				// .create(file.getProject()),

+				// new NullProgressMonitor());

+				IType types[] = hierachy.getAllSubtypes(type);

+				Map sortMap = new HashMap();

+				IType aitype[];

+				int j = (aitype = types).length;

+				for (int i = 0; i < j; i++) {

+					IType foundType = aitype[i];

+					if ((foundType.getFullyQualifiedName().startsWith(prefix) || foundType

+							.getElementName().startsWith(prefix))

+							&& !sortMap.containsKey(foundType

+									.getFullyQualifiedName())

+							&& !Flags.isAbstract(foundType.getFlags())) {

+						boolean accepted = false;

+						if ((flags & 8) != 0

+								&& !Flags.isInterface(foundType.getFlags()))

+							accepted = true;

+						else if ((flags & 4) != 0

+								&& Flags.isInterface(foundType.getFlags()))

+							accepted = true;

+						if (accepted) {

+							recordProposal(recorder,

+											JavaPluginImages

+													.get("org.eclipse.jdt.ui.class_obj.gif"),

+											10,

+											(new StringBuilder(String

+													.valueOf(foundType

+															.getElementName())))

+													.append(" - ")

+													.append(

+															foundType

+																	.getPackageFragment()

+																	.getElementName())

+													.toString(), foundType

+													.getFullyQualifiedName(),

+											foundType);

+							sortMap.put(foundType.getFullyQualifiedName(),

+									foundType);

+						}

+					}

+				}

+

+			}

+		} catch (JavaModelException _ex) {

+		} catch (CoreException _ex) {

+		}

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistCalculator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistCalculator.java
new file mode 100644
index 0000000..e1cefcc
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistCalculator.java
@@ -0,0 +1,62 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.contentassist;

+

+import java.util.Collection;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistCalculator;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistContext;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+

+public class XMLReferencesContentAssistCalculator implements

+		IContentAssistCalculator {

+

+	private IXMLReference reference;

+	private IDOMNode selectedNode;

+

+	public XMLReferencesContentAssistCalculator(IXMLReference reference,

+			IDOMNode selectedNode) {

+		this.reference = reference;

+		this.selectedNode = selectedNode;

+	}

+

+	public void computeProposals(IContentAssistContext context,

+			IContentAssistProposalRecorder recorder) {

+		IFile file = context.getFile();

+		if (reference.isExpression()) {

+			IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;

+			IXMLSearcher searcher = expression.getSearcher();

+			if (searcher != null) {

+				searcher.searchForCompletion(selectedNode, context

+						.getMatchString(), null, null, file, expression,

+						recorder);

+			}

+

+		} else {

+			Collection<IXMLReferenceTo> toPath = reference.getTo();

+			for (IXMLReferenceTo referenceTo : toPath) {

+				IXMLSearcher searcher = referenceTo.getSearcher();

+				if (searcher != null) {

+					searcher.searchForCompletion(selectedNode, context

+							.getMatchString(), null, null, file, referenceTo,

+							recorder);

+				}

+			}

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistProcessor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistProcessor.java
new file mode 100644
index 0000000..a1c0d62
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/contentassist/XMLReferencesContentAssistProcessor.java
@@ -0,0 +1,100 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.contentassist;

+

+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.contentassist.XMLReferencesContentAssistUtils;

+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;

+import org.eclipse.wst.xml.ui.internal.contentassist.XMLContentAssistProcessor;

+

+public class XMLReferencesContentAssistProcessor extends

+		XMLContentAssistProcessor {

+

+	@Override

+	protected void addAttributeValueProposals(

+			ContentAssistRequest contentAssistRequest) {

+		int proposalCount = 0;

+		if (contentAssistRequest.getCompletionProposals() != null) {

+			proposalCount = contentAssistRequest.getCompletionProposals().length;

+		}

+		IDOMNode node = (IDOMNode) contentAssistRequest.getNode();

+		// XML reference

+		XMLReferencesContentAssistUtils

+				.addAttributeValueProposals(contentAssistRequest);

+

+		super.addAttributeValueProposals(contentAssistRequest);

+

+	}

+

+	@Override

+	protected ContentAssistRequest computeEndTagOpenProposals(

+			int documentPosition, String matchString,

+			ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {

+		ContentAssistRequest request = super.computeEndTagOpenProposals(

+				documentPosition, matchString, completionRegion, nodeAtOffset,

+				node);

+		doEntityProposalIfNeeded(request);

+		return request;

+	}

+

+	@Override

+	protected ContentAssistRequest computeContentProposals(

+			int documentPosition, String matchString,

+			ITextRegion completionRegion, IDOMNode nodeAtOffset, IDOMNode node) {

+		// TODO Auto-generated method stub

+		ContentAssistRequest request = super.computeContentProposals(

+				documentPosition, matchString, completionRegion, nodeAtOffset,

+				node);

+		doEntityProposalIfNeeded(request);

+		return request;

+	}

+

+	//

+	// @Override

+	// protected void addTagInsertionProposals(

+	// ContentAssistRequest contentAssistRequest, int childPosition) {

+	// doEntityProposalIfNeeded(contentAssistRequest);

+	// super.addTagInsertionProposals(contentAssistRequest, childPosition);

+	// }

+	//

+	// @Override

+	// protected void addEntityProposals(

+	// ContentAssistRequest contentAssistRequest, int documentPosition,

+	// ITextRegion completionRegion, IDOMNode treeNode) {

+	// CMElementDeclaration parentDecl =

+	// getCMElementDeclaration(contentAssistRequest

+	// .getParent());

+	// if (!((parentDecl != null) && (parentDecl.getContentType() ==

+	// CMElementDeclaration.PCDATA))) {

+	// doEntityProposalIfNeeded(contentAssistRequest);

+	// }

+	// super.addEntityProposals(contentAssistRequest, documentPosition,

+	// completionRegion, treeNode);

+	// }

+

+	private void doEntityProposalIfNeeded(

+			ContentAssistRequest contentAssistRequest) {

+

+		XMLReferencesContentAssistUtils.addEntityProposals(this,

+				contentAssistRequest);

+		// entityProposalsAlreadyDone = true;

+

+	}

+

+	// @Override

+	// protected void addPCDATAProposal(String nodeName,

+	// ContentAssistRequest contentAssistRequest) {

+	// // XML reference

+	// doEntityProposalIfNeeded(contentAssistRequest);

+	// super.addPCDATAProposal(nodeName, contentAssistRequest);

+	// }

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/handlers/ReferencesInContainerHandler.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/handlers/ReferencesInContainerHandler.java
new file mode 100644
index 0000000..ee99840
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/handlers/ReferencesInContainerHandler.java
@@ -0,0 +1,124 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.handlers;

+

+import org.eclipse.core.commands.AbstractHandler;

+import org.eclipse.core.commands.ExecutionEvent;

+import org.eclipse.core.commands.ExecutionException;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.jface.dialogs.MessageDialog;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;

+import org.eclipse.wst.xml.search.core.queryspecifications.XMLQuerySpecificationRegistry;

+import org.eclipse.wst.xml.search.editor.internal.Messages;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.internal.reporter.XMLSearchReporterManager;

+import org.eclipse.wst.xml.search.editor.internal.util.ExceptionHandler;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;

+import org.eclipse.wst.xml.search.editor.references.XMLReferencePathResult;

+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;

+import org.eclipse.wst.xml.search.editor.util.XMLQuerySpecificationUtil;

+import org.eclipse.wst.xml.search.ui.util.DOMUtils;

+import org.eclipse.wst.xml.search.ui.util.SearchUtil;

+

+/**

+ * 

+ * Handler launched with Ctrl+Shift+G to start search which retrieve referenced

+ * nodes of the selected node.

+ * 

+ */

+public class ReferencesInContainerHandler extends AbstractHandler {

+

+	public Object execute(ExecutionEvent event) throws ExecutionException {

+

+		// 1) Get text editor which has started the search.

+		ITextEditor textEditor = SearchUtil.getTextEditor(event);

+		if (textEditor == null) {

+			showOperationUnavailableDialog(

+					XMLSearchEditorPlugin.getActiveWorkbenchShell(),

+					Messages.ReferencesInContainerHandler_operationUnavailable_textEditorUnavailable);

+			return null;

+		}

+

+		// 2) Get file which has started the search.

+		Shell shell = textEditor.getSite().getShell();

+		IFile file = SearchUtil.getFile(textEditor);

+		if (file == null) {

+			showOperationUnavailableDialog(

+					XMLSearchEditorPlugin.getActiveWorkbenchShell(),

+					Messages.ReferencesInContainerHandler_operationUnavailable_fileUnavailable);

+			return null;

+		}

+

+		// 3) Get selected node which has started the search.

+		IDOMNode selectedNode = DOMUtils.getSelectedNode(textEditor);

+		if (selectedNode == null) {

+			showOperationUnavailableDialog(

+					XMLSearchEditorPlugin.getActiveWorkbenchShell(),

+					Messages.ReferencesInContainerHandler_operationUnavailable_domNodeUnavailable);

+			return null;

+		}

+

+		// 3) Get list of XML reference path to execute to retrieve referenced

+		// nodes of the selected node.

+		XMLReferencePathResult result = XMLReferencesUtil.getReferencePath(

+				selectedNode, file);

+		if (result == null) {

+			showOperationUnavailableDialog(

+					XMLSearchEditorPlugin.getActiveWorkbenchShell(),

+					Messages.ReferencesInContainerHandler_operationUnavailable_noReferencesDefined);

+			return null;

+		}

+

+		IXMLQuerySpecificationRegistry querySpecificationRegistry = new XMLQuerySpecificationRegistry(

+				file, selectedNode);

+		for (IXMLReferencePath referencePath : result) {

+			IXMLQuerySpecification querySpecification = XMLQuerySpecificationUtil

+					.getQuerySpecification(referencePath);

+			if (querySpecification != null) {

+				String query = referencePath.getQuery(selectedNode, null,

+						querySpecification.getEqualsStringQueryBuilder(),

+						result.isReversed());

+				if (query != null) {

+					querySpecificationRegistry.register(querySpecification,

+							query, null);

+				}

+			}

+		}

+

+		// will return true except for debugging purposes.

+		try {

+			SearchUtil.performNewSearch(shell, querySpecificationRegistry,

+					XMLSearchReporterManager.getDefault());

+		} catch (InterruptedException e) {

+			// cancelled

+

+		} catch (CoreException ex) {

+			ExceptionHandler.handle(ex, shell,

+					Messages.Search_Error_search_notsuccessful_title,

+					Messages.Search_Error_search_notsuccessful_message);

+		}

+

+		return null;

+	}

+

+	private void showOperationUnavailableDialog(Shell shell, String message) {

+		MessageDialog

+				.openInformation(

+						shell,

+						Messages.ReferencesInContainerHandler_operationUnavailable_title,

+						message);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/DOMNodeHyperlink.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/DOMNodeHyperlink.java
new file mode 100644
index 0000000..4beca37
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/DOMNodeHyperlink.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.hyperlink;

+

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;

+

+/**

+ * JFace {@link IHyperlink} implementation for DOM-SSE Node {@link IDOMNode}.

+ * 

+ */

+public class DOMNodeHyperlink implements IHyperlink, IRegion {

+

+	private int offset;

+	private int length;

+	private final IRegion region;

+	private final IDOMNode node;

+

+	public DOMNodeHyperlink(IRegion region, IDOMNode node, int startOffset,

+			int endOffset) {

+		this.region = region;

+		this.node = node;

+		this.offset = region.getOffset();

+		if (startOffset != -1) {

+			this.offset += startOffset;

+		}

+		this.length = region.getLength();

+		if (endOffset != -1) {

+			this.length = endOffset - startOffset;

+		}

+	}

+

+	public IRegion getHyperlinkRegion() {

+		return this;

+	}

+

+	public String getTypeLabel() {

+		return null;

+	}

+

+	public String getHyperlinkText() {

+		return (new StringBuilder("Open '")).append(node.getLocalName())

+				.append("' - ").append(node.getModel().getBaseLocation())

+				.toString();

+	}

+

+	public void open() {

+		EditorUtils.openInEditor(node);

+	}

+

+	public int getLength() {

+		return length;

+	}

+

+	public int getOffset() {

+		return offset;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/JavaElementHyperlink.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/JavaElementHyperlink.java
new file mode 100644
index 0000000..6223bd8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/JavaElementHyperlink.java
@@ -0,0 +1,60 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.hyperlink;

+

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.ui.JavaElementLabels;

+import org.eclipse.jdt.ui.JavaUI;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.PartInitException;

+

+/**

+ * JFace {@link IHyperlink} implementation for JDT Java element

+ * {@link IJavaElement} .

+ * 

+ */

+public class JavaElementHyperlink implements IHyperlink {

+

+	private final IRegion region;

+	private final IJavaElement element;

+

+	public JavaElementHyperlink(IRegion region, IJavaElement element) {

+		this.region = region;

+		this.element = element;

+	}

+

+	public IRegion getHyperlinkRegion() {

+		return region;

+	}

+

+	public void open() {

+		if (element != null)

+			try {

+				JavaUI.revealInEditor(JavaUI.openInEditor(element), element);

+			} catch (PartInitException _ex) {

+			} catch (JavaModelException _ex) {

+			}

+	}

+

+	public String getTypeLabel() {

+		return null;

+	}

+

+	public String getHyperlinkText() {

+		return (new StringBuilder("Open '"))

+				.append(JavaElementLabels.getElementLabel(element,

+						JavaElementLabels.ALL_POST_QUALIFIED)).append("'")

+				.toString();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/PropertiesFileHyperlink.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/PropertiesFileHyperlink.java
new file mode 100644
index 0000000..84be8e4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/PropertiesFileHyperlink.java
@@ -0,0 +1,271 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.hyperlink;

+

+import org.eclipse.core.filebuffers.FileBuffers;

+import org.eclipse.core.filebuffers.ITextFileBuffer;

+import org.eclipse.core.filebuffers.ITextFileBufferManager;

+import org.eclipse.core.filebuffers.LocationKind;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IPath;

+import org.eclipse.jdt.internal.ui.JavaPlugin;

+import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;

+import org.eclipse.jdt.internal.ui.propertiesfileeditor.IPropertiesFilePartitions;

+import org.eclipse.jdt.internal.ui.propertiesfileeditor.PropertyKeyHyperlinkDetector;

+import org.eclipse.jface.text.BadLocationException;

+import org.eclipse.jface.text.BadPartitioningException;

+import org.eclipse.jface.text.FindReplaceDocumentAdapter;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.jface.text.IDocumentExtension3;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.ITypedRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.IEditorInput;

+import org.eclipse.ui.IEditorPart;

+import org.eclipse.ui.PartInitException;

+import org.eclipse.ui.texteditor.ITextEditor;

+

+/**

+ * JFace {@link IHyperlink} implementation for properties file {@link IStorage}.

+ * 

+ */

+public class PropertiesFileHyperlink implements IHyperlink {

+

+	private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',

+			'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

+

+	private final IRegion region;

+	private final IStorage propertiesFile;

+	private final String keyName;

+	private final IEditorPart editor;

+

+	public PropertiesFileHyperlink(IRegion region, IStorage propertiesFile,

+			String keyName, IEditorPart editor) {

+		this.region = region;

+		this.propertiesFile = propertiesFile;

+		this.keyName = keyName;

+		this.editor = editor;

+	}

+

+	public IRegion getHyperlinkRegion() {

+		return region;

+	}

+

+	public String getTypeLabel() {

+		return null;

+	}

+

+	public String getHyperlinkText() {

+		return (new StringBuilder("Open '").toString());

+	}

+

+	public void open() {

+		openKeyInPropertiesFile(keyName, propertiesFile, editor);

+

+	}

+

+	/**

+	 * Calculates the region of the NLS key in the properties file and reveals

+	 * it in editor.

+	 * 

+	 * @param keyName

+	 *            the NLS key

+	 * @param propertiesFile

+	 *            the properties file, or <code>null</code>

+	 * @param activeEditor

+	 *            the active editor part

+	 */

+	public static void openKeyInPropertiesFile(String keyName,

+			IStorage propertiesFile, IEditorPart activeEditor) {

+		if (propertiesFile == null) {

+			// showErrorInStatusLine(activeEditor,

+			// JavaEditorMessages.Editor_OpenPropertiesFile_error_fileNotFound_dialogMessage);

+			return;

+		}

+

+		IEditorPart editor;

+		try {

+			editor = EditorUtility.openInEditor(propertiesFile, true);

+		} catch (PartInitException e) {

+			handleOpenPropertiesFileFailed(propertiesFile, activeEditor);

+			return;

+		}

+

+		// Reveal the key in the editor

+		IEditorInput editorInput = editor.getEditorInput();

+		IDocument document = null;

+		if (editor instanceof ITextEditor)

+			document = ((ITextEditor) editor).getDocumentProvider()

+					.getDocument(editorInput);

+		else {

+			IFile file = (IFile) editorInput.getAdapter(IFile.class);

+			if (file != null) {

+				IPath path = file.getFullPath();

+				ITextFileBufferManager manager = FileBuffers

+						.getTextFileBufferManager();

+				try {

+					manager.connect(path, LocationKind.IFILE, null);

+					try {

+						ITextFileBuffer buffer = manager.getTextFileBuffer(

+								path, LocationKind.IFILE);

+						if (buffer != null)

+							document = buffer.getDocument();

+					} finally {

+						manager.disconnect(path, LocationKind.IFILE, null);

+					}

+				} catch (CoreException ex) {

+					JavaPlugin.log(ex);

+				}

+			}

+		}

+

+		// Find key in document

+		boolean found = false;

+		IRegion region = null;

+		if (document != null) {

+			FindReplaceDocumentAdapter finder = new FindReplaceDocumentAdapter(

+					document);

+			PropertyKeyHyperlinkDetector detector = new PropertyKeyHyperlinkDetector();

+			detector.setContext(editor);

+			String key = unwindEscapeChars(keyName);

+			int offset = document.getLength() - 1;

+			try {

+				while (!found && offset >= 0) {

+					region = finder

+							.find(offset, key, false, true, false, false);

+					if (region == null)

+						offset = -1;

+					else {

+						// test whether it's the key

+						IHyperlink[] hyperlinks = detector.detectHyperlinks(

+								null, region, false);

+						if (hyperlinks != null) {

+							for (int i = 0; i < hyperlinks.length; i++) {

+								IRegion hyperlinkRegion = hyperlinks[i]

+										.getHyperlinkRegion();

+								found = key.equals(document.get(

+										hyperlinkRegion.getOffset(),

+										hyperlinkRegion.getLength()));

+							}

+						} else if (document instanceof IDocumentExtension3) {

+							// Fall back: test using properties file

+							// partitioning

+							ITypedRegion partition = null;

+							partition = ((IDocumentExtension3) document)

+									.getPartition(

+											IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING,

+											region.getOffset(), false);

+							found = IDocument.DEFAULT_CONTENT_TYPE

+									.equals(partition.getType())

+									&& key.equals(document.get(

+											partition.getOffset(),

+											partition.getLength()).trim());

+						}

+						// Prevent endless loop (panic code, shouldn't be

+						// needed)

+						if (offset == region.getOffset())

+							offset = -1;

+						else

+							offset = region.getOffset();

+					}

+				}

+			} catch (BadLocationException ex) {

+				found = false;

+			} catch (BadPartitioningException e1) {

+				found = false;

+			}

+		}

+		if (found)

+			EditorUtility.revealInEditor(editor, region);

+		else {

+			EditorUtility.revealInEditor(editor, 0, 0);

+			// showErrorInStatusLine(editor,

+			// Messages.format(JavaEditorMessages.Editor_OpenPropertiesFile_error_keyNotFound,

+			// keyName));

+		}

+	}

+

+	/**

+	 * Shows error message in status line if opening the properties file in

+	 * editor fails.

+	 * 

+	 * @param propertiesFile

+	 *            the propertiesFile

+	 * @param editor

+	 *            the editor part

+	 */

+	private static void handleOpenPropertiesFileFailed(IStorage propertiesFile,

+			IEditorPart editor) {

+		// showErrorInStatusLine(editor,

+		// Messages.format(JavaEditorMessages.Editor_OpenPropertiesFile_error_openEditor_dialogMessage,

+		// BasicElementLabels.getPathLabel(propertiesFile.getFullPath(),

+		// true)));

+	}

+

+	public static String unwindEscapeChars(String s) {

+		StringBuilder sb = new StringBuilder(s.length());

+		int length = s.length();

+		for (int i = 0; i < length; i++) {

+			char c = s.charAt(i);

+			sb.append(getUnwoundString(c));

+		}

+		return sb.toString();

+	}

+

+	private static String getUnwoundString(char c) {

+		switch (c) {

+		case '\b':

+			return "\\b";//$NON-NLS-1$

+		case '\t':

+			return "\\t";//$NON-NLS-1$

+		case '\n':

+			return "\\n";//$NON-NLS-1$

+		case '\f':

+			return "\\f";//$NON-NLS-1$

+		case '\r':

+			return "\\r";//$NON-NLS-1$

+

+			// These can be used unescaped in properties file:

+			// case '\"' :

+			// return "\\\"";//$NON-NLS-1$

+			// case '\'' :

+			// return "\\\'";//$NON-NLS-1$

+

+		case '\\':

+			return "\\\\";//$NON-NLS-1$

+

+			// This is only done when writing to the .properties file in

+			// #unwindValue(String)

+			// case '!':

+			// return "\\!";//$NON-NLS-1$

+			// case '#':

+			// return "\\#";//$NON-NLS-1$

+

+		default:

+			if (((c < 0x0020) || (c > 0x007e))) {

+				return new StringBuilder().append('\\').append('u')

+						.append(toHex((c >> 12) & 0xF))

+						.append(toHex((c >> 8) & 0xF))

+						.append(toHex((c >> 4) & 0xF)).append(toHex(c & 0xF))

+						.toString();

+

+			} else

+				return String.valueOf(c);

+		}

+	}

+

+	private static char toHex(int halfByte) {

+		return HEX_DIGITS[(halfByte & 0xF)];

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/ResourceHyperlink.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/ResourceHyperlink.java
new file mode 100644
index 0000000..c5bb8e4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/hyperlink/ResourceHyperlink.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.hyperlink;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;

+

+/**

+ * JFace {@link IHyperlink} implementation for {@link IResource}.

+ * 

+ */

+public class ResourceHyperlink implements IHyperlink {

+

+	private final IRegion region;

+	private final IResource resource;

+	private final int startOffset;

+	private final int length;

+

+	public ResourceHyperlink(IRegion region, IResource file, int startOffset,

+			int length) {

+		this.region = region;

+		this.resource = file;

+		this.startOffset = startOffset;

+		this.length = length;

+	}

+

+	public ResourceHyperlink(IRegion region, IResource file) {

+		this(region, file, 0, 0);

+	}

+

+	public IRegion getHyperlinkRegion() {

+		return region;

+	}

+

+	public String getTypeLabel() {

+		return null;

+	}

+

+	public String getHyperlinkText() {

+		return (new StringBuilder("Open '"))

+				.append("/"

+						+ resource.getProject().getName()

+						+ "/"

+						+ resource.getProjectRelativePath().toString()

+								.toString()).append("'").toString();

+	}

+

+	public void open() {

+		switch (resource.getType()) {

+		case IResource.FILE:

+			EditorUtils.openInEditor((IFile) resource, startOffset, length,

+					true);

+			break;

+		}

+		// TODO : manage another resource type.

+

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesFileVisitor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesFileVisitor.java
new file mode 100644
index 0000000..bab690f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesFileVisitor.java
@@ -0,0 +1,125 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.indexing;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Map;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IResourceProxy;

+import org.eclipse.core.resources.IResourceProxyVisitor;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.core.util.FileUtils;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;

+

+/**

+ * Visitor which retrieves XML references files.

+ */

+class XMLReferencesFileVisitor implements IResourceProxyVisitor {

+

+	private final IProgressMonitor monitor;

+	private final Map<String, Collection<IFile>> files;

+

+	public XMLReferencesFileVisitor(Map<String, Collection<IFile>> files,

+			IProgressMonitor monitor) {

+		this.monitor = monitor;

+		this.files = files;

+	}

+

+	public boolean visit(IResourceProxy proxy) throws CoreException {

+

+		// check job canceled

+		if (this.monitor != null && this.monitor.isCanceled()) {

+			// setCanceledState();

+			return false;

+		}

+

+		if (proxy.getType() == IResource.FILE) {

+

+			// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3553

+			// check this before description

+			// check name before actually getting the file (less work)

+			if (isXMLFile(proxy.getName())) {

+				IResource resource = proxy.requestResource();

+				String contentTypeId = isXMLReferenceResource(resource);

+				if (contentTypeId != null) {

+					IFile file = (IFile) resource;

+					if (XMLReferencesIndexManager.DEBUG)

+						System.out

+								.println("(+) XMLReferencesFileVisitor adding file: " + file.getName()); //$NON-NLS-1$

+					// this call will check the ContentTypeDescription,

+					// so

+					// don't need to do it here.

+					addXMLFile(file, contentTypeId, files);

+					// this.files.add(file);

+					this.monitor.subTask(proxy.getName());

+

+					// don't search deeper for files

+					return false;

+				}

+			}

+		}

+		return true;

+	}

+

+	private boolean isXMLFile(String filename) {

+		return FileUtils.isXMLFile(filename);

+	}

+

+	private String isXMLReferenceResource(IResource resource) {

+		if (resource == null) {

+			return null;

+		}

+		if (!resource.exists()) {

+			return null;

+		}

+		if (resource.getType() != IResource.FILE) {

+			return null;

+		}

+		Collection<String> contentTypeIds = XMLReferencesManager.getInstance()

+				.getContentTypeIds();

+		String contentTypeId = DOMUtils

+				.getStructuredModelContentTypeId((IFile) resource);

+		if (contentTypeId == null) {

+			return null;

+		}

+		if (contentTypeIds.contains(contentTypeId)) {

+			return contentTypeId;

+		}

+		return null;

+	}

+

+	public void addXMLFile(IFile file, String contentTypeId,

+			Map<String, Collection<IFile>> indexedFiles) {

+		if (!file.isAccessible()) {

+			return;

+		}

+		// String contentTypeId =

+		// DOMUtils.getStructuredModelContentTypeId(file);

+		// if (contentTypeId == null) {

+		// return;

+		// }

+		Collection<IFile> f = indexedFiles.get(contentTypeId);

+		if (f == null) {

+			f = new ArrayList<IFile>();

+			indexedFiles.put(contentTypeId, f);

+		}

+		if (!f.contains(file)) {

+			f.add(file);

+		}

+		if (XMLReferencesIndexManager.DEBUG)

+			System.out.println("adding XML file:" + file.getFullPath()); //$NON-NLS-1$	

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesIndexManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesIndexManager.java
new file mode 100644
index 0000000..b2e8269
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/indexing/XMLReferencesIndexManager.java
@@ -0,0 +1,148 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.indexing;

+

+import java.util.Collection;

+import java.util.Collections;

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.jdt.core.IJavaProject;

+

+public class XMLReferencesIndexManager {

+

+	// for debugging

+	static final boolean DEBUG;

+	static {

+		String value = Platform

+				.getDebugOption("org.eclipse.wst.xml.search.editor/debug/indexmanager"); //$NON-NLS-1$

+		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$

+	}

+

+	public static XMLReferencesIndexManager INSTANCE = new XMLReferencesIndexManager();

+

+	private Map<IProject, Map<String, Collection<IFile>>> indexedFiles = null;

+

+	public static XMLReferencesIndexManager getDefault() {

+		return INSTANCE;

+	}

+

+	public XMLReferencesIndexManager() {

+		indexedFiles = new HashMap<IProject, Map<String, Collection<IFile>>>();

+	}

+

+	public Collection<IFile> getIndexedFiles(IProject project,

+			String contentTypeId, IProgressMonitor monitor) {

+		indexFilesIfNeeded(project, monitor);

+		Map<String, Collection<IFile>> files = indexedFiles.get(project);

+		if (files == null) {

+			return Collections.emptyList();

+		}

+		Collection<IFile> f = files.get(contentTypeId);

+		if (f == null) {

+			return Collections.emptyList();

+		}

+		return f;

+	}

+

+	private void indexFilesIfNeeded(IProject project, IProgressMonitor monitor) {

+		Map<String, Collection<IFile>> files = indexedFiles.get(project);

+		if (files == null) {

+			files = new HashMap<String, Collection<IFile>>();

+			run(project, files, monitor);

+			indexedFiles.put(project, files);

+		}

+	}

+

+	public void flushIndexedFiles(IJavaProject javaProject) {

+		if (javaProject == null) {

+			indexedFiles.clear();

+		} else {

+			IProject project = javaProject.getProject();

+			indexedFiles.remove(project);

+			IProject[] referencingProjects = project.getReferencingProjects();

+			for (IProject referencingProject : referencingProjects) {

+				indexedFiles.remove(referencingProject);

+			}

+		}

+	}

+

+	public void initialize() {

+		// TODO Auto-generated method stub

+

+	}

+

+	public void destroy() {

+		// TODO Auto-generated method stub

+

+	}

+

+	private IStatus run(IProject project, Map<String, Collection<IFile>> files,

+			IProgressMonitor monitor) {

+

+		IStatus status = Status.OK_STATUS;

+

+		if (monitor.isCanceled()) {

+			// setCanceledState();

+			return Status.CANCEL_STATUS;

+		}

+

+		if (DEBUG)

+			System.out.println(" ^ IndexWorkspaceJob started: "); //$NON-NLS-1$

+

+		Thread.currentThread().setPriority(Thread.MAX_PRIORITY);

+		long start = System.currentTimeMillis();

+

+		try {

+			XMLReferencesFileVisitor visitor = new XMLReferencesFileVisitor(

+					files, monitor);

+			// collect all jsp files

+			if (project != null) {

+				project.accept(visitor, IResource.DEPTH_INFINITE);

+				// IProject[] referencingProjects = project

+				// .getReferencingProjects();

+				// for (int i = 0; i < referencingProjects.length; i++) {

+				// referencingProjects[i].accept(visitor,

+				// IResource.DEPTH_INFINITE);

+				// }

+			} else {

+				ResourcesPlugin.getWorkspace().getRoot().accept(visitor,

+						IResource.DEPTH_INFINITE);

+			}

+			// request indexing

+			// this is pretty much like faking an entire workspace resource

+			// delta

+			// XMLReferenceIndexManager.getInstance().indexFiles(

+			// visitor.getFiles());

+		} catch (CoreException e) {

+			if (DEBUG)

+				e.printStackTrace();

+		} finally {

+			monitor.done();

+		}

+		long finish = System.currentTimeMillis();

+		if (DEBUG)

+			System.out

+					.println(" ^ IndexWorkspaceJob finished\n   total time running: " + (finish - start)); //$NON-NLS-1$

+

+		return status;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/JDTStorageLocationProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/JDTStorageLocationProvider.java
new file mode 100644
index 0000000..914c6e4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/JDTStorageLocationProvider.java
@@ -0,0 +1,31 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.jdt;

+

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.jdt.core.IJarEntryResource;

+import org.eclipse.wst.xml.search.core.storage.IStorageLocationProvider;

+

+public class JDTStorageLocationProvider implements IStorageLocationProvider {

+

+	public String getLocation(IStorage storage) {

+		if (storage instanceof IJarEntryResource) {

+			StringBuilder location = new StringBuilder("/");

+			location.append(((IJarEntryResource) storage)

+					.getPackageFragmentRoot().getPath());

+			location.append("/");

+			location.append(storage.getName());

+			return location.toString();

+		}

+		return null;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/SuperTypeHierarchyCache.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/SuperTypeHierarchyCache.java
new file mode 100644
index 0000000..cd7588d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/SuperTypeHierarchyCache.java
@@ -0,0 +1,140 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.jdt;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.ITypeHierarchy;

+import org.eclipse.jdt.core.ITypeHierarchyChangedListener;

+import org.eclipse.jdt.core.JavaModelException;

+

+public class SuperTypeHierarchyCache {

+

+	private static final int CACHE_SIZE = 50;

+	private static List<HierarchyCacheEntry> HIERACHY_CACHE = new ArrayList<HierarchyCacheEntry>(

+			50);

+

+	public SuperTypeHierarchyCache() {

+	}

+

+	private static void addTypeHierarchyToCache(ITypeHierarchy hierarchy) {

+		synchronized (HIERACHY_CACHE) {

+			int nEntries = HIERACHY_CACHE.size();

+			if (nEntries >= 50) {

+				HierarchyCacheEntry oldest = null;

+				List<HierarchyCacheEntry> obsoleteHierarchies = new ArrayList<HierarchyCacheEntry>(

+						50);

+				for (int i = 0; i < nEntries; i++) {

+					HierarchyCacheEntry entry = HIERACHY_CACHE.get(i);

+					ITypeHierarchy curr = entry.getTypeHierarchy();

+					if (!curr.exists() || hierarchy.contains(curr.getType()))

+						obsoleteHierarchies.add(entry);

+					else if (oldest == null

+							|| entry.getLastAccess() < oldest.getLastAccess())

+						oldest = entry;

+				}

+

+				if (!obsoleteHierarchies.isEmpty()) {

+					for (int i = 0; i < obsoleteHierarchies.size(); i++)

+						removeHierarchyEntryFromCache((HierarchyCacheEntry) obsoleteHierarchies

+								.get(i));

+

+				} else if (oldest != null)

+					removeHierarchyEntryFromCache(oldest);

+			}

+			HierarchyCacheEntry newEntry = new HierarchyCacheEntry(hierarchy);

+			HIERACHY_CACHE.add(newEntry);

+		}

+	}

+

+	private static ITypeHierarchy findTypeHierarchyInCache(IType type) {

+		synchronized (HIERACHY_CACHE) {

+			for (int i = HIERACHY_CACHE.size() - 1; i >= 0; i--) {

+				HierarchyCacheEntry curr = (HierarchyCacheEntry) HIERACHY_CACHE

+						.get(i);

+				ITypeHierarchy hierarchy = curr.getTypeHierarchy();

+				if (!hierarchy.exists()) {

+					removeHierarchyEntryFromCache(curr);

+				} else {

+					if (hierarchy.contains(type)) {

+						curr.markAsAccessed();

+						return hierarchy;

+					}

+				}

+			}

+		}

+		return null;

+	}

+

+	public static ITypeHierarchy getTypeHierarchy(IType type)

+			throws JavaModelException {

+		return getTypeHierarchy(type, null);

+	}

+

+	public static ITypeHierarchy getTypeHierarchy(IType type,

+			IProgressMonitor progressMonitor) throws JavaModelException {

+		ITypeHierarchy hierarchy = findTypeHierarchyInCache(type);

+		if (hierarchy == null) {

+			hierarchy = type.newTypeHierarchy(progressMonitor);

+			addTypeHierarchyToCache(hierarchy);

+		}

+		return hierarchy;

+	}

+

+	public static boolean hasInCache(IType type) {

+		return findTypeHierarchyInCache(type) != null;

+	}

+

+	private static void removeHierarchyEntryFromCache(HierarchyCacheEntry entry) {

+		synchronized (HIERACHY_CACHE) {

+			entry.dispose();

+			HIERACHY_CACHE.remove(entry);

+		}

+	}

+

+	private static class HierarchyCacheEntry implements

+			ITypeHierarchyChangedListener {

+

+		public void dispose() {

+			typeHierarchy.removeTypeHierarchyChangedListener(this);

+			typeHierarchy = null;

+		}

+

+		public long getLastAccess() {

+			return lastAccess;

+		}

+

+		public ITypeHierarchy getTypeHierarchy() {

+			return typeHierarchy;

+		}

+

+		public void markAsAccessed() {

+			lastAccess = System.currentTimeMillis();

+		}

+

+		public void typeHierarchyChanged(ITypeHierarchy typeHierarchy) {

+			SuperTypeHierarchyCache.removeHierarchyEntryFromCache(this);

+		}

+

+		private long lastAccess;

+		private ITypeHierarchy typeHierarchy;

+

+		public HierarchyCacheEntry(ITypeHierarchy hierarchy) {

+			typeHierarchy = hierarchy;

+			typeHierarchy.addTypeHierarchyChangedListener(this);

+			markAsAccessed();

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/JDTSearchDOMNodeCollector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/JDTSearchDOMNodeCollector.java
new file mode 100644
index 0000000..d0a3d18
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/JDTSearchDOMNodeCollector.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.jdt.search;

+

+import org.eclipse.jdt.ui.search.ISearchRequestor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.ui.XMLMatch;

+

+public class JDTSearchDOMNodeCollector implements IXMLSearchDOMNodeCollector {

+

+	private final ISearchRequestor requestor;

+

+	public JDTSearchDOMNodeCollector(final ISearchRequestor requestor) {

+		this.requestor = requestor;

+	}

+

+	public boolean add(IDOMNode node) {

+		requestor.reportMatch(new XMLMatch(node));

+		return true;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLReferenceJavaSearchParticipant.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLReferenceJavaSearchParticipant.java
new file mode 100644
index 0000000..a5e842d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLReferenceJavaSearchParticipant.java
@@ -0,0 +1,288 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.jdt.search;

+

+import java.util.Collection;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.NullProgressMonitor;

+import org.eclipse.core.runtime.SubProgressMonitor;

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.jdt.core.IJavaProject;

+import org.eclipse.jdt.core.IMember;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.search.IJavaSearchConstants;

+import org.eclipse.jdt.core.search.IJavaSearchScope;

+import org.eclipse.jdt.ui.search.ElementQuerySpecification;

+import org.eclipse.jdt.ui.search.IMatchPresentation;

+import org.eclipse.jdt.ui.search.IQueryParticipant;

+import org.eclipse.jdt.ui.search.ISearchRequestor;

+import org.eclipse.jdt.ui.search.PatternQuerySpecification;

+import org.eclipse.jdt.ui.search.QuerySpecification;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.core.SimpleXMLSearchEngine;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.indexing.XMLReferencesIndexManager;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;

+import org.eclipse.wst.xml.search.editor.util.XMLQuerySpecificationUtil;

+

+/**

+ * JDT {@link IQueryParticipant} implementation to give the capability to search

+ * Java classes and Java methods used in the XML files which are managed with

+ * XML references extension point

+ * "org.eclipse.wst.xml.search.editor.references".

+ * 

+ * XML search engine will be used to retrieve from XML files :

+ * <ul>

+ * <li>declared classes when "toJava" is used :

+ * 

+ * <pre>

+ * &lt;reference&gt;			

+ * 				&lt;from ... /&gt;

+ * 				&lt;toJava /&gt;

+ * 			&lt;/reference&gt;

+ * </pre>

+ * 

+ * </li>

+ * <li>declared methods when "toJavaMethod" is used :

+ * 

+ * <pre>

+ * &lt;reference&gt;			

+ * 				&lt;from ... /&gt;

+ * 				&lt;toJavaMethod /&gt;

+ * 			&lt;/reference&gt;

+ * </pre>

+ * 

+ * </li>

+ * </ul>

+ */

+public class XMLReferenceJavaSearchParticipant implements IQueryParticipant {

+

+	/**

+	 * Singleton instance of the UI participant for the configuration search

+	 * matches

+	 */

+	private IMatchPresentation uiParticipant;

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.jdt.ui.search.IQueryParticipant#estimateTicks(org.eclipse

+	 * .jdt.ui.search.QuerySpecification)

+	 */

+	public int estimateTicks(QuerySpecification query) {

+		if (isValid(query)) {

+			return 50;

+		}

+		return 0;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.jdt.ui.search.IQueryParticipant#getUIParticipant()

+	 */

+	public synchronized IMatchPresentation getUIParticipant() {

+		if (uiParticipant == null) {

+			uiParticipant = new XMLUIParticipant();

+		}

+		return uiParticipant;

+	}

+

+	public void search(final ISearchRequestor requestor,

+			final QuerySpecification query, IProgressMonitor monitor)

+			throws CoreException {

+		if (!isValid(query)) {

+			return;

+		}

+		if (monitor == null) {

+			monitor = new NullProgressMonitor();

+		}

+		monitor.beginTask("", 11); //$NON-NLS-1$

+		try {

+			// Get Java project, class name and method name to search

+			IJavaProject javaProject = null;

+			String className = null;

+			String methodName = null;

+			if (query instanceof ElementQuerySpecification) {

+				// Java Search launched with Java Editor with Ctrl+Shift+G

+				ElementQuerySpecification elementQuery = (ElementQuerySpecification) query;

+				IJavaElement element = elementQuery.getElement();

+				if (element instanceof IMember) {

+					IMember member = (IMember) element;

+					javaProject = member.getJavaProject();

+					if (member.getElementType() == IJavaElement.TYPE) {

+						// Java class

+						IType type = (IType) member;

+						className = type.getFullyQualifiedName('.');

+					} else if (member.getElementType() == IJavaElement.METHOD) {

+						IMethod method = (IMethod) member;

+						methodName = method.getElementName();

+						className = method.getDeclaringType()

+								.getFullyQualifiedName('.');

+					}

+				} else {

+					return;

+				}

+			} else if (query instanceof PatternQuerySpecification) {

+				// Java Search launched with Java UI Dialog Search

+				PatternQuerySpecification patternQuery = (PatternQuerySpecification) query;

+				if (patternQuery.getSearchFor() == IJavaSearchConstants.METHOD) {

+					methodName = patternQuery.getPattern();

+				} else {

+					className = patternQuery.getPattern();

+				}

+			}

+			if (monitor.isCanceled()) {

+				return;

+			}

+			monitor.worked(1);

+			if (className == null && methodName == null) {

+				return;

+			}

+			ToType toType = (!StringUtils.isEmpty(methodName) ? ToType.JAVA_METHOD

+					: ToType.JAVA);

+			Collection<IXMLReference> references = XMLReferencesManager

+					.getInstance().getXMLReferencesForToType(toType);

+			if (references.size() < 1) {

+				return;

+			}

+			XMLReferencesIndexManager.getDefault().flushIndexedFiles(javaProject);

+			searchXMLReferences(query.getScope(), requestor, className,

+					methodName, javaProject, references, toType,

+					new SubProgressMonitor(monitor, 7));

+		} finally {

+			monitor.done();

+		}

+	}

+

+	private void searchXMLReferences(IJavaSearchScope scope,

+			ISearchRequestor requestor, String className, String methodName,

+			IJavaProject javaProject, Collection<IXMLReference> references,

+			ToType toType, SubProgressMonitor monitor) {

+		if (javaProject != null) {

+			search(requestor, className, methodName, javaProject.getProject(),

+					references, toType, monitor);

+		}

+	}

+

+	private void search(final ISearchRequestor requestor, String className,

+			String methodName, IProject project,

+			Collection<IXMLReference> references, ToType toType,

+			IProgressMonitor monitor) {

+

+		IXMLSearchDOMNodeCollector collector = null;

+		String contentTypeId = null;

+		String javaTypeName = null;

+		for (IXMLReference reference : references) {

+			String[] contentTypeIds = reference.getContentTypeIds();

+			for (int i = 0; i < contentTypeIds.length; i++) {

+				contentTypeId = contentTypeIds[i];

+				if (toType == ToType.JAVA) {

+					javaTypeName = className;

+				} else {

+					javaTypeName = methodName;

+				}

+

+				collector = search(requestor, javaTypeName, monitor, project,

+						collector, contentTypeId, reference);

+

+				IProject[] referencingProjects = project

+						.getReferencingProjects();

+				for (IProject referencingProject : referencingProjects) {

+					collector = search(requestor, javaTypeName, monitor,

+							referencingProject, collector, contentTypeId,

+							reference);

+				}

+			}

+		}

+	}

+

+	private IXMLSearchDOMNodeCollector search(final ISearchRequestor requestor,

+			String javaTypeName, IProgressMonitor monitor, IProject project,

+			IXMLSearchDOMNodeCollector collector, String contentTypeId,

+			IXMLReference reference) {

+		Collection<IFile> indexedFiles = XMLReferencesIndexManager.getDefault()

+				.getIndexedFiles(project, contentTypeId, monitor);

+		if (indexedFiles != null && indexedFiles.size() > 0) {

+			if (collector == null) {

+				collector = new JDTSearchDOMNodeCollector(requestor);

+			}

+

+			IXMLReferencePath referencePath = reference.getFrom();

+			IXMLQuerySpecification xmlQuerySpecification = XMLQuerySpecificationUtil

+					.getQuerySpecification(referencePath);

+			if (xmlQuerySpecification != null) {

+				String query = referencePath.getQuery(null, javaTypeName,

+						xmlQuerySpecification.getEqualsStringQueryBuilder(),

+						true);

+				if (query != null) {

+

+					SimpleXMLSearchEngine.getDefault().search(

+							indexedFiles.toArray(new IResource[indexedFiles

+									.size()]),

+							xmlQuerySpecification.getRequestor(),

+							xmlQuerySpecification.getVisitor(), query, null,

+							null, collector, null, null, monitor);

+				}

+			}

+		}

+		return collector;

+	}

+

+	/**

+	 * Determines if the current query should be considered or not

+	 * 

+	 * @param query

+	 *            the current query

+	 * @return true if the query should be considered, false otherwise

+	 */

+	private boolean isValid(QuerySpecification query) {

+		switch (query.getLimitTo()) {

+		case IJavaSearchConstants.REFERENCES:

+		case IJavaSearchConstants.ALL_OCCURRENCES: {

+			break;

+		}

+		default: {

+			return false;

+		}

+		}

+		if (query instanceof ElementQuerySpecification) {

+			IJavaElement element = ((ElementQuerySpecification) query)

+					.getElement();

+			return element.getElementType() == IJavaElement.TYPE

+					|| element.getElementType() == IJavaElement.METHOD;

+		}

+		if (query instanceof PatternQuerySpecification) {

+			PatternQuerySpecification patternQuery = (PatternQuerySpecification) query;

+			switch (patternQuery.getSearchFor()) {

+			case IJavaSearchConstants.UNKNOWN:

+			case IJavaSearchConstants.TYPE:

+			case IJavaSearchConstants.CLASS:

+			case IJavaSearchConstants.CLASS_AND_INTERFACE:

+			case IJavaSearchConstants.METHOD: {

+				return true;

+			}

+			}

+		}

+		return false;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLUIParticipant.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLUIParticipant.java
new file mode 100644
index 0000000..93bb279
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search/XMLUIParticipant.java
@@ -0,0 +1,45 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.jdt.search;

+

+import org.eclipse.jdt.ui.search.IMatchPresentation;

+import org.eclipse.jface.viewers.ILabelProvider;

+import org.eclipse.search.ui.text.Match;

+import org.eclipse.ui.PartInitException;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.ui.DecoratingXMLSearchLabelProvider;

+import org.eclipse.wst.xml.search.ui.XMLLabelProvider;

+import org.eclipse.wst.xml.search.ui.util.EditorOpener;

+

+public class XMLUIParticipant implements IMatchPresentation {

+

+	private EditorOpener fEditorOpener = new EditorOpener();

+

+	public ILabelProvider createLabelProvider() {

+		return new DecoratingXMLSearchLabelProvider((new XMLLabelProvider()));

+	}

+

+	public void showMatch(Match match, int currentOffset, int currentLength,

+			boolean activate) throws PartInitException {

+		Object o = match.getElement();

+		if (o instanceof IDOMNode) {

+			if (activate) {

+				IDOMNode node = (IDOMNode) o;

+				EditorOpener.openDOMNode(XMLSearchEditorPlugin.getActivePage(),

+						node, fEditorOpener,

+						XMLSearchEditorPlugin.getActiveWorkbenchShell());

+			}

+		}

+

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/JavaContentAssistProposalRecorder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/JavaContentAssistProposalRecorder.java
new file mode 100644
index 0000000..90b6bbf
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/JavaContentAssistProposalRecorder.java
@@ -0,0 +1,93 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.jdt.search2;

+

+import java.util.Collection;

+import java.util.List;

+

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.contentassist.ICompletionProposal;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;

+

+@SuppressWarnings("restriction")

+public class JavaContentAssistProposalRecorder implements

+		IContentAssistProposalRecorder {

+

+	private final IRegion region;

+	private final Collection<ICompletionProposal> proposals;

+

+	private static final String ICONS_FULL_OBJ16_ENUM_GIF = "icons/full/obj16/enum.gif";

+

+	/**

+	 * 

+	 * Creates a new {@link JavaContentAssistProposalRecorder}.

+	 * 

+	 * @param region

+	 */

+

+	public JavaContentAssistProposalRecorder(IRegion region,

+			List<ICompletionProposal> proposals) {

+		this.proposals = proposals;

+		this.region = region;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.editor.contentassist.

+	 * IContentAssistProposalRecorder

+	 * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,

+	 * java.lang.String)

+	 */

+	public void recordProposal(Image image, int relevance, String displayText,

+			String replaceText) {

+		recordProposal(image, relevance, displayText, replaceText, null);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.editor.contentassist.

+	 * IContentAssistProposalRecorder

+	 * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,

+	 * java.lang.String, java.lang.Object)

+	 */

+	public void recordProposal(Image image, int relevance, String displayText,

+			String replaceText, Object proposedObject) {

+		recordProposal(image, relevance, displayText, replaceText,

+				replaceText.length(), proposedObject);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.xml.search.editor.contentassist.

+	 * IContentAssistProposalRecorder

+	 * #recordProposal(org.eclipse.swt.graphics.Image, int, java.lang.String,

+	 * java.lang.String, int, java.lang.Object)

+	 */

+	public void recordProposal(Image image, int relevance, String displayText,

+			String replaceText, int cursorPosition, Object proposedObject) {

+		if (image == null) {

+			image = XMLEditorPluginImageHelper.getInstance().getImage(

+					ICONS_FULL_OBJ16_ENUM_GIF);

+		}

+		proposals.add(new CustomCompletionProposal(replaceText, region

+				.getOffset(), region.getLength(), cursorPosition, image,

+				displayText, null, proposedObject != null ? proposedObject

+						.toString() : null, relevance, true));

+

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/SearchJavaNoTypeCompletionProposalComputer.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/SearchJavaNoTypeCompletionProposalComputer.java
new file mode 100644
index 0000000..0e68ec0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/jdt/search2/SearchJavaNoTypeCompletionProposalComputer.java
@@ -0,0 +1,108 @@
+package org.eclipse.wst.xml.search.editor.internal.jdt.search2;

+

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.internal.ui.text.java.JavaNoTypeCompletionProposalComputer;

+import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext;

+import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;

+import org.eclipse.jface.text.BadLocationException;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.contentassist.ICompletionProposal;

+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper;

+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper.StringArgument;

+import org.eclipse.wst.xml.search.editor.java.IJavaReference;

+import org.eclipse.wst.xml.search.editor.java.JavaReferencesManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+

+public class SearchJavaNoTypeCompletionProposalComputer extends

+		JavaNoTypeCompletionProposalComputer {

+

+	@Override

+	public List<ICompletionProposal> computeCompletionProposals(

+			final ContentAssistInvocationContext context,

+			final IProgressMonitor monitor) {

+		List<ICompletionProposal> proposals = null;

+		if (context instanceof JavaContentAssistInvocationContext) {

+			final JavaContentAssistInvocationContext jcontext = (JavaContentAssistInvocationContext) context;

+			try {

+				int offset = jcontext.getInvocationOffset();

+				IJavaElement element = jcontext.getCompilationUnit()

+						.getElementAt(offset);

+				if (element != null) {

+

+					IJavaReference javaReference = JavaReferencesManager

+							.getInstance().getXMLReference(element, null);

+					if (javaReference != null) {

+

+						IDocument document = jcontext.getDocument();

+						StringArgument stringArgument = DocumentHelper

+								.findStringArgument(document, offset, false);

+

+						if (stringArgument != null) {

+

+							IRegion region = stringArgument.getRegion();

+							String matchingString = stringArgument

+									.getMatchingString();

+							if (proposals == null) {

+								proposals = new ArrayList<ICompletionProposal>();

+							}

+

+							IResource resource = jcontext.getCompilationUnit()

+									.getCorrespondingResource();

+							IFile file = (resource != null && resource

+									.getType() == IResource.FILE) ? (IFile) resource

+									: null;

+							List<IXMLReferenceTo> tos = javaReference.getTo();

+							for (IXMLReferenceTo to : tos) {

+								IXMLSearcher searcher = to.getSearcher();

+								if (searcher != null) {

+									searcher.searchForCompletion(

+											element,

+											matchingString.toString(),

+											null,

+											null,

+											file,

+											to,

+											new JavaContentAssistProposalRecorder(

+													region, proposals));

+								}

+							}

+						}

+					}

+				}

+

+			} catch (JavaModelException e) {

+				e.printStackTrace();

+			}

+		}

+		if (proposals != null) {

+			return proposals;

+		}

+		return Collections.emptyList();

+	}

+

+	private String getMatchingString(final IDocument document, final int offset) {

+		StringBuilder s = new StringBuilder("");

+		try {

+			final IRegion li = document.getLineInformationOfOffset(offset);

+			for (int i = offset - 1; i >= li.getOffset(); i--) {

+				if (document.get(i, 1).equals("\"")) {

+					break;

+				}

+				s.insert(0, document.get(i, 1));

+			}

+		} catch (final BadLocationException e) {

+		}

+		return s.toString();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLReferencesSyntaxColoringPage.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLReferencesSyntaxColoringPage.java
new file mode 100644
index 0000000..91cfafa
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLReferencesSyntaxColoringPage.java
@@ -0,0 +1,1089 @@
+/*******************************************************************************

+ * Copyright (c) 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

+ *     Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search.

+ *     

+ *     Code comes from org.eclipse.wst.xml.ui.internal.preferences.XMLSyntaxColoringPage

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.preferences;

+

+import java.text.Collator;

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+

+import org.eclipse.jface.preference.ColorSelector;

+import org.eclipse.jface.preference.IPreferenceStore;

+import org.eclipse.jface.preference.PreferencePage;

+import org.eclipse.jface.resource.JFaceResources;

+import org.eclipse.jface.text.TextAttribute;

+import org.eclipse.jface.text.source.SourceViewer;

+import org.eclipse.jface.util.IPropertyChangeListener;

+import org.eclipse.jface.util.PropertyChangeEvent;

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.jface.viewers.ISelectionChangedListener;

+import org.eclipse.jface.viewers.IStructuredSelection;

+import org.eclipse.jface.viewers.ITreeContentProvider;

+import org.eclipse.jface.viewers.LabelProvider;

+import org.eclipse.jface.viewers.ListViewer;

+import org.eclipse.jface.viewers.SelectionChangedEvent;

+import org.eclipse.jface.viewers.StructuredSelection;

+import org.eclipse.jface.viewers.StructuredViewer;

+import org.eclipse.jface.viewers.Viewer;

+import org.eclipse.jface.viewers.ViewerComparator;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.accessibility.ACC;

+import org.eclipse.swt.accessibility.AccessibleAdapter;

+import org.eclipse.swt.accessibility.AccessibleEvent;

+import org.eclipse.swt.custom.SashForm;

+import org.eclipse.swt.custom.StyleRange;

+import org.eclipse.swt.custom.StyledText;

+import org.eclipse.swt.events.KeyEvent;

+import org.eclipse.swt.events.KeyListener;

+import org.eclipse.swt.events.MouseEvent;

+import org.eclipse.swt.events.MouseListener;

+import org.eclipse.swt.events.SelectionAdapter;

+import org.eclipse.swt.events.SelectionEvent;

+import org.eclipse.swt.events.SelectionListener;

+import org.eclipse.swt.events.TraverseEvent;

+import org.eclipse.swt.events.TraverseListener;

+import org.eclipse.swt.graphics.Color;

+import org.eclipse.swt.graphics.RGB;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.widgets.Button;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Label;

+import org.eclipse.swt.widgets.Link;

+import org.eclipse.ui.IWorkbench;

+import org.eclipse.ui.IWorkbenchPreferencePage;

+import org.eclipse.ui.PlatformUI;

+import org.eclipse.ui.dialogs.PreferencesUtil;

+import org.eclipse.wst.sse.core.StructuredModelManager;

+import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;

+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;

+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;

+import org.eclipse.wst.sse.ui.internal.SSEUIMessages;

+import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;

+import org.eclipse.wst.sse.ui.internal.preferences.OverlayPreferenceStore;

+import org.eclipse.wst.sse.ui.internal.preferences.OverlayPreferenceStore.OverlayKey;

+import org.eclipse.wst.sse.ui.internal.preferences.ui.ColorHelper;

+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.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;

+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.internal.Messages;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.internal.style.IReferencesStyleConstantsXML;

+import org.eclipse.wst.xml.ui.internal.XMLUIMessages;

+import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;

+import org.eclipse.wst.xml.ui.internal.editor.IHelpContextIds;

+import org.eclipse.wst.xml.ui.internal.style.IStyleConstantsXML;

+import org.w3c.dom.Node;

+

+public class XMLReferencesSyntaxColoringPage extends PreferencePage implements

+		IWorkbenchPreferencePage, IReferencesStyleConstantsXML {

+

+	private Button fColorReferencedEnabled;

+	private Button fBold;

+	private Label fForegroundLabel;

+	private Label fBackgroundLabel;

+	private Button fClearStyle;

+	private Map fContextToStyleMap;

+	private Color fDefaultForeground = null;

+	private Color fDefaultBackground = null;

+	private IStructuredDocument fDocument;

+	private IDOMModel model;

+	private ColorSelector fForegroundColorEditor;

+	private ColorSelector fBackgroundColorEditor;

+	private Button fItalic;

+	private OverlayPreferenceStore fOverlayStore;

+	private Button fStrike;

+	private Collection fStylePreferenceKeys;

+	private StructuredViewer fStylesViewer = null;

+	private Map fStyleToDescriptionMap;

+	private StyledText fText;

+	private Button fUnderline;

+

+	// activate controls based on the given local color type

+	private void activate(String namedStyle) {

+		Color foreground = fDefaultForeground;

+		Color background = fDefaultBackground;

+		if (namedStyle == null) {

+			fClearStyle.setEnabled(false);

+			fBold.setEnabled(false);

+			fItalic.setEnabled(false);

+			fStrike.setEnabled(false);

+			fUnderline.setEnabled(false);

+			fForegroundLabel.setEnabled(false);

+			fBackgroundLabel.setEnabled(false);

+			fForegroundColorEditor.setEnabled(false);

+			fBackgroundColorEditor.setEnabled(false);

+			fBold.setSelection(false);

+			fItalic.setSelection(false);

+			fStrike.setSelection(false);

+			fUnderline.setSelection(false);

+		} else {

+			boolean enabled = fColorReferencedEnabled.getSelection();

+			TextAttribute attribute = getAttributeFor(namedStyle);

+			fClearStyle.setEnabled(enabled);

+			fBold.setEnabled(enabled);

+			fItalic.setEnabled(enabled);

+			fStrike.setEnabled(enabled);

+			fUnderline.setEnabled(enabled);

+			fForegroundLabel.setEnabled(enabled);

+			fBackgroundLabel.setEnabled(enabled);

+			fForegroundColorEditor.setEnabled(enabled);

+			fBackgroundColorEditor.setEnabled(enabled);

+			fBold.setSelection((attribute.getStyle() & SWT.BOLD) != 0);

+			fItalic.setSelection((attribute.getStyle() & SWT.ITALIC) != 0);

+			fStrike

+					.setSelection((attribute.getStyle() & TextAttribute.STRIKETHROUGH) != 0);

+			fUnderline

+					.setSelection((attribute.getStyle() & TextAttribute.UNDERLINE) != 0);

+			if (attribute.getForeground() != null) {

+				foreground = attribute.getForeground();

+			}

+			if (attribute.getBackground() != null) {

+				background = attribute.getBackground();

+			}

+		}

+

+		fForegroundColorEditor.setColorValue(foreground.getRGB());

+		fBackgroundColorEditor.setColorValue(background.getRGB());

+	}

+

+	/**

+	 * Color the text in the sample area according to the current preferences

+	 */

+	void applyStyles() {

+		if (fText == null || fText.isDisposed())

+			return;

+		boolean applyRef = false;

+		IStructuredDocumentRegion[] structuredDocumentRegions = model

+				.getStructuredDocument().getStructuredDocumentRegions();

+		for (int j = 0; j < structuredDocumentRegions.length; j++) {

+			IStructuredDocumentRegion documentRegion = structuredDocumentRegions[j];

+			// ITextRegion currentRegion = documentRegion.getFirstRegion();

+			// while (documentRegion != null) {

+			ITextRegionList regions = documentRegion.getRegions();

+			for (int i = 0; i < regions.size(); i++) {

+				ITextRegion currentRegion = regions.get(i);

+				String namedStyle = null;

+				String type = currentRegion.getType();

+				if ((type == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)) {

+					applyRef = false;

+					IDOMNode node = DOMUtils.getNodeByOffset(model,

+							documentRegion.getStart());

+					if (node != null) {

+						IDOMAttr attr = DOMUtils.getAttrByOffset(node,

+								documentRegion.getStart()

+										+ currentRegion.getStart());

+						if (attr != null && attr.getName().startsWith("ref")) {

+							applyRef = true;

+						}

+					}

+					if (applyRef) {

+						namedStyle = TAG_REFERENCED_ATTRIBUTE_VALUE;

+					} else {

+						namedStyle = (String) fContextToStyleMap

+								.get(currentRegion.getType());

+					}

+				} else if ((type == DOMRegionContext.XML_CONTENT)) {

+					applyRef = false;

+					IDOMNode node = DOMUtils.getNodeByOffset(model,

+							documentRegion.getStart());

+					if (node != null) {

+						Node parent = node.getParentNode();

+						if (parent.getNodeName().startsWith("ref")) {

+							applyRef = true;

+						}

+					}

+					if (applyRef) {

+						namedStyle = XML_REFERENCED_CONTENT;

+					} else {

+						namedStyle = (String) fContextToStyleMap

+								.get(currentRegion.getType());

+					}

+				} else {

+					namedStyle = (String) fContextToStyleMap.get(currentRegion

+							.getType());

+				}

+

+				// lookup the local coloring type and apply it

+				if (namedStyle == null)

+					continue;

+				TextAttribute attribute = getAttributeFor(namedStyle);

+				if (attribute == null)

+					continue;

+				StyleRange style = new StyleRange(documentRegion

+						.getStartOffset(currentRegion), currentRegion

+						.getTextLength(), attribute.getForeground(), attribute

+						.getBackground(), attribute.getStyle());

+				style.strikeout = (attribute.getStyle() & TextAttribute.STRIKETHROUGH) != 0;

+				style.underline = (attribute.getStyle() & TextAttribute.UNDERLINE) != 0;

+				fText.setStyleRange(style);

+			}

+			documentRegion = documentRegion.getNext();

+		}

+	}

+

+	Button createCheckbox(Composite parent, String label) {

+		Button button = new Button(parent, SWT.CHECK);

+		button.setText(label);

+		button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

+		return button;

+	}

+

+	/**

+	 * Creates composite control and sets the default layout data.

+	 */

+	private Composite createComposite(Composite parent, int numColumns) {

+		Composite composite = new Composite(parent, SWT.NULL);

+

+		// GridLayout

+		GridLayout layout = new GridLayout();

+		layout.numColumns = numColumns;

+		layout.makeColumnsEqualWidth = false;

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		composite.setLayout(layout);

+

+		// GridData

+		GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);

+		composite.setLayoutData(data);

+		return composite;

+	}

+

+	protected Control createContents(final Composite parent) {

+		initializeDialogUnits(parent);

+

+		fDefaultForeground = parent.getDisplay().getSystemColor(

+				SWT.COLOR_LIST_FOREGROUND);

+		fDefaultBackground = parent.getDisplay().getSystemColor(

+				SWT.COLOR_LIST_BACKGROUND);

+		final Composite pageComponent = createComposite(parent, 2);

+		PlatformUI.getWorkbench().getHelpSystem().setHelp(pageComponent,

+				IHelpContextIds.XML_PREFWEBX_STYLES_HELPID);

+

+		fColorReferencedEnabled = createCheckbox(pageComponent,

+				Messages.XMLReferencesSyntaxColoringPage_0);

+		fColorReferencedEnabled.addSelectionListener(new SelectionAdapter() {

+			@Override

+			public void widgetSelected(SelectionEvent e) {

+				updateEnabled();

+			}

+		});

+		fColorReferencedEnabled.setSelection(getOverlayStore().getBoolean(ENABLED_COLOR));

+

+		Link link = new Link(pageComponent, SWT.WRAP);

+		link.setText(SSEUIMessages.SyntaxColoring_Link);

+		link.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				PreferencesUtil.createPreferenceDialogOn(parent.getShell(),

+						e.text, null, null);

+			}

+		});

+

+		GridData linkData = new GridData(SWT.FILL, SWT.BEGINNING, true, false,

+				2, 1);

+		linkData.widthHint = 150; // only expand further if anyone else requires

+		// it

+		link.setLayoutData(linkData);

+

+		new Label(pageComponent, SWT.NONE).setLayoutData(new GridData());

+		new Label(pageComponent, SWT.NONE).setLayoutData(new GridData());

+

+		SashForm editor = new SashForm(pageComponent, SWT.VERTICAL);

+		GridData gridData2 = new GridData(SWT.FILL, SWT.FILL, true, true);

+		gridData2.horizontalSpan = 2;

+		editor.setLayoutData(gridData2);

+		SashForm top = new SashForm(editor, SWT.HORIZONTAL);

+		Composite styleEditor = createComposite(top, 1);

+		((GridLayout) styleEditor.getLayout()).marginRight = 5;

+		((GridLayout) styleEditor.getLayout()).marginLeft = 0;

+		createLabel(styleEditor, XMLUIMessages.SyntaxColoringPage_0);

+		fStylesViewer = createStylesViewer(styleEditor);

+		GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);

+		gridData.horizontalIndent = 0;

+		Iterator iterator = fStyleToDescriptionMap.values().iterator();

+		while (iterator.hasNext()) {

+			gridData.widthHint = Math.max(gridData.widthHint,

+					convertWidthInCharsToPixels(iterator.next().toString()

+							.length()));

+		}

+		gridData.heightHint = convertHeightInCharsToPixels(5);

+		fStylesViewer.getControl().setLayoutData(gridData);

+

+		Composite editingComposite = createComposite(top, 1);

+		((GridLayout) styleEditor.getLayout()).marginLeft = 5;

+		createLabel(editingComposite, ""); //$NON-NLS-1$

+		Button enabler = createCheckbox(editingComposite,

+				XMLUIMessages.SyntaxColoringPage_2);

+		enabler.setEnabled(false);

+		enabler.setSelection(true);

+		Composite editControls = createComposite(editingComposite, 2);

+		((GridLayout) editControls.getLayout()).marginLeft = 20;

+

+		fForegroundLabel = createLabel(editControls,

+				SSEUIMessages.Foreground_UI_);

+		((GridData) fForegroundLabel.getLayoutData()).verticalAlignment = SWT.CENTER;

+		fForegroundLabel.setEnabled(false);

+

+		fForegroundColorEditor = new ColorSelector(editControls);

+		Button fForegroundColor = fForegroundColorEditor.getButton();

+		GridData gd = new GridData(SWT.BEGINNING, SWT.FILL, false, false);

+		fForegroundColor.setLayoutData(gd);

+		fForegroundColorEditor.setEnabled(false);

+

+		fBackgroundLabel = createLabel(editControls,

+				SSEUIMessages.Background_UI_);

+		((GridData) fBackgroundLabel.getLayoutData()).verticalAlignment = SWT.CENTER;

+		fBackgroundLabel.setEnabled(false);

+

+		fBackgroundColorEditor = new ColorSelector(editControls);

+		Button fBackgroundColor = fBackgroundColorEditor.getButton();

+		gd = new GridData(SWT.BEGINNING, SWT.FILL, false, false);

+		fBackgroundColor.setLayoutData(gd);

+		fBackgroundColorEditor.setEnabled(false);

+

+		fBold = createCheckbox(editControls, XMLUIMessages.SyntaxColoringPage_3);

+		fBold.setEnabled(false);

+		((GridData) fBold.getLayoutData()).horizontalSpan = 2;

+		fItalic = createCheckbox(editControls,

+				XMLUIMessages.SyntaxColoringPage_4);

+		fItalic.setEnabled(false);

+		((GridData) fItalic.getLayoutData()).horizontalSpan = 2;

+		fStrike = createCheckbox(editControls,

+				XMLUIMessages.SyntaxColoringPage_5);

+		fStrike.setEnabled(false);

+		((GridData) fStrike.getLayoutData()).horizontalSpan = 2;

+		fUnderline = createCheckbox(editControls,

+				XMLUIMessages.SyntaxColoringPage_6);

+		fUnderline.setEnabled(false);

+		((GridData) fUnderline.getLayoutData()).horizontalSpan = 2;

+		fClearStyle = new Button(editingComposite, SWT.PUSH);

+		fClearStyle.setText(SSEUIMessages.Restore_Default_UI_); //$NON-NLS-1$ = "Restore Default"

+		fClearStyle.setLayoutData(new GridData(SWT.BEGINNING));

+		((GridData) fClearStyle.getLayoutData()).horizontalIndent = 20;

+		fClearStyle.setEnabled(false);

+

+		Composite sampleArea = createComposite(editor, 1);

+

+		((GridLayout) sampleArea.getLayout()).marginLeft = 5;

+		((GridLayout) sampleArea.getLayout()).marginTop = 5;

+		createLabel(sampleArea, SSEUIMessages.Sample_text__UI_); //$NON-NLS-1$ = "&Sample text:"

+		SourceViewer viewer = new SourceViewer(sampleArea, null, SWT.BORDER

+				| SWT.LEFT_TO_RIGHT | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL

+				| SWT.READ_ONLY);

+		fText = viewer.getTextWidget();

+		GridData gridData3 = new GridData(SWT.FILL, SWT.FILL, true, true);

+		gridData3.widthHint = convertWidthInCharsToPixels(20);

+		gridData3.heightHint = convertHeightInCharsToPixels(5);

+		gridData3.horizontalSpan = 2;

+		fText.setLayoutData(gridData3);

+		fText.setEditable(false);

+		fText

+				.setFont(JFaceResources

+						.getFont("org.eclipse.wst.sse.ui.textfont")); //$NON-NLS-1$

+		fText.addKeyListener(getTextKeyListener());

+		fText.addSelectionListener(getTextSelectionListener());

+		fText.addMouseListener(getTextMouseListener());

+		fText.addTraverseListener(getTraverseListener());

+		setAccessible(fText, SSEUIMessages.Sample_text__UI_);

+		fDocument = StructuredModelManager.getModelManager()

+				.createStructuredDocumentFor(

+						ContentTypeIdForXML.ContentTypeID_XML);

+		fDocument.set(getExampleText());

+		model = (IDOMModel) StructuredModelManager.getModelManager()

+				.createUnManagedStructuredModelFor(

+						ContentTypeIdForXML.ContentTypeID_XML);

+		model.setStructuredDocument(fDocument);

+		viewer.setDocument(fDocument);

+		top.setWeights(new int[] { 1, 1 });

+		editor.setWeights(new int[] { 1, 1 });

+		PlatformUI.getWorkbench().getHelpSystem().setHelp(pageComponent,

+				IHelpContextIds.XML_PREFWEBX_STYLES_HELPID);

+

+		fStylesViewer.setInput(getStylePreferenceKeys());

+

+		applyStyles();

+		updateEnabled();

+		

+		fStylesViewer

+				.addSelectionChangedListener(new ISelectionChangedListener() {

+					public void selectionChanged(SelectionChangedEvent event) {

+						if (!event.getSelection().isEmpty()) {

+							Object o = ((IStructuredSelection) event

+									.getSelection()).getFirstElement();

+							String namedStyle = o.toString();

+							activate(namedStyle);

+							if (namedStyle == null)

+								return;

+						}

+					}

+				});

+

+		fForegroundColorEditor.addListener(new IPropertyChangeListener() {

+			public void propertyChange(PropertyChangeEvent event) {

+				if (event.getProperty().equals(ColorSelector.PROP_COLORCHANGE)) {

+					Object o = ((IStructuredSelection) fStylesViewer

+							.getSelection()).getFirstElement();

+					String namedStyle = o.toString();

+					String prefString = getOverlayStore().getString(namedStyle);

+					String[] stylePrefs = ColorHelper

+							.unpackStylePreferences(prefString);

+					if (stylePrefs != null) {

+						String oldValue = stylePrefs[0];

+						// open color dialog to get new color

+						String newValue = ColorHelper

+								.toRGBString(fForegroundColorEditor

+										.getColorValue());

+

+						if (!newValue.equals(oldValue)) {

+							stylePrefs[0] = newValue;

+							String newPrefString = ColorHelper

+									.packStylePreferences(stylePrefs);

+							getOverlayStore().setValue(namedStyle,

+									newPrefString);

+							applyStyles();

+							fText.redraw();

+						}

+					}

+				}

+			}

+		});

+

+		fBackgroundColorEditor.addListener(new IPropertyChangeListener() {

+			public void propertyChange(PropertyChangeEvent event) {

+				if (event.getProperty().equals(ColorSelector.PROP_COLORCHANGE)) {

+					Object o = ((IStructuredSelection) fStylesViewer

+							.getSelection()).getFirstElement();

+					String namedStyle = o.toString();

+					String prefString = getOverlayStore().getString(namedStyle);

+					String[] stylePrefs = ColorHelper

+							.unpackStylePreferences(prefString);

+					if (stylePrefs != null) {

+						String oldValue = stylePrefs[1];

+						// open color dialog to get new color

+						String newValue = ColorHelper

+								.toRGBString(fBackgroundColorEditor

+										.getColorValue());

+

+						if (!newValue.equals(oldValue)) {

+							stylePrefs[1] = newValue;

+							String newPrefString = ColorHelper

+									.packStylePreferences(stylePrefs);

+							getOverlayStore().setValue(namedStyle,

+									newPrefString);

+							applyStyles();

+							fText.redraw();

+							activate(namedStyle);

+						}

+					}

+				}

+			}

+		});

+

+		fBold.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				super.widgetSelected(e);

+				// get current (newly old) style

+				Object o = ((IStructuredSelection) fStylesViewer.getSelection())

+						.getFirstElement();

+				String namedStyle = o.toString();

+				String prefString = getOverlayStore().getString(namedStyle);

+				String[] stylePrefs = ColorHelper

+						.unpackStylePreferences(prefString);

+				if (stylePrefs != null) {

+					String oldValue = stylePrefs[2];

+					String newValue = String.valueOf(fBold.getSelection());

+					if (!newValue.equals(oldValue)) {

+						stylePrefs[2] = newValue;

+						String newPrefString = ColorHelper

+								.packStylePreferences(stylePrefs);

+						getOverlayStore().setValue(namedStyle, newPrefString);

+						applyStyles();

+						fText.redraw();

+					}

+				}

+			}

+		});

+

+		fItalic.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				super.widgetSelected(e);

+				// get current (newly old) style

+				Object o = ((IStructuredSelection) fStylesViewer.getSelection())

+						.getFirstElement();

+				String namedStyle = o.toString();

+				String prefString = getOverlayStore().getString(namedStyle);

+				String[] stylePrefs = ColorHelper

+						.unpackStylePreferences(prefString);

+				if (stylePrefs != null) {

+					String oldValue = stylePrefs[3];

+					String newValue = String.valueOf(fItalic.getSelection());

+					if (!newValue.equals(oldValue)) {

+						stylePrefs[3] = newValue;

+						String newPrefString = ColorHelper

+								.packStylePreferences(stylePrefs);

+						getOverlayStore().setValue(namedStyle, newPrefString);

+						applyStyles();

+						fText.redraw();

+					}

+				}

+			}

+		});

+

+		fStrike.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				super.widgetSelected(e);

+				// get current (newly old) style

+				Object o = ((IStructuredSelection) fStylesViewer.getSelection())

+						.getFirstElement();

+				String namedStyle = o.toString();

+				String prefString = getOverlayStore().getString(namedStyle);

+				String[] stylePrefs = ColorHelper

+						.unpackStylePreferences(prefString);

+				if (stylePrefs != null) {

+					String oldValue = stylePrefs[4];

+					String newValue = String.valueOf(fStrike.getSelection());

+					if (!newValue.equals(oldValue)) {

+						stylePrefs[4] = newValue;

+						String newPrefString = ColorHelper

+								.packStylePreferences(stylePrefs);

+						getOverlayStore().setValue(namedStyle, newPrefString);

+						applyStyles();

+						fText.redraw();

+					}

+				}

+			}

+		});

+

+		fUnderline.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				super.widgetSelected(e);

+				// get current (newly old) style

+				Object o = ((IStructuredSelection) fStylesViewer.getSelection())

+						.getFirstElement();

+				String namedStyle = o.toString();

+				String prefString = getOverlayStore().getString(namedStyle);

+				String[] stylePrefs = ColorHelper

+						.unpackStylePreferences(prefString);

+				if (stylePrefs != null) {

+					String oldValue = stylePrefs[5];

+					String newValue = String.valueOf(fUnderline.getSelection());

+					if (!newValue.equals(oldValue)) {

+						stylePrefs[5] = newValue;

+						String newPrefString = ColorHelper

+								.packStylePreferences(stylePrefs);

+						getOverlayStore().setValue(namedStyle, newPrefString);

+						applyStyles();

+						fText.redraw();

+					}

+				}

+			}

+		});

+

+		fClearStyle.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				if (fStylesViewer.getSelection().isEmpty())

+					return;

+				String namedStyle = ((IStructuredSelection) fStylesViewer

+						.getSelection()).getFirstElement().toString();

+				getOverlayStore().setToDefault(namedStyle);

+				applyStyles();

+				fText.redraw();

+				activate(namedStyle);

+			}

+		});

+

+		return pageComponent;

+	}

+	

+	private void updateEnabled() {

+		boolean enabled = fColorReferencedEnabled.getSelection();

+		fStylesViewer.getControl().setEnabled(enabled);

+		getOverlayStore().setValue(ENABLED_COLOR, enabled);

+		if (enabled) {

+			ISelection selection = fStylesViewer.getSelection();

+			if (selection.isEmpty()) {

+				activate(null);

+			}

+			else {

+				String namedStyle = (String)((IStructuredSelection)selection).getFirstElement();

+				activate(namedStyle);

+			}

+		}

+		else {

+			activate(null);

+		}

+	}

+

+	private Label createLabel(Composite parent, String text) {

+		Label label = new Label(parent, SWT.WRAP);

+		label.setText(text);

+		GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);

+		label.setLayoutData(data);

+		label.setBackground(parent.getBackground());

+		return label;

+	}

+

+	// protected Label createDescriptionLabel(Composite parent) {

+	// return null;

+	// }

+

+	/**

+	 * Set up all the style preference keys in the overlay store

+	 */

+	private OverlayKey[] createOverlayStoreKeys() {

+		List overlayKeys = new ArrayList();

+

+		Iterator i = getStylePreferenceKeys().iterator();

+		while (i.hasNext()) {

+			overlayKeys.add(new OverlayPreferenceStore.OverlayKey(

+					OverlayPreferenceStore.STRING, (String) i.next()));

+		}

+		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(

+				OverlayPreferenceStore.BOOLEAN, ENABLED_COLOR));

+		OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys

+				.size()];

+		overlayKeys.toArray(keys);

+		return keys;

+	}

+

+	/**

+	 * Creates the List viewer where we see the various syntax element display

+	 * names--would it ever be a Tree like JDT's?

+	 * 

+	 * @param parent

+	 * @return

+	 */

+	private StructuredViewer createStylesViewer(Composite parent) {

+		StructuredViewer stylesViewer = new ListViewer(parent, SWT.SINGLE

+				| SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);

+		stylesViewer

+				.setComparator(new ViewerComparator(Collator.getInstance()));

+		stylesViewer.setLabelProvider(new LabelProvider() {

+			public String getText(Object element) {

+				Object description = fStyleToDescriptionMap.get(element);

+				if (description != null)

+					return description.toString();

+				return super.getText(element);

+			}

+		});

+		stylesViewer.setContentProvider(new ITreeContentProvider() {

+			public void dispose() {

+			}

+

+			public Object[] getChildren(Object parentElement) {

+				return getStylePreferenceKeys().toArray();

+			}

+

+			public Object[] getElements(Object inputElement) {

+				return getChildren(inputElement);

+			}

+

+			public Object getParent(Object element) {

+				return getStylePreferenceKeys();

+			}

+

+			public boolean hasChildren(Object element) {

+				return false;

+			}

+

+			public void inputChanged(Viewer viewer, Object oldInput,

+					Object newInput) {

+			}

+		});

+		return stylesViewer;

+	}

+

+	public void dispose() {

+		if (fOverlayStore != null) {

+			fOverlayStore.stop();

+		}

+		super.dispose();

+	}

+

+	protected IPreferenceStore doGetPreferenceStore() {

+		return XMLSearchEditorPlugin.getDefault().getPreferenceStore();

+	}

+

+	private TextAttribute getAttributeFor(String namedStyle) {

+		TextAttribute ta = new TextAttribute(fDefaultForeground,

+				fDefaultBackground, SWT.NORMAL);

+		IPreferenceStore colorPreferences = null;

+		if (namedStyle != null && fOverlayStore != null) {

+			if (TAG_REFERENCED_ATTRIBUTE_VALUE.equals(namedStyle)

+					|| XML_REFERENCED_CONTENT.equals(namedStyle)) {

+				colorPreferences = getOverlayStore();

+			} else {

+				colorPreferences = XMLUIPlugin.getDefault()

+						.getPreferenceStore();

+			}

+			// note: "namedStyle" *is* the preference key

+			String prefString = colorPreferences.getString(namedStyle);

+			String[] stylePrefs = ColorHelper

+					.unpackStylePreferences(prefString);

+			if (stylePrefs != null) {

+				RGB foreground = ColorHelper.toRGB(stylePrefs[0]);

+				RGB background = ColorHelper.toRGB(stylePrefs[1]);

+

+				int fontModifier = SWT.NORMAL;

+

+				if (stylePrefs.length > 2) {

+					boolean on = Boolean.valueOf(stylePrefs[2]).booleanValue();

+					if (on)

+						fontModifier = fontModifier | SWT.BOLD;

+				}

+				if (stylePrefs.length > 3) {

+					boolean on = Boolean.valueOf(stylePrefs[3]).booleanValue();

+					if (on)

+						fontModifier = fontModifier | SWT.ITALIC;

+				}

+				if (stylePrefs.length > 4) {

+					boolean on = Boolean.valueOf(stylePrefs[4]).booleanValue();

+					if (on)

+						fontModifier = fontModifier

+								| TextAttribute.STRIKETHROUGH;

+				}

+				if (stylePrefs.length > 5) {

+					boolean on = Boolean.valueOf(stylePrefs[5]).booleanValue();

+					if (on)

+						fontModifier = fontModifier | TextAttribute.UNDERLINE;

+				}

+

+				ta = new TextAttribute((foreground != null) ? EditorUtility

+						.getColor(foreground) : null,

+						(background != null) ? EditorUtility

+								.getColor(background) : null, fontModifier);

+			}

+		}

+		return ta;

+	}

+

+	private String getExampleText() {

+		return Messages.Sample_XML_doc;

+	}

+

+	private String getNamedStyleAtOffset(int offset) {

+		IndexedRegion indexedRegion = model.getIndexedRegion(offset);

+		if (indexedRegion instanceof IDOMAttr) {

+			IDOMAttr attr = (IDOMAttr) indexedRegion;

+			if (attr.getName().startsWith("ref")) {

+				return TAG_REFERENCED_ATTRIBUTE_VALUE;

+			}

+		} else if (indexedRegion instanceof IDOMText) {

+			IDOMText text = (IDOMText) indexedRegion;

+			Node parent = text.getParentNode();

+			if (parent.getNodeName().startsWith("ref")) {

+				return XML_REFERENCED_CONTENT;

+			}

+		}

+		// ensure the offset is clean

+		if (offset >= fDocument.getLength())

+			return getNamedStyleAtOffset(fDocument.getLength() - 1);

+		else if (offset < 0)

+			return getNamedStyleAtOffset(0);

+		IStructuredDocumentRegion documentRegion = fDocument

+				.getFirstStructuredDocumentRegion();

+		while (documentRegion != null && !documentRegion.containsOffset(offset)) {

+			documentRegion = documentRegion.getNext();

+		}

+		if (documentRegion != null) {

+			// find the ITextRegion's Context at this offset

+			ITextRegion interest = documentRegion

+					.getRegionAtCharacterOffset(offset);

+			if (interest == null)

+				return null;

+			if (offset > documentRegion.getTextEndOffset(interest))

+				return null;

+			String regionContext = interest.getType();

+			if (regionContext == null)

+				return null;

+			// find the named style (internal/selectable name) for that

+			// context

+			String namedStyle = (String) fContextToStyleMap.get(regionContext);

+			if (namedStyle != null) {

+				return namedStyle;

+			}

+		}

+		return null;

+	}

+

+	private OverlayPreferenceStore getOverlayStore() {

+		return fOverlayStore;

+	}

+

+	private Collection getStylePreferenceKeys() {

+		if (fStylePreferenceKeys == null) {

+			List styles = new ArrayList();

+			styles.add(TAG_REFERENCED_ATTRIBUTE_VALUE);

+			styles.add(XML_REFERENCED_CONTENT);

+			fStylePreferenceKeys = styles;

+		}

+		return fStylePreferenceKeys;

+	}

+

+	private KeyListener getTextKeyListener() {

+		return new KeyListener() {

+			public void keyPressed(KeyEvent e) {

+				if (e.widget instanceof StyledText) {

+					int x = ((StyledText) e.widget).getCaretOffset();

+					selectColorAtOffset(x);

+				}

+			}

+

+			public void keyReleased(KeyEvent e) {

+				if (e.widget instanceof StyledText) {

+					int x = ((StyledText) e.widget).getCaretOffset();

+					selectColorAtOffset(x);

+				}

+			}

+		};

+	}

+

+	private MouseListener getTextMouseListener() {

+		return new MouseListener() {

+			public void mouseDoubleClick(MouseEvent e) {

+			}

+

+			public void mouseDown(MouseEvent e) {

+			}

+

+			public void mouseUp(MouseEvent e) {

+				if (e.widget instanceof StyledText) {

+					int x = ((StyledText) e.widget).getCaretOffset();

+					selectColorAtOffset(x);

+				}

+			}

+		};

+	}

+

+	private SelectionListener getTextSelectionListener() {

+		return new SelectionListener() {

+			public void widgetDefaultSelected(SelectionEvent e) {

+				selectColorAtOffset(e.x);

+				if (e.widget instanceof StyledText) {

+					((StyledText) e.widget).setSelection(e.x);

+				}

+			}

+

+			public void widgetSelected(SelectionEvent e) {

+				selectColorAtOffset(e.x);

+				if (e.widget instanceof StyledText) {

+					((StyledText) e.widget).setSelection(e.x);

+				}

+			}

+		};

+	}

+

+	private TraverseListener getTraverseListener() {

+		return new TraverseListener() {

+			/**

+			 * @see org.eclipse.swt.events.TraverseListener#keyTraversed(TraverseEvent)

+			 */

+			public void keyTraversed(TraverseEvent e) {

+				if (e.widget instanceof StyledText) {

+					if ((e.detail == SWT.TRAVERSE_TAB_NEXT)

+							|| (e.detail == SWT.TRAVERSE_TAB_PREVIOUS))

+						e.doit = true;

+				}

+			}

+		};

+	}

+

+	public void init(IWorkbench workbench) {

+		setDescription(SSEUIMessages.SyntaxColoring_Description);

+

+		fStyleToDescriptionMap = new HashMap();

+		fContextToStyleMap = new HashMap();

+

+		initStyleToDescriptionMap();

+		initRegionContextToStyleMap();

+

+		fOverlayStore = new OverlayPreferenceStore(getPreferenceStore(),

+				createOverlayStoreKeys());

+		fOverlayStore.load();

+		fOverlayStore.start();

+	}

+

+	private void initRegionContextToStyleMap() {

+		fContextToStyleMap.put(DOMRegionContext.XML_COMMENT_OPEN,

+				IStyleConstantsXML.COMMENT_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_COMMENT_TEXT,

+				IStyleConstantsXML.COMMENT_TEXT);

+		fContextToStyleMap.put(DOMRegionContext.XML_COMMENT_CLOSE,

+				IStyleConstantsXML.COMMENT_BORDER);

+

+		fContextToStyleMap.put(DOMRegionContext.XML_TAG_OPEN,

+				IStyleConstantsXML.TAG_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_END_TAG_OPEN,

+				IStyleConstantsXML.TAG_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_TAG_NAME,

+				IStyleConstantsXML.TAG_NAME);

+		fContextToStyleMap.put(DOMRegionContext.XML_TAG_ATTRIBUTE_NAME,

+				IStyleConstantsXML.TAG_ATTRIBUTE_NAME);

+		fContextToStyleMap.put(DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE,

+				IStyleConstantsXML.TAG_ATTRIBUTE_VALUE);

+		fContextToStyleMap.put(DOMRegionContext.XML_TAG_CLOSE,

+				IStyleConstantsXML.TAG_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_EMPTY_TAG_CLOSE,

+				IStyleConstantsXML.TAG_BORDER);

+

+		fContextToStyleMap.put(DOMRegionContext.XML_DECLARATION_OPEN,

+				IStyleConstantsXML.DECL_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_DECLARATION_CLOSE,

+				IStyleConstantsXML.DECL_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_ELEMENT_DECLARATION,

+				IStyleConstantsXML.DECL_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_ELEMENT_DECL_CLOSE,

+				IStyleConstantsXML.DECL_BORDER);

+

+		fContextToStyleMap.put(DOMRegionContext.XML_CONTENT,

+				IStyleConstantsXML.XML_CONTENT);

+		fContextToStyleMap.put(DOMRegionContext.XML_CDATA_OPEN,

+				IStyleConstantsXML.CDATA_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_CDATA_TEXT,

+				IStyleConstantsXML.CDATA_TEXT);

+		fContextToStyleMap.put(DOMRegionContext.XML_CDATA_CLOSE,

+				IStyleConstantsXML.CDATA_BORDER);

+

+		fContextToStyleMap.put(DOMRegionContext.XML_PI_OPEN,

+				IStyleConstantsXML.PI_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_PI_CONTENT,

+				IStyleConstantsXML.PI_CONTENT);

+		fContextToStyleMap.put(DOMRegionContext.XML_PI_CLOSE,

+				IStyleConstantsXML.PI_BORDER);

+		fContextToStyleMap.put(DOMRegionContext.XML_ELEMENT_DECL_NAME,

+				IStyleConstantsXML.DOCTYPE_NAME);

+		fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_DECLARATION,

+				IStyleConstantsXML.TAG_NAME);

+		fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_DECLARATION_CLOSE,

+				IStyleConstantsXML.DECL_BORDER);

+

+		fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_NAME,

+				IStyleConstantsXML.DOCTYPE_NAME);

+		fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_EXTERNAL_ID_PUBLIC,

+				IStyleConstantsXML.DOCTYPE_EXTERNAL_ID);

+		fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_EXTERNAL_ID_PUBREF,

+				IStyleConstantsXML.DOCTYPE_EXTERNAL_ID_PUBREF);

+		fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_EXTERNAL_ID_SYSTEM,

+				IStyleConstantsXML.DOCTYPE_EXTERNAL_ID);

+		fContextToStyleMap.put(DOMRegionContext.XML_DOCTYPE_EXTERNAL_ID_SYSREF,

+				IStyleConstantsXML.DOCTYPE_EXTERNAL_ID_SYSREF);

+

+		fContextToStyleMap.put(DOMRegionContext.XML_CHAR_REFERENCE,

+				IStyleConstantsXML.ENTITY_REFERENCE);

+		fContextToStyleMap.put(DOMRegionContext.XML_ENTITY_REFERENCE,

+				IStyleConstantsXML.ENTITY_REFERENCE);

+		fContextToStyleMap.put(DOMRegionContext.XML_PE_REFERENCE,

+				IStyleConstantsXML.ENTITY_REFERENCE);

+	}

+

+	private void initStyleToDescriptionMap() {

+		fStyleToDescriptionMap.put(IStyleConstantsXML.CDATA_BORDER,

+				XMLUIMessages.CDATA_Delimiters_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.CDATA_TEXT,

+				XMLUIMessages.CDATA_Content_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.PI_BORDER,

+				XMLUIMessages.Processing_Instruction_Del_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.PI_CONTENT,

+				XMLUIMessages.Processing_Instruction_Con_UI__UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.COMMENT_BORDER,

+				XMLUIMessages.Comment_Delimiters_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.COMMENT_TEXT,

+				XMLUIMessages.Comment_Content_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.TAG_BORDER,

+				XMLUIMessages.Tag_Delimiters_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.TAG_NAME,

+				XMLUIMessages.Tag_Names_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.TAG_ATTRIBUTE_NAME,

+				XMLUIMessages.Attribute_Names_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.TAG_ATTRIBUTE_VALUE,

+				XMLUIMessages.Attribute_Values_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.DECL_BORDER,

+				XMLUIMessages.Declaration_Delimiters_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.XML_CONTENT,

+				XMLUIMessages.Content_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.DOCTYPE_NAME,

+				XMLUIMessages.DOCTYPE_Name_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.DOCTYPE_EXTERNAL_ID,

+				XMLUIMessages.DOCTYPE_SYSTEM_PUBLIC_Keyw_UI_);

+		fStyleToDescriptionMap.put(

+				IStyleConstantsXML.DOCTYPE_EXTERNAL_ID_PUBREF,

+				XMLUIMessages.DOCTYPE_Public_Reference_UI_);

+		fStyleToDescriptionMap.put(

+				IStyleConstantsXML.DOCTYPE_EXTERNAL_ID_SYSREF,

+				XMLUIMessages.DOCTYPE_System_Reference_UI_);

+		fStyleToDescriptionMap.put(IStyleConstantsXML.ENTITY_REFERENCE,

+				XMLUIMessages.Entity_Reference_UI_);

+

+		fStyleToDescriptionMap.put(TAG_REFERENCED_ATTRIBUTE_VALUE,

+				Messages.Referenced_Attribute_Values_UI_);

+		fStyleToDescriptionMap.put(XML_REFERENCED_CONTENT,

+				Messages.Referenced_Content_UI_);

+	}

+

+	protected void performDefaults() {

+		super.performDefaults();

+		getOverlayStore().loadDefaults();

+		fColorReferencedEnabled.setSelection(getOverlayStore().getBoolean(ENABLED_COLOR));

+		updateEnabled();

+		applyStyles();

+		fStylesViewer.setSelection(StructuredSelection.EMPTY);

+		activate(null);

+		fText.redraw();

+	}

+

+	public boolean performOk() {

+		getOverlayStore().propagate();

+		XMLSearchEditorPlugin.getDefault().savePluginPreferences();

+		SSEUIPlugin.getDefault().savePluginPreferences();

+		return true;

+	}

+

+	private void selectColorAtOffset(int offset) {

+		String namedStyle = getNamedStyleAtOffset(offset);

+		if (namedStyle != null) {

+			fStylesViewer.setSelection(new StructuredSelection(namedStyle));

+			fStylesViewer.reveal(namedStyle);

+		} else {

+			fStylesViewer.setSelection(StructuredSelection.EMPTY);

+		}

+		activate(namedStyle);

+	}

+

+	/**

+	 * Specifically set the reporting name of a control for accessibility

+	 */

+	private void setAccessible(Control control, String name) {

+		if (control == null)

+			return;

+		final String n = name;

+		control.getAccessible().addAccessibleListener(new AccessibleAdapter() {

+			public void getName(AccessibleEvent e) {

+				if (e.childID == ACC.CHILDID_SELF)

+					e.result = n;

+			}

+		});

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSearchEditorPreferenceInitializer.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSearchEditorPreferenceInitializer.java
new file mode 100644
index 0000000..b6de33c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSearchEditorPreferenceInitializer.java
@@ -0,0 +1,50 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.preferences;

+

+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;

+import org.eclipse.jface.preference.IPreferenceStore;

+import org.eclipse.jface.resource.ColorRegistry;

+import org.eclipse.ui.PlatformUI;

+import org.eclipse.wst.sse.ui.internal.preferences.ui.ColorHelper;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.internal.style.IReferencesStyleConstantsXML;

+

+public class XMLSearchEditorPreferenceInitializer extends

+		AbstractPreferenceInitializer implements IReferencesStyleConstantsXML {

+

+	@Override

+	public void initializeDefaultPreferences() {

+		IPreferenceStore store = XMLSearchEditorPlugin.getDefault()

+				.getPreferenceStore();

+		ColorRegistry registry = PlatformUI.getWorkbench().getThemeManager()

+				.getCurrentTheme().getColorRegistry();

+

+		// tagReferencedAttributeValue

+		String BOLD_AND_ITALIC = " | null | true | true"; //$NON-NLS-1$

+		String styleValue = ColorHelper.findRGBString(registry,

+				TAG_REFERENCED_ATTRIBUTE_VALUE,

+				42, 0, 255)

+				+ BOLD_AND_ITALIC;

+		store.setDefault(

+				TAG_REFERENCED_ATTRIBUTE_VALUE,

+				styleValue);

+

+		// xmlReferencedContent

+		styleValue = "null | null | true | false";

+		store.setDefault(

+				IReferencesStyleConstantsXML.XML_REFERENCED_CONTENT,

+				styleValue);

+

+		// enabledColor 

+		store.setDefault(ENABLED_COLOR, true);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSourcePreferencePage.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSourcePreferencePage.java
new file mode 100644
index 0000000..43ac9da
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/preferences/XMLSourcePreferencePage.java
@@ -0,0 +1,45 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.preferences;

+

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Text;

+import org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractPreferencePage;

+import org.eclipse.wst.xml.search.editor.internal.Messages;

+

+

+@SuppressWarnings("restriction")

+public class XMLSourcePreferencePage extends AbstractPreferencePage {

+

+		/**

+		 * (non-Javadoc)

+		 * 

+		 * @see org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractPreferencePage#createContents(org.eclipse.swt.widgets.Composite)

+		 * @deprecated

+		 */

+		protected Control createContents(Composite parent) {

+			Composite composite = createScrolledComposite(parent);

+

+			String description = Messages.XMLSourcePreferencePage_0;

+			Text text = new Text(composite, SWT.READ_ONLY);

+			// some themes on GTK have different background colors for Text and

+			// Labels

+			text.setBackground(composite.getBackground());

+			text.setText(description);

+

+			setSize(composite);

+			return composite;

+		}

+

+	}

+

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/AbstractXMLReferenceTo.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/AbstractXMLReferenceTo.java
new file mode 100644
index 0000000..78c6f7f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/AbstractXMLReferenceTo.java
@@ -0,0 +1,54 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import org.eclipse.wst.xml.search.editor.references.IReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+

+public abstract class AbstractXMLReferenceTo implements IXMLReferenceTo {

+

+	private final String id;	

+	private final IXMLSearcher searcher;

+	private final IReference ownerReference;

+	private final String querySpecificationId;

+	private final String tokenId;

+	

+	public AbstractXMLReferenceTo(IReference ownerReference, String id,

+			IXMLSearcher searcher, String querySpecificationId, String tokenId) {

+		this.ownerReference = ownerReference;

+		this.querySpecificationId = querySpecificationId;

+		this.id = (id != null ? id : querySpecificationId);

+		this.searcher = searcher;

+		this.tokenId = tokenId;

+	}

+

+	public IReference getOwnerReference() {

+		return ownerReference;

+	}

+

+	public String getId() {

+		return id;

+	}

+

+	public String getQuerySpecificationId() {

+		return querySpecificationId;

+	}

+

+	public IXMLSearcher getSearcher() {

+		return searcher;

+	}

+	

+	public String getTokenId() {

+		return tokenId;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReference.java
new file mode 100644
index 0000000..0b6e253
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReference.java
@@ -0,0 +1,119 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.references.AbstractReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJava;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJavaMethod;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+

+public class XMLReference extends AbstractReference implements IXMLReference {

+

+	private final String[] contentTypeIds;

+	private final IXMLReferencePath from;

+	private final IXMLReferenceValidator validator;

+

+	public XMLReference(String fromPath, String fromTargetNodes,

+			Namespaces namespaces, String querySpecificationId,

+			String[] contentTypeIds, IXMLReferenceFilter filter,

+			IXMLReferenceValidator validator) {

+		this.from = createToXML(null, null, fromPath, fromTargetNodes,

+				namespaces, querySpecificationId, null, filter, null);

+		this.contentTypeIds = contentTypeIds;

+		this.validator = validator;

+	}

+

+	public IXMLReferencePath getFrom() {

+		return from;

+	}

+

+	public List<IXMLReferenceTo> getTo() {

+		return this;

+	}

+

+	public IXMLReference addTo(IXMLReferenceTo to) {

+		super.add(to);

+		return this;

+	}

+

+	public IXMLReferenceToResource createToResource(

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider) {

+		return new XMLReferenceToResource(this, id, searcher,

+				querySpecificationId, tokenId, additionalProposalInfoProvider);

+	}

+

+	public IXMLReferenceToJava createToJava(String id, IXMLSearcher searcher,

+			String querySpecificationId, String tokenId,

+			IJavaQuerySpecification querySpecification) {

+		return new XMLReferenceToJava(this, id, searcher, querySpecificationId,

+				querySpecification, tokenId);

+	}

+

+	public IXMLReferenceToJavaMethod createToJavaMethod(String id,

+			IXMLSearcher searcher, String querySpecificationId, String tokenId,

+			String pathForClass,

+			IJavaMethodQuerySpecification querySpecification) {

+		return new XMLReferenceToJavaMethod(this, id, searcher,

+				querySpecificationId, pathForClass, querySpecification, tokenId);

+	}

+

+	public IXMLReferenceToStatic createToStatic(

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {

+		return new XMLReferenceToStatic(this, id, searcher,

+				querySpecificationId, tokenId, additionalProposalInfoProvider);

+	}

+

+	public IXMLReferenceToProperty createToProperty(

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {

+		return new XMLReferenceToProperty(this, id, searcher,

+				querySpecificationId, tokenId, additionalProposalInfoProvider);

+	}

+

+	public String[] getContentTypeIds() {

+		return contentTypeIds;

+	}

+

+	public IXMLReferenceValidator getValidator() {

+		return validator;

+	}

+

+	public boolean isExpression() {

+		return false;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceContainer.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceContainer.java
new file mode 100644
index 0000000..c3387f5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceContainer.java
@@ -0,0 +1,303 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager.Direction;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Node;

+

+public class XMLReferenceContainer {

+

+	private static final String TEXT_KEY = "text()";

+	private final String contentTypeId;

+	private final Collection<IXMLReference> allReferences;

+	private final Map<String, Collection<IXMLReferencePath>> referencesById;

+	private final Map<String, Collection<IXMLReference>> fromReferencesByTargetNode;

+	private Map<String, Collection<IXMLReference>> fromReferencesWithFilterByTargetNode;

+	private final Map<String, Collection<IXMLReference>> toReferencesByTargetNode;

+

+	public XMLReferenceContainer(String contentTypeId) {

+		this.contentTypeId = contentTypeId;

+		this.allReferences = new ArrayList<IXMLReference>();

+		this.referencesById = new HashMap<String, Collection<IXMLReferencePath>>();

+		this.fromReferencesByTargetNode = new HashMap<String, Collection<IXMLReference>>();

+		this.fromReferencesWithFilterByTargetNode = null;

+		this.toReferencesByTargetNode = new HashMap<String, Collection<IXMLReference>>();

+	}

+

+	public Collection<IXMLReference> getAllXMLReferences() {

+		return allReferences;

+	}

+

+	public Collection<IXMLReference> getXMLReferences(Node node,

+			Direction direction) {

+		short nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			String attrName = ((Attr) node).getName();

+			// attrName can be have value "id" or "wicket:id".

+			// For the second case, if prefix is linked to a DTD or XML Schema,

+			// the prefix must be removed.

+			//if (node.getNamespaceURI() != null) {

+				// Node has namespace (ex : wicket:id where wicket prefix is

+				// linked to the DTD , XML Schema of wicket).

+				// Remove the prefix

+				int indexPrefix = attrName.indexOf(":");

+				if (indexPrefix != -1) {

+					attrName = attrName.substring(indexPrefix + 1,

+							attrName.length());

+				}

+			//}

+			String key = getKey(attrName, null, node.getNamespaceURI());

+			return getXMLReferences(node, key, direction);

+		case Node.ELEMENT_NODE:

+		case Node.TEXT_NODE:

+			return getXMLReferences(node, TEXT_KEY, direction);

+		}

+		return null;

+	}

+

+	private Collection<IXMLReference> getXMLReferences(Node node,

+			String nodeName, Direction direction) {

+		if (nodeName == null) {

+			return null;

+		}

+		if (direction == Direction.TO)

+			return toReferencesByTargetNode.get(nodeName);

+		if (fromReferencesWithFilterByTargetNode == null) {

+			return fromReferencesByTargetNode.get(nodeName);

+		}

+		Collection<IXMLReference> allReferences = new ArrayList<IXMLReference>(

+				fromReferencesByTargetNode.size());

+		fromReferencesByTargetNode.get(nodeName);

+		Collection<IXMLReference> noFfilteredReferences = fromReferencesByTargetNode

+				.get(nodeName);

+		if (noFfilteredReferences != null) {

+			allReferences.addAll(noFfilteredReferences);

+		}

+		Collection<IXMLReference> filteredReferences = fromReferencesWithFilterByTargetNode

+				.get(nodeName);

+		if (filteredReferences != null) {

+			for (IXMLReference reference : filteredReferences) {

+				if (reference.getFrom().getFilter().accept(node)) {

+					allReferences.add(reference);

+				}

+			}

+		}

+		return allReferences;

+	}

+

+	public Collection<IXMLReferencePath> getXMLReferencesByPathTo(String path) {

+		return referencesById.get(path);

+	}

+

+	public String getContentTypeId() {

+		return contentTypeId;

+	}

+

+	public void addReference(IXMLReference reference) {

+		// cache XML reference

+		allReferences.add(reference);

+		// cache "From" reference

+		IXMLReferenceFilter filter = reference.getFrom().getFilter();

+		if (filter != null) {

+			if (fromReferencesWithFilterByTargetNode == null) {

+				fromReferencesWithFilterByTargetNode = new HashMap<String, Collection<IXMLReference>>();

+			}

+			register(reference, reference.getFrom(),

+					fromReferencesWithFilterByTargetNode);

+		} else {

+			register(reference, reference.getFrom(), fromReferencesByTargetNode);

+		}

+		// cache "To" reference

+		Collection<IXMLReferenceTo> to = reference.getTo();

+		for (IXMLReferenceTo referenceTo : to) {

+			register(reference, referenceTo, toReferencesByTargetNode);

+

+			if (referenceTo.getType() == ToType.XML) {

+				IXMLReferencePath referencePath = (IXMLReferencePath) referenceTo;

+				Collection<IXMLReferencePath> refTo = referencesById

+						.get(referencePath.getKeyPath());

+				if (refTo == null) {

+					refTo = new ArrayList<IXMLReferencePath>();

+					referencesById.put(referencePath.getKeyPath(), refTo);

+				}

+				refTo.add(reference.getFrom());

+			}

+		}

+	}

+

+	private void register(IXMLReference reference, IXMLReferenceTo referenceTo,

+			Map<String, Collection<IXMLReference>> references) {

+		if (referenceTo.getType() != ToType.XML)

+			return;

+

+		IXMLReferencePath path = (IXMLReferencePath) referenceTo;

+		// Namespaces namespaces = path.getNamespaces();

+		String[] targetNodes = path.getTargetNodes();

+		String targetNode = null;

+		for (int i = 0; i < targetNodes.length; i++) {

+			targetNode = targetNodes[i];

+			if (targetNode.startsWith("@")) {

+				targetNode = targetNode.substring(1, targetNode.length());

+			}

+			int index = targetNode.indexOf(":");

+			if (index != -1) {

+				targetNode = targetNode.substring(index+1, targetNode.length());

+			}

+			Collection<IXMLReference> referencesByTargetNode = references

+					.get(targetNode);

+			if (referencesByTargetNode == null) {

+				referencesByTargetNode = new ArrayList<IXMLReference>();

+

+				references.put(targetNode, referencesByTargetNode);

+

+				// if (namespaces != null) {

+				//

+				//

+				//

+				// // List<String> prefixs = namespaces.getPrefixs();

+				// // for (String prefix : prefixs) {

+				// // references.put(getKey(targetNode, prefix, null),

+				// // referencesByTargetNode);

+				// // }

+				// // List<String> uris = namespaces.getURIs();

+				// // for (String uri : uris) {

+				// // references.put(getKey(targetNode, null, uri),

+				// // referencesByTargetNode);

+				// // }

+				// } else {

+				// references.put(targetNode, referencesByTargetNode);

+				// }

+			}

+			referencesByTargetNode.add(reference);

+		}

+	}

+

+	public Collection<IXMLReference> getAllReferencesWithOneReferenceTo(

+			ToType toType) {

+		Collection<IXMLReference> allTo = new ArrayList<IXMLReference>();

+		Collection<Collection<IXMLReference>> allreferences = fromReferencesByTargetNode

+				.values();

+		for (Collection<IXMLReference> collection : allreferences) {

+			for (IXMLReference reference : collection) {

+				if (hasReferenceTo(reference, toType)) {

+					allTo.add(reference);

+				}

+			}

+		}

+		if (fromReferencesWithFilterByTargetNode != null) {

+			allreferences = fromReferencesWithFilterByTargetNode.values();

+			for (Collection<IXMLReference> collection : allreferences) {

+				for (IXMLReference reference : collection) {

+					if (hasReferenceTo(reference, toType)) {

+						allTo.add(reference);

+					}

+				}

+			}

+		}

+		return allTo;

+	}

+

+	private boolean hasReferenceTo(IXMLReference reference, ToType toType) {

+		List<IXMLReferenceTo> to = reference.getTo();

+		for (IXMLReferenceTo referenceTo : to) {

+			if (toType == referenceTo.getType()) {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	public Collection<String> getContentTypeIdsForToType(ToType toType) {

+		Collection<String> contentTypeIds = new ArrayList<String>();

+		Collection<Collection<IXMLReference>> allReferences = fromReferencesByTargetNode

+				.values();

+		getContentTypeIdsForToType(toType, contentTypeIds, allReferences);

+		if (fromReferencesWithFilterByTargetNode != null) {

+			allReferences = fromReferencesWithFilterByTargetNode.values();

+			getContentTypeIdsForToType(toType, contentTypeIds, allReferences);

+		}

+		return contentTypeIds;

+	}

+

+	private void getContentTypeIdsForToType(ToType toType,

+			Collection<String> contentTypeIds,

+			Collection<Collection<IXMLReference>> allReferences) {

+		for (Collection<IXMLReference> references : allReferences) {

+			for (IXMLReference reference : references) {

+				if (hasReferenceTo(reference, toType)) {

+					String contentTypeId = null;

+					for (int i = 0; i < reference.getContentTypeIds().length; i++) {

+						contentTypeId = reference.getContentTypeIds()[i];

+						if (contentTypeIds.contains(contentTypeId)) {

+							contentTypeIds.add(contentTypeId);

+						}

+					}

+				}

+			}

+		}

+	}

+

+	public Collection<IXMLReference> getXMLReferencesForToType(ToType toType) {

+		Collection<IXMLReference> referencesForToType = new ArrayList<IXMLReference>();

+		Collection<Collection<IXMLReference>> allReferences = fromReferencesByTargetNode

+				.values();

+		getXMLReferencesForToType(toType, referencesForToType, allReferences);

+		if (fromReferencesWithFilterByTargetNode != null) {

+			allReferences = fromReferencesWithFilterByTargetNode.values();

+			getXMLReferencesForToType(toType, referencesForToType,

+					allReferences);

+		}

+		return referencesForToType;

+	}

+

+	private void getXMLReferencesForToType(ToType toType,

+			Collection<IXMLReference> referencesForToType,

+			Collection<Collection<IXMLReference>> allReferences) {

+		for (Collection<IXMLReference> references : allReferences) {

+			for (IXMLReference reference : references) {

+				if (hasReferenceTo(reference, toType)) {

+					referencesForToType.add(reference);

+				}

+			}

+		}

+	}

+

+	private String getKey(String nodeName, String prefix, String namespaceURI) {

+		if (prefix == null && namespaceURI == null) {

+			return nodeName;

+		}

+//		StringBuilder key = new StringBuilder();

+//		if (prefix != null) {

+//			key.append(prefix);

+//			key.append(":");

+//		} else {

+//			key.append(namespaceURI);

+//			key.append("#");

+//		}

+//		key.append(nodeName);

+//		return key.toString();

+		return nodeName;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePath.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePath.java
new file mode 100644
index 0000000..5ee7488
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePath.java
@@ -0,0 +1,201 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.EqualsStringQueryBuilder;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.eclipse.wst.xml.search.core.xpath.matcher.XPathMatcher;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.references.IReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToXML;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.w3c.dom.Node;

+

+public class XMLReferencePath extends AbstractXMLReferenceTo implements

+		IXMLReferenceToXML {

+

+	public static final int FROM_PATH_INDEX = -9999999;

+

+	private final String path;

+	private final String[] targetNodes;

+	private final XPathMatcher matcher;

+	private final String keyPath;

+	private final IXMLReferenceFilter filter;

+	private final IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider;

+	private final Namespaces namespaces;

+

+	private Map<String, String> builtPaths = new HashMap<String, String>();

+	private int nbWildCard;

+

+	public XMLReferencePath(

+			IReference ownerReference,

+			String id,

+			IXMLSearcher searcher,

+			String path,

+			String[] targetNodes,

+			Namespaces namespaces,

+			String querySpecificationId,

+			String tokenId,

+			IXMLReferenceFilter filter,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {

+		super(ownerReference, id, searcher, querySpecificationId, tokenId);

+		this.targetNodes = targetNodes;

+		this.namespaces = namespaces;

+		this.matcher = new XPathMatcher(path);

+		this.nbWildCard = matcher.getNbWildCard();

+		this.keyPath = computeKeyPath(path, targetNodes);

+		this.path = computeXPathWithWildcard(path);

+		this.filter = filter;

+		this.additionalProposalInfoProvider = additionalProposalInfoProvider;

+	}

+

+	private String computeXPathWithWildcard(String path) {

+		if (nbWildCard == -1)

+			return path;

+		for (int i = 0; i < nbWildCard + 1; i++) {

+			path = path.replaceAll("\\$" + i + "", "{" + i + "}");

+		}

+		return path;

+	}

+

+	public String getPath() {

+		return path;

+	}

+

+	public String[] getTargetNodes() {

+		return targetNodes;

+	}

+

+	public boolean match(final Node node) {

+		return matcher.match(node);

+	}

+

+	private String getXPathFromCache(IStringQueryBuilder builder,

+			Object selectedNode) {

+		if (builder == null) {

+			builder = EqualsStringQueryBuilder.INSTANCE;

+		}

+		if (builder.getId() == null) {

+			return createXPath(builder, selectedNode);

+		}

+		// boolean withWildcard = nbWildCard > 0;

+		String id = builder.getId() + "_" + nbWildCard;

+		String xpath = builtPaths.get(id);

+		if (xpath == null) {

+			xpath = createXPath(builder, selectedNode);

+			builtPaths.put(id, xpath);

+		}

+		return xpath;

+	}

+

+	private String createXPath(IStringQueryBuilder builder, Object selectedNode) {

+		String xpath;

+		String p = path;// (withWildcard ? path : pathWithoutWildcard);

+		int index = nbWildCard + 1;

+		xpath = builder.build(p, targetNodes, index, selectedNode);

+		return xpath;

+	}

+

+	public ToType getType() {

+		return ToType.XML;

+	}

+

+	public String getKeyPath() {

+		return keyPath;

+	}

+

+	private String computeKeyPath(String path, String[] targetNodes) {

+		StringBuilder result = new StringBuilder(path);

+		for (String targetNode : targetNodes) {

+			result.append("_");

+			result.append(targetNode);

+		}

+		return result.toString();

+	}

+

+	public String getQuery(Object selectedNode, String mathingString,

+			IStringQueryBuilder builder) {

+		return getQuery(selectedNode, mathingString, builder, true);

+	}

+

+	public String getQuery(Object selectedNode, String mathingString,

+			IStringQueryBuilder builder, boolean reversed) {

+		// Get Xpath with wildcard

+		String xpath = getXPathFromCache(builder, selectedNode);

+

+		// get values

+		Collection<String> values = null;

+		if (hasWildCard()) {

+			// Get values of XPath

+			IXMLReferencePath from = ((IXMLReference) getOwnerReference())

+					.getFrom();

+			if (!reversed) {

+				List<IXMLReferenceTo> to = getOwnerReference().getTo();

+				for (IXMLReferenceTo referenceTo : to) {

+					if (referenceTo.getType() == ToType.XML) {

+						values = ((IXMLReferenceToXML) referenceTo)

+								.getWildcardValues(selectedNode);

+					}

+				}

+			} else {

+				values = from.getWildcardValues(selectedNode);

+			}

+		} else {

+			values = new ArrayList<String>();

+		}

+		if (mathingString != null) {

+			values.add(mathingString);

+		} else {

+			if (selectedNode instanceof Node) {

+				values.add(DOMUtils.getNodeValue((Node) selectedNode));

+			}

+		}

+		return XPathManager.getManager().getXPath(xpath,

+				values.toArray(StringUtils.EMPTY_ARRAY));

+	}

+

+	public List<String> getWildcardValues(Object selectedNode) {

+		if (selectedNode instanceof Node) {

+			return matcher.getWildcardValues((Node) selectedNode);

+		}

+		return null;

+	}

+

+	public IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider() {

+		return additionalProposalInfoProvider;

+	}

+

+	public IXMLReferenceFilter getFilter() {

+		return filter;

+	}

+

+	public boolean hasWildCard() {

+		return nbWildCard != -1;

+	}

+

+	public Namespaces getNamespaces() {

+		return namespaces;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePathFactory.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePathFactory.java
new file mode 100644
index 0000000..a5007f7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencePathFactory.java
@@ -0,0 +1,272 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.namespaces.NamespacesManager;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.contentassist.DefaultDOMContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.PropertyContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.ResourceContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.internal.contentassist.ContentAssistsManager;

+import org.eclipse.wst.xml.search.editor.internal.references.filters.XMLReferenceFiltersManager;

+import org.eclipse.wst.xml.search.editor.internal.searchers.java.JavaQuerySpecification;

+import org.eclipse.wst.xml.search.editor.internal.searchers.java.JavaQuerySpecificationrManager;

+import org.eclipse.wst.xml.search.editor.internal.searchers.javamethod.JavaMethodQuerySpecification;

+import org.eclipse.wst.xml.search.editor.internal.searchers.javamethod.JavaMethodQuerySpecificationrManager;

+import org.eclipse.wst.xml.search.editor.references.IReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.XMLSearcherManager;

+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;

+import org.eclipse.wst.xml.search.editor.searchers.java.DefaultExtendedClassProvider;

+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+import org.eclipse.wst.xml.search.editor.searchers.properties.PropertyInfo;

+import org.w3c.dom.Node;

+

+public class XMLReferencePathFactory {

+

+	private static final String ADDITIONAL_PROPOSAL_INFO_PROVIDER_ID_ATTR = "additionalProposalInfoProviderId";

+	// Default searcher ID

+	private static final String DEFAULT_SEARCHER_FOR_STATICS = "org.eclipse.wst.xml.search.editor.searcher.statics";

+	private static final String DEFAULT_SEARCHER_FOR_JAVAMETHOD = "org.eclipse.wst.xml.search.editor.searcher.javamethod";

+	private static final String DEFAULT_SEARCHER_FOR_JAVA = "org.eclipse.wst.xml.search.editor.searcher.java";

+	private static final String DEFAULT_SEARCHER_FOR_FILE = "org.eclipse.wst.xml.search.editor.searcher.resource";

+	private static final String DEFAULT_SEARCHER_FOR_PROPERTIES = "org.eclipse.wst.xml.search.editor.searcher.properties";;

+	private static final String DEFAULT_SEARCHER_FOR_XML = "org.eclipse.wst.xml.search.editor.searcher.xml";

+

+	public static XMLReferencePathFactory INSTANCE = new XMLReferencePathFactory();

+	public static final String CONTENT_TYPE_IDS_ATTR = "contentTypeIds";

+

+	// Global attributes for to*

+	private static final String ID_ATTR = "id";

+	private static final String QUERY_SPECIFICATION_ID_ATTR = "querySpecificationId";

+	private static final String TOKEN_ID_ATTR = "tokenId";

+	private static final String SEARCHER_ID_ATTR = "searcherId";

+	private static final String FILTER_ID_ATTR = "filterId";

+

+	// toResource

+	private static final String TO_RESOURCE_ELT = "toResource";

+

+	// toJava

+	private static final String TO_JAVA_ELT = "toJava";

+

+	// toJavaMethod

+	private static final String TO_JAVA_METHOD_ELT = "toJavaMethod";

+	private static final String PATH_FOR_CLASS_ATTR = "pathForClass";

+

+	// toProperty

+	private static final String TO_PROPERTY_ELT = "toProperty";

+

+	// toStatic

+	private static final String TO_STATIC_ELT = "toStatic";

+

+	// to

+	private static final String TO_ELT = "to";

+	private static final String PATH_ATTR = "path";

+	private static final String TARGET_NODES_ATTR = "targetNodes";

+	private static final String NAMESPACE_ID_ATTR = "namespacesId";

+

+	public IXMLReference createReference(IConfigurationElement element,

+			String[] defaultContentTypeIds, IXMLReferenceValidator validator,

+			IXMLExpressionParser parser, IXMLSearcher expressionSearcher) {

+		String[] contentTypeIds = defaultContentTypeIds;

+		String ids = element.getAttribute(CONTENT_TYPE_IDS_ATTR);

+		if (!StringUtils.isEmpty(ids)) {

+			contentTypeIds = ids.split(",");

+		}

+		String fromPath = element.getAttribute(PATH_ATTR);

+		String fromTargetNodes = element.getAttribute(TARGET_NODES_ATTR);

+		String fromQuerySpecificationId = element

+				.getAttribute(QUERY_SPECIFICATION_ID_ATTR);

+		IXMLReferenceFilter filter = getFilter(element);

+		Namespaces namespaces = getNamespaces(element);

+		if (parser != null) {

+			return XMLReferencesUtil.createXMLReferenceToExpression(fromPath,

+					fromTargetNodes, namespaces, fromQuerySpecificationId,

+					contentTypeIds, filter, validator, parser,

+					expressionSearcher);

+		}

+		return XMLReferencesUtil.createXMLReference(fromPath, fromTargetNodes,

+				namespaces, fromQuerySpecificationId, contentTypeIds, filter,

+				validator);

+	}

+

+	public IXMLReferenceTo createTo(IConfigurationElement element,

+			IReference reference) {

+		if (reference == null) {

+			return null;

+		}

+		String id = element.getAttribute(ID_ATTR);

+		String toQuerySpecificationId = element

+				.getAttribute(QUERY_SPECIFICATION_ID_ATTR);

+		String tokenId = element.getAttribute(TOKEN_ID_ATTR);

+		if (TO_ELT.equals(element.getName())) {

+			// XML reference path

+			IXMLSearcher searcher = getSearcher(element,

+					DEFAULT_SEARCHER_FOR_XML);

+			if (searcher == null) {

+				return null;

+			}

+			Namespaces namespaces = getNamespaces(element);

+

+			IContentAssistAdditionalProposalInfoProvider<Node> additionalProposalInfoProvider = getAdditionalProposalInfoProvider(element);

+			if (additionalProposalInfoProvider == null) {

+				additionalProposalInfoProvider = DefaultDOMContentAssistAdditionalProposalInfoProvider.INSTANCE;

+			}

+			String toPath = element.getAttribute(PATH_ATTR);

+			String toTargetNodes = element.getAttribute(TARGET_NODES_ATTR);

+			return reference.createToXML(id, searcher, toPath, toTargetNodes,

+					namespaces, toQuerySpecificationId, tokenId, null,

+					additionalProposalInfoProvider);

+		} else if (TO_PROPERTY_ELT.equals(element.getName())) {

+			// Resource (file, folder...) reference

+			IXMLSearcher searcher = getSearcher(element,

+					DEFAULT_SEARCHER_FOR_PROPERTIES);

+			if (searcher == null) {

+				return null;

+			}

+			IContentAssistAdditionalProposalInfoProvider<PropertyInfo> additionalProposalInfoProvider = getAdditionalProposalInfoProvider(element);

+			if (additionalProposalInfoProvider == null) {

+				additionalProposalInfoProvider = PropertyContentAssistAdditionalProposalInfoProvider.INSTANCE;

+			}

+			return reference.createToProperty(id, searcher,

+					toQuerySpecificationId, tokenId,

+					additionalProposalInfoProvider);

+		} else if (TO_RESOURCE_ELT.equals(element.getName())) {

+			// Resource (file, folder...) reference

+			IXMLSearcher searcher = getSearcher(element,

+					DEFAULT_SEARCHER_FOR_FILE);

+			if (searcher == null) {

+				return null;

+			}

+			IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider = getAdditionalProposalInfoProvider(element);

+			if (additionalProposalInfoProvider == null) {

+				additionalProposalInfoProvider = ResourceContentAssistAdditionalProposalInfoProvider.INSTANCE;

+			}

+			return reference.createToResource(id, searcher,

+					toQuerySpecificationId, tokenId,

+					additionalProposalInfoProvider);

+		} else if (TO_JAVA_ELT.equals(element.getName())) {

+			// Java reference

+			IXMLSearcher searcher = getSearcher(element,

+					DEFAULT_SEARCHER_FOR_JAVA);

+			if (searcher == null) {

+				return null;

+			}

+			IJavaQuerySpecification querySpecification = getJavaQuerySpecification(element);

+			return reference.createToJava(id, searcher, toQuerySpecificationId,

+					tokenId, querySpecification);

+		} else if (TO_JAVA_METHOD_ELT.equals(element.getName())) {

+			// Java method reference

+			IXMLSearcher searcher = getSearcher(element,

+					DEFAULT_SEARCHER_FOR_JAVAMETHOD);

+			if (searcher == null) {

+				return null;

+			}

+			IJavaMethodQuerySpecification querySpecification = getJavaMethodQuerySpecification(element);

+			String pathForClass = element.getAttribute(PATH_FOR_CLASS_ATTR);

+			return reference.createToJavaMethod(id, searcher,

+					toQuerySpecificationId, tokenId, pathForClass,

+					querySpecification);

+		} else if (TO_STATIC_ELT.equals(element.getName())) {

+			// static reference

+			IXMLSearcher searcher = getSearcher(element,

+					DEFAULT_SEARCHER_FOR_STATICS);

+			if (searcher == null) {

+				return null;

+			}

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider = getAdditionalProposalInfoProvider(element);

+			return reference.createToStatic(id, searcher,

+					toQuerySpecificationId, tokenId,

+					additionalProposalInfoProvider);

+		}

+		return null;

+	}

+

+	private Namespaces getNamespaces(IConfigurationElement element) {

+		String namespaceId = element.getAttribute(NAMESPACE_ID_ATTR);

+		if (StringUtils.isEmpty(namespaceId)) {

+			return null;

+		}

+		return NamespacesManager.getInstance().getNamespaces(namespaceId);

+	}

+

+	private IXMLSearcher getSearcher(IConfigurationElement element,

+			String defaultSearcherId) {

+		String searcherId = element.getAttribute(SEARCHER_ID_ATTR);

+		if (searcherId == null) {

+			searcherId = defaultSearcherId;

+		}

+		IXMLSearcher searcher = XMLSearcherManager.getDefault().getSearcher(

+				searcherId);

+		if (searcher == null) {

+			return null;

+		}

+		return searcher;

+	}

+

+	private <T> IContentAssistAdditionalProposalInfoProvider<T> getAdditionalProposalInfoProvider(

+			IConfigurationElement element) {

+		String additionalProposalInfoProviderId = element

+				.getAttribute(ADDITIONAL_PROPOSAL_INFO_PROVIDER_ID_ATTR);

+		if (StringUtils.isEmpty(additionalProposalInfoProviderId)) {

+			return null;

+		}

+		return ContentAssistsManager.getDefault().getProvider(

+				additionalProposalInfoProviderId);

+	}

+

+	private IJavaMethodQuerySpecification getJavaMethodQuerySpecification(

+			IConfigurationElement element) {

+		String querySpecificationId = element

+				.getAttribute(QUERY_SPECIFICATION_ID_ATTR);

+		if (StringUtils.isEmpty(querySpecificationId)) {

+			return JavaMethodQuerySpecification.DEFAULT;

+		}

+		return JavaMethodQuerySpecificationrManager.getDefault()

+				.getQuerySpecification(querySpecificationId);

+	}

+

+	private IJavaQuerySpecification getJavaQuerySpecification(

+			IConfigurationElement element) {

+		String querySpecificationId = element

+				.getAttribute(QUERY_SPECIFICATION_ID_ATTR);

+		if (StringUtils.isEmpty(querySpecificationId)) {

+			String extendsClass = element.getAttribute("extends");

+			if (!StringUtils.isEmpty(extendsClass)) {

+				DefaultExtendedClassProvider implementsClassProvider = new DefaultExtendedClassProvider(

+						extendsClass.split(","));

+				return new JavaQuerySpecification(implementsClassProvider);

+			}

+			return null;

+		}

+		return JavaQuerySpecificationrManager.getDefault()

+				.getQuerySpecification(querySpecificationId);

+	}

+

+	private IXMLReferenceFilter getFilter(IConfigurationElement element) {

+		String filterId = element.getAttribute(FILTER_ID_ATTR);

+		if (StringUtils.isEmpty(filterId)) {

+			return null;

+		}

+		return XMLReferenceFiltersManager.getDefault().getProvider(filterId);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToExpression.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToExpression.java
new file mode 100644
index 0000000..95a98a1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToExpression.java
@@ -0,0 +1,102 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;

+

+public class XMLReferenceToExpression extends XMLReference implements

+		IXMLReferenceToExpression {

+

+	private final IXMLExpressionParser parser;

+	private final IXMLSearcher expressionSearcher;

+	private final Map<String, List<IXMLReferenceTo>> tokens;

+

+	public XMLReferenceToExpression(String fromPath, String fromTargetNodes,

+			Namespaces namespaces, String querySpecificationId,

+			String[] contentTypeIds, IXMLReferenceFilter filter,

+			IXMLReferenceValidator validator, IXMLExpressionParser parser,

+			IXMLSearcher expressionSearcher) {

+		super(fromPath, fromTargetNodes, namespaces, querySpecificationId,

+				contentTypeIds, filter, validator);

+		this.parser = parser;

+		this.expressionSearcher = expressionSearcher;

+		this.tokens = new HashMap<String, List<IXMLReferenceTo>>();

+	}

+

+	public ToType getType() {

+		return ToType.EXPRESSION;

+	}

+

+	public String getId() {

+		return null;

+	}

+

+	public IXMLReference getOwnerReference() {

+		return this;

+	}

+

+	public String getQuerySpecificationId() {

+		return null;

+	}

+

+	public IXMLSearcher getSearcher() {

+		return expressionSearcher;

+	}

+

+	public IXMLExpressionParser getParser() {

+		return parser;

+	}

+

+	@Override

+	public IXMLReference addTo(IXMLReferenceTo to) {

+		String tokenId = to.getTokenId();

+		if (!StringUtils.isEmpty(tokenId)) {

+			List<IXMLReferenceTo> tos = tokens.get(tokenId);

+			if (tos == null) {

+				tos = new ArrayList<IXMLReferenceTo>();

+				tokens.put(tokenId, tos);

+			}

+			tos.add(to);

+		}

+		return super.addTo(to);

+	}

+

+	public List<IXMLReferenceTo> getTo(String tokenId) {

+		List<IXMLReferenceTo> tos = tokens.get(tokenId);

+		if (tos != null) {

+			return tos;

+		}

+		return Collections.emptyList();

+	}

+

+	public String getTokenId() {

+		return null;

+	}

+

+	@Override

+	public boolean isExpression() {

+		return true;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJava.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJava.java
new file mode 100644
index 0000000..1578cf1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJava.java
@@ -0,0 +1,43 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.wst.xml.search.editor.references.IReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJava;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;

+

+public class XMLReferenceToJava extends AbstractXMLReferenceTo implements

+		IXMLReferenceToJava {

+

+	private final IJavaQuerySpecification querySpecification;

+

+	public XMLReferenceToJava(IReference ownerReference, String id,

+			IXMLSearcher searcher, String querySpecificationId,

+			IJavaQuerySpecification querySpecification, String tokenId) {

+		super(ownerReference, id, searcher, querySpecificationId, tokenId);

+		this.querySpecification = querySpecification;

+	}

+

+	public ToType getType() {

+		return ToType.JAVA;

+	}

+

+	public IType[] getExtends(Object selectedNode, IFile file) {

+		if (querySpecification != null) {

+			return querySpecification.getExtends(selectedNode, file);

+		}

+		return null;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJavaMethod.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJavaMethod.java
new file mode 100644
index 0000000..06e36f9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToJavaMethod.java
@@ -0,0 +1,109 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.eclipse.wst.xml.search.editor.references.IReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJavaMethod;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.IClassNameExtractor;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.XPathClassNameExtractor;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;

+import org.w3c.dom.Node;

+

+public class XMLReferenceToJavaMethod extends AbstractXMLReferenceTo implements

+		IXMLReferenceToJavaMethod {

+

+	private static final String PARENT_TOKEN = "../";

+	private static final int PARENT_TOKEN_LENGTH = PARENT_TOKEN.length();

+

+	private final String pathForClass;

+	private final IJavaMethodQuerySpecification querySpecification;

+	private boolean findByParentNode = false;

+	private String findByAttrName = null;

+

+	public XMLReferenceToJavaMethod(IReference ownerReference, String id,

+			IXMLSearcher searcher, String querySpecificationId,

+			String pathForClass,

+			IJavaMethodQuerySpecification querySpecification, String tokenId) {

+		super(ownerReference, id, searcher, querySpecificationId, tokenId);

+		this.pathForClass = pathForClass;

+		this.querySpecification = querySpecification;

+		if (pathForClass != null) {

+			findByAttrName = getAttrCondition(pathForClass);

+			if (findByAttrName == null) {

+				if (pathForClass.startsWith(PARENT_TOKEN)) {

+					findByParentNode = true;

+					findByAttrName = getAttrCondition(pathForClass.substring(

+							PARENT_TOKEN_LENGTH, pathForClass.length()));

+				}

+			}

+		}

+	}

+

+	private static String getAttrCondition(String s) {

+		if (s.startsWith("@")) {

+			return s.substring(1, s.length());

+		}

+		return null;

+	}

+

+	public ToType getType() {

+		return ToType.JAVA_METHOD;

+	}

+

+	public String getPathForClass() {

+		return pathForClass;

+	}

+

+	public IClassNameExtractor getClassNameExtractor(Object selectedNode,

+			IFile file) {

+		if (querySpecification != null) {

+			return querySpecification.getClassNameExtractor(selectedNode, file);

+		}

+		return null;

+	}

+

+	public String extractClassName(Node selectedNode, IFile file,

+			String xpathFactoryProviderId, NamespaceInfos namespaceInfo)

+			throws XPathExpressionException {

+		IClassNameExtractor extractor = getClassNameExtractor(selectedNode,

+				file);

+		if (extractor == null) {

+			extractor = XPathClassNameExtractor.INSTANCE;

+		}

+		if (extractor != null) {

+			return extractor.extractClassName(selectedNode, file, pathForClass,

+					findByAttrName, findByParentNode, xpathFactoryProviderId,

+					namespaceInfo);

+		}

+		return null;

+	}

+

+	public boolean isFindByParentNode() {

+		return findByParentNode;

+	}

+

+	public String getFindByAttrName() {

+		return findByAttrName;

+	}

+

+	public IJavaMethodRequestor getRequestor(Object selectedNode, IFile file) {

+		if (querySpecification != null) {

+			return querySpecification.getRequestor(selectedNode, file);

+		}

+		return null;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToProperty.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToProperty.java
new file mode 100644
index 0000000..0429917
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToProperty.java
@@ -0,0 +1,41 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.references.IReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+

+public class XMLReferenceToProperty extends AbstractXMLReferenceTo implements

+		IXMLReferenceToProperty {

+

+	private final IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider;

+

+	public XMLReferenceToProperty(

+			IReference ownerReference,

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId, 

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {

+		super(ownerReference, id, searcher, querySpecificationId, tokenId);

+		this.additionalProposalInfoProvider = additionalProposalInfoProvider;

+	}

+

+	public ToType getType() {

+		return ToType.PROPERTY;

+	}

+

+	public IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider() {

+		return additionalProposalInfoProvider;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToResource.java
new file mode 100644
index 0000000..76a290c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToResource.java
@@ -0,0 +1,42 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.references.IReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+

+public class XMLReferenceToResource extends AbstractXMLReferenceTo implements

+		IXMLReferenceToResource {

+

+	private final IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider;

+

+	public XMLReferenceToResource(

+			IReference ownerReference,

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider) {

+		super(ownerReference, id, searcher, querySpecificationId, tokenId);

+		this.additionalProposalInfoProvider = additionalProposalInfoProvider;

+	}

+

+	public ToType getType() {

+		return ToType.RESOURCE;

+	}

+

+	public IContentAssistAdditionalProposalInfoProvider<IResource> getAdditionalProposalInfoProvider() {

+		return additionalProposalInfoProvider;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToStatic.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToStatic.java
new file mode 100644
index 0000000..cba402b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferenceToStatic.java
@@ -0,0 +1,41 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.references.IReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+

+public class XMLReferenceToStatic extends AbstractXMLReferenceTo implements

+		IXMLReferenceToStatic {

+

+	private final IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider;

+

+	public XMLReferenceToStatic(

+			IReference ownerReference,

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {

+		super(ownerReference, id, searcher, querySpecificationId, tokenId);

+		this.additionalProposalInfoProvider = additionalProposalInfoProvider;

+	}

+

+	public ToType getType() {

+		return ToType.STATIC;

+	}

+

+	public IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider() {

+		return additionalProposalInfoProvider;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencesManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencesManager.java
new file mode 100644
index 0000000..ccac5b6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/XMLReferencesManager.java
@@ -0,0 +1,394 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.references.validators.XMLReferenceValidatorsManager;

+import org.eclipse.wst.xml.search.editor.internal.searchers.expressions.XMLExpressionParserManager;

+import org.eclipse.wst.xml.search.editor.references.AbstractReferencesManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;

+import org.eclipse.wst.xml.search.editor.references.validators.DefaultDOMNodeValidator;

+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.XMLSearcherManager;

+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Node;

+import org.w3c.dom.Text;

+

+public class XMLReferencesManager extends

+		AbstractReferencesManager<IXMLReference, Node> {

+

+	private static final String XPATH_FACTORY_ID_ATTR = "xpathFactoryId";

+	private static final String VALIDATOR_ID_ATTR = "validatorId";

+	private static final String PARSER_ID_ATTR = "parserId";

+	private static final String SEARCHER_ID_ATTR = "searcherId";

+

+	private static final String DEFAULT_SEARCHER_FOR_EXPRESSION = "org.eclipse.wst.xml.search.editor.searcher.expression";

+

+	private static final XMLReferencesManager INSTANCE = new XMLReferencesManager();

+	private static final String XML_REFERENCES_EXTENSION_POINT = "xmlReferences";

+

+	private Map<String, XMLReferenceContainer> referencesContainerByContentTypeId = null;

+

+	private Collection<String> contentTypeIds = null;

+

+	public static XMLReferencesManager getInstance() {

+		return INSTANCE;

+	}

+

+	enum Direction {

+		FROM, TO

+	}

+

+	// ---------- XML Refernce

+

+	public IXMLReference getXMLReference(Node node, String contentTypeId) {

+		if (node == null)

+			return null;

+		Collection<IXMLReference> references = getXMLReferences(node,

+				Direction.FROM, contentTypeId);

+		if (references == null) {

+			return null;

+		}

+		Node testNode = getTestNode(node);

+		for (IXMLReference reference : references) {

+			if (match(testNode, node, reference.getFrom()))

+				return reference;

+		}

+		return null;

+	}

+

+	private Node getTestNode(Node node) {

+		short nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			return ((Attr) node).getOwnerElement();

+		case Node.TEXT_NODE:

+			return ((Text) node).getParentNode();

+		}

+		return node;

+	}

+

+	public boolean match(Node node, IXMLReferencePath referencePath) {

+		return match(getTestNode(node), node, referencePath);

+	}

+

+	public boolean match(Node parentNode, Node node,

+			IXMLReferencePath referencePath) {

+		if (referencePath == null) {

+			return false;

+		}

+		if (!referencePath.match(parentNode)) {

+			return false;

+		}

+		Namespaces namespaces = referencePath.getNamespaces();

+		if (namespaces == null) {

+			return true;

+		}

+		if (referencePath.getTargetNodes()[0].indexOf(':') == -1) {

+			return true;

+		}

+		return namespaces.match(node);

+	}

+

+	public Collection<IXMLReference> getXMLReferences(Node node,

+			Direction direction, String contentTypeId) {

+		loadXMLReferencesIfNeeded();

+		if (contentTypeId == null) {

+			List<IXMLReference> references = new ArrayList<IXMLReference>();

+			Collection<XMLReferenceContainer> containers = referencesContainerByContentTypeId

+					.values();

+			for (XMLReferenceContainer container : containers) {

+				Collection<IXMLReference> referencesByContainer = container

+						.getXMLReferences(node, direction);

+				if (referencesByContainer != null) {

+					references.addAll(referencesByContainer);

+				}

+			}

+			return references;

+		}

+		XMLReferenceContainer container = referencesContainerByContentTypeId

+				.get(contentTypeId);

+		return container == null ? null : container.getXMLReferences(node,

+				direction);

+	}

+

+	// XML reference inversed

+

+	public List<IXMLReference> getXMLReferenceInversed(Node node,

+			String contentTypeId) {

+		if (node == null)

+			return null;

+		Collection<IXMLReference> references = getXMLReferences(node,

+				Direction.TO, null);

+		if (references == null) {

+			return null;

+		}

+		List<IXMLReference> matchedPaths = null;

+		Node parentNode = getTestNode(node);

+		for (IXMLReference reference : references) {

+			Collection<IXMLReferenceTo> to = reference.getTo();

+			for (IXMLReferenceTo referenceTo : to) {

+				if (!(referenceTo.getType() == ToType.XML)) {

+					continue;

+				}

+				IXMLReferencePath referencePath = (IXMLReferencePath) referenceTo;

+				if (match(parentNode, node, referencePath)) {

+					if (matchedPaths == null) {

+						matchedPaths = new ArrayList<IXMLReference>();

+					}

+					if (!matchedPaths.contains(reference)) {

+						matchedPaths.add(reference);

+					}

+				}

+

+				continue;

+			}

+		}

+		return matchedPaths;

+	}

+

+	public Collection<IXMLReferencePath> getXMLReferencesByPathTo(String path,

+			String contentTypeId) {

+		Collection<IXMLReferencePath> referencePaths = new ArrayList<IXMLReferencePath>();

+		Collection<XMLReferenceContainer> containers = referencesContainerByContentTypeId

+				.values();

+		for (XMLReferenceContainer container : containers) {

+			Collection<IXMLReferencePath> o = container

+					.getXMLReferencesByPathTo(path);

+			if (o != null) {

+				referencePaths.addAll(o);

+			}

+		}

+		//

+		// XMLReferenceContainer container = referencesContainerByContentTypeId

+		// .get(contentTypeId);

+		// return container == null ? null : container

+		// .getXMLReferencesByPathTo(path);

+		return referencePaths;

+	}

+

+	private synchronized void loadXMLReferences() {

+		if (referencesContainerByContentTypeId != null) {

+			return;

+		}

+		this.contentTypeIds = new ArrayList<String>();

+		Map<String, XMLReferenceContainer> referencesContainerByContentTypeId = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					getPluginId(), XML_REFERENCES_EXTENSION_POINT);

+			referencesContainerByContentTypeId = new HashMap<String, XMLReferenceContainer>();

+			addXMLReferences(referencesContainerByContentTypeId, cf);

+		} else {

+			referencesContainerByContentTypeId = new HashMap<String, XMLReferenceContainer>();

+		}

+		this.referencesContainerByContentTypeId = referencesContainerByContentTypeId;

+		super.addRegistryListenerIfNeeded();

+	}

+

+	private synchronized void addXMLReferences(

+			Map<String, XMLReferenceContainer> referencesContainerByContentTypeId,

+			IConfigurationElement[] cf) {

+

+		for (IConfigurationElement ce : cf) {

+			if (REFERENCES_ELT.equals(ce.getName())) {

+				String ids = ce

+						.getAttribute(XMLReferencePathFactory.CONTENT_TYPE_IDS_ATTR);

+				String[] defaultContentTypeIds = (ids != null ? ids.split(",")

+						: StringUtils.EMPTY_ARRAY);

+				// Update collection of contenttype ids supported with XML

+				// reference.

+				String contentTypeId = null;

+				for (int i = 0; i < defaultContentTypeIds.length; i++) {

+					contentTypeId = defaultContentTypeIds[i];

+					if (!contentTypeIds.contains(contentTypeId)) {

+						contentTypeIds.add(contentTypeId);

+					}

+				}

+

+				String xpathFactoryId = ce.getAttribute(XPATH_FACTORY_ID_ATTR);

+				for (IConfigurationElement referenceDecl : ce.getChildren()) {

+					parseReferenceDecl(referenceDecl, defaultContentTypeIds,

+							xpathFactoryId, referencesContainerByContentTypeId);

+				}

+			}

+		}

+	}

+

+	private void parseReferenceDecl(

+			IConfigurationElement referenceDecl,

+			String[] defaultContentTypeIds,

+			String defaultXpathFactoryId,

+			Map<String, XMLReferenceContainer> referencesContainerByContentTypeId) {

+		try {

+			IXMLReference reference = null;

+			IXMLReferenceTo referenceTo = null;

+			IXMLReferenceValidator validator = getValidator(referenceDecl);

+			if (validator == null) {

+				validator = DefaultDOMNodeValidator.INSTANCE;

+			}

+			IXMLExpressionParser parser = getParser(referenceDecl);

+			IXMLSearcher expressionSearcher = getSearcher(referenceDecl,

+					DEFAULT_SEARCHER_FOR_EXPRESSION);

+			// reference declaration,

+			// loop for to get from+to declaration

+			for (IConfigurationElement fromOrTo : referenceDecl.getChildren()) {

+				if (FROM_ELT.equals(fromOrTo.getName())) {

+					reference = XMLReferencePathFactory.INSTANCE

+							.createReference(fromOrTo, defaultContentTypeIds,

+									validator, parser, expressionSearcher);

+

+				} else if (reference != null) {

+					referenceTo = XMLReferencePathFactory.INSTANCE.createTo(

+							fromOrTo, reference);

+					if (referenceTo != null) {

+						reference.addTo(referenceTo);

+					}

+				}

+			}

+			if (reference != null) {

+				registerXMLReference(reference,

+						referencesContainerByContentTypeId);

+			}

+		} catch (Throwable t) {

+			Trace.trace(Trace.SEVERE, "  Could not load references", t);

+		}

+	}

+

+	private IXMLReferenceValidator getValidator(IConfigurationElement element) {

+		String validatorId = element.getAttribute(VALIDATOR_ID_ATTR);

+		if (StringUtils.isEmpty(validatorId)) {

+			return null;

+		}

+		return XMLReferenceValidatorsManager.getDefault().getProvider(

+				validatorId);

+	}

+

+	private IXMLExpressionParser getParser(IConfigurationElement element) {

+		String parserId = element.getAttribute(PARSER_ID_ATTR);

+		if (StringUtils.isEmpty(parserId)) {

+			return null;

+		}

+		return XMLExpressionParserManager.getDefault().getParser(parserId);

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (referencesContainerByContentTypeId == null) // not loaded yet

+			return;

+

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addXMLReferences(referencesContainerByContentTypeId, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	public void registerXMReference(IXMLReference reference) {

+		loadXMLReferencesIfNeeded();

+		registerXMLReference(reference, referencesContainerByContentTypeId);

+	}

+

+	private void registerXMLReference(

+			IXMLReference reference,

+			Map<String, XMLReferenceContainer> referencesContainerByContentTypeId) {

+		String[] contentTypeIds = reference.getContentTypeIds();

+		if (contentTypeIds != null) {

+			for (String contentTypeId : contentTypeIds) {

+				XMLReferenceContainer container = referencesContainerByContentTypeId

+						.get(contentTypeId);

+				if (container == null) {

+					container = new XMLReferenceContainer(contentTypeId);

+					referencesContainerByContentTypeId.put(contentTypeId,

+							container);

+				}

+				container.addReference(reference);

+			}

+		}

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return XML_REFERENCES_EXTENSION_POINT;

+	}

+

+	public Collection<IXMLReference> getAllReferencesWithOneReferenceTo(

+			ToType toType) {

+		loadXMLReferencesIfNeeded();

+		List<IXMLReference> to = new ArrayList<IXMLReference>();

+		Collection<XMLReferenceContainer> containers = referencesContainerByContentTypeId

+				.values();

+		for (XMLReferenceContainer container : containers) {

+			to.addAll(container.getAllReferencesWithOneReferenceTo(toType));

+		}

+		return to;

+	}

+

+	public XMLReferenceContainer getXMLReferenceContainer(String contentTypeId) {

+		loadXMLReferencesIfNeeded();

+		return referencesContainerByContentTypeId.get(contentTypeId);

+	}

+

+	private void loadXMLReferencesIfNeeded() {

+		if (referencesContainerByContentTypeId == null) {

+			loadXMLReferences();

+		}

+	}

+

+	public Collection<String> getContentTypeIds() {

+		loadXMLReferencesIfNeeded();

+		return contentTypeIds;

+	}

+

+	public Collection<IXMLReference> getXMLReferencesForToType(ToType toType) {

+		loadXMLReferencesIfNeeded();

+		List<IXMLReference> references = new ArrayList<IXMLReference>();

+		Collection<XMLReferenceContainer> containers = referencesContainerByContentTypeId

+				.values();

+		for (XMLReferenceContainer container : containers) {

+			references.addAll(container.getXMLReferencesForToType(toType));

+		}

+		return references;

+	}

+

+	private IXMLSearcher getSearcher(IConfigurationElement element,

+			String defaultSearcherId) {

+		String searcherId = element.getAttribute(SEARCHER_ID_ATTR);

+		if (searcherId == null) {

+			searcherId = defaultSearcherId;

+		}

+		IXMLSearcher searcher = XMLSearcherManager.getDefault().getSearcher(

+				searcherId);

+		if (searcher == null) {

+			return null;

+		}

+		return searcher;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/filters/XMLReferenceFiltersManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/filters/XMLReferenceFiltersManager.java
new file mode 100644
index 0000000..98934fd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/filters/XMLReferenceFiltersManager.java
@@ -0,0 +1,115 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references.filters;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+

+public class XMLReferenceFiltersManager extends AbstractRegistryManager {

+

+	private static final String CLASS_ATTR = "class";

+	private static final String ID_ATTR = "id";

+	private static final String FILTER_ELT = "filter";

+	public static final XMLReferenceFiltersManager INSTANCE = new XMLReferenceFiltersManager();

+	private static final String XML_REFERENCE_FILTERS_EXTENSION_POINT = "referenceFilters";

+

+	private Map<String, IXMLReferenceFilter> filtersById = null;

+

+	public static XMLReferenceFiltersManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (filtersById == null) {// not loaded yet

+			return;

+		}

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addXMLReferenceFilters(filtersById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	private synchronized void addXMLReferenceFilters(

+			Map<String, IXMLReferenceFilter> providersById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		for (IConfigurationElement ce : cf) {

+			// loop for to get additionalProposalInfoProvider declaration

+			if (FILTER_ELT.equals(ce.getName())) {

+				id = ce.getAttribute(ID_ATTR);

+				try {

+					IXMLReferenceFilter provider = (IXMLReferenceFilter) ce

+							.createExecutableExtension(CLASS_ATTR);

+					providersById.put(id, provider);

+				} catch (Throwable t) {

+					Trace.trace(Trace.SEVERE,

+							"  Could not load XML references filters for id: "

+									+ id, t);

+				}

+			}

+		}

+	}

+

+	public IXMLReferenceFilter getProvider(String referenceId) {

+		if (StringUtils.isEmpty(referenceId)) {

+			return null;

+		}

+		if (filtersById == null) {

+			loadXMLReferenceFilters();

+		}

+

+		return filtersById.get(referenceId);

+	}

+

+	private synchronized void loadXMLReferenceFilters() {

+		if (filtersById != null) {

+			return;

+		}

+		Map<String, IXMLReferenceFilter> providersById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchEditorPlugin.PLUGIN_ID,

+					XML_REFERENCE_FILTERS_EXTENSION_POINT);

+			providersById = new HashMap<String, IXMLReferenceFilter>(cf.length);

+			addXMLReferenceFilters(providersById, cf);

+		} else {

+			providersById = new HashMap<String, IXMLReferenceFilter>();

+		}

+		this.filtersById = providersById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return XML_REFERENCE_FILTERS_EXTENSION_POINT;

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchEditorPlugin.PLUGIN_ID;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/validators/XMLReferenceValidatorsManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/validators/XMLReferenceValidatorsManager.java
new file mode 100644
index 0000000..51e20b3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/references/validators/XMLReferenceValidatorsManager.java
@@ -0,0 +1,115 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.references.validators;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;

+

+public class XMLReferenceValidatorsManager extends AbstractRegistryManager {

+

+	private static final String CLASS_ATTR = "class";

+	private static final String ID_ATTR = "id";

+	private static final String FILTER_ELT = "validator";

+	public static final XMLReferenceValidatorsManager INSTANCE = new XMLReferenceValidatorsManager();

+	private static final String XML_REFERENCE_FILTERS_EXTENSION_POINT = "referenceValidators";

+

+	private Map<String, IXMLReferenceValidator> validatorsById = null;

+

+	public static XMLReferenceValidatorsManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (validatorsById == null) {// not loaded yet

+			return;

+		}

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addXMLReferenceValidators(validatorsById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	private synchronized void addXMLReferenceValidators(

+			Map<String, IXMLReferenceValidator> providersById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		for (IConfigurationElement ce : cf) {

+			// loop for to get additionalProposalInfoProvider declaration

+			if (FILTER_ELT.equals(ce.getName())) {

+				id = ce.getAttribute(ID_ATTR);

+				try {

+					IXMLReferenceValidator provider = (IXMLReferenceValidator) ce

+							.createExecutableExtension(CLASS_ATTR);

+					providersById.put(id, provider);

+				} catch (Throwable t) {

+					Trace.trace(Trace.SEVERE,

+							"  Could not load XML references validators for id: "

+									+ id, t);

+				}

+			}

+		}

+	}

+

+	public IXMLReferenceValidator getProvider(String referenceId) {

+		if (StringUtils.isEmpty(referenceId)) {

+			return null;

+		}

+		if (validatorsById == null) {

+			loadXMLReferenceValidators();

+		}

+

+		return validatorsById.get(referenceId);

+	}

+

+	private synchronized void loadXMLReferenceValidators() {

+		if (validatorsById != null) {

+			return;

+		}

+		Map<String, IXMLReferenceValidator> providersById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchEditorPlugin.PLUGIN_ID,

+					XML_REFERENCE_FILTERS_EXTENSION_POINT);

+			providersById = new HashMap<String, IXMLReferenceValidator>(cf.length);

+			addXMLReferenceValidators(providersById, cf);

+		} else {

+			providersById = new HashMap<String, IXMLReferenceValidator>();

+		}

+		this.validatorsById = providersById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return XML_REFERENCE_FILTERS_EXTENSION_POINT;

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchEditorPlugin.PLUGIN_ID;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/reporter/XMLSearchReporterManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/reporter/XMLSearchReporterManager.java
new file mode 100644
index 0000000..26b74e0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/reporter/XMLSearchReporterManager.java
@@ -0,0 +1,60 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.reporter;

+

+import java.util.Collection;

+import java.util.Map;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;

+import org.eclipse.wst.xml.search.core.reporter.MutliXMLSearchReporter;

+import org.eclipse.wst.xml.search.core.reporter.SysOutSearchReporter;

+

+public class XMLSearchReporterManager implements IXMLSearchReporter {

+

+	private static final XMLSearchReporterManager INSTANCE = new XMLSearchReporterManager();

+

+	public static XMLSearchReporterManager getDefault() {

+		return INSTANCE;

+	}

+

+	private MutliXMLSearchReporter multiReporter = new MutliXMLSearchReporter();

+

+	public void beginSearch(int searchId,

+			Map<IResource, Collection<String>> queries) {

+		multiReporter.beginSearch(searchId, queries);

+	}

+

+	public void endSearch(int searchId, long elapsedTime) {

+		multiReporter.endSearch(searchId, elapsedTime);

+	}

+

+	public boolean isEnabled() {

+		return multiReporter.isEnabled();

+	}

+

+	public void initialize() {

+		boolean debug = Boolean

+				.valueOf(

+						Platform

+								.getDebugOption("org.eclipse.wst.xml.search.editor/debug/reporter"))

+				.booleanValue();

+		if (debug) {

+			multiReporter.add(SysOutSearchReporter.INSTANCE);

+		}

+	}

+

+	public void destroy() {

+

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/expressions/XMLExpressionParserManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/expressions/XMLExpressionParserManager.java
new file mode 100644
index 0000000..084bbd4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/expressions/XMLExpressionParserManager.java
@@ -0,0 +1,119 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.searchers.expressions;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;

+

+public class XMLExpressionParserManager extends AbstractRegistryManager {

+

+	private static XMLExpressionParserManager INSTANCE = new XMLExpressionParserManager();

+

+	private static final String CLASS_ATTR = "class";

+	private static final String ID_ATTR = "id";

+	private static final String EXPRESSION_PARSER_ELT = "parser";

+	private static final String EXPRESSION_PARSERS_EXTENSION_POINT = "expressionParsers";

+

+	private Map<String, IXMLExpressionParser> expressionParserById = null;

+

+	public static XMLExpressionParserManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (expressionParserById == null) {// not loaded yet

+			return;

+		}

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addParser(expressionParserById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	private synchronized void addParser(

+			Map<String, IXMLExpressionParser> expressionParserById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		for (IConfigurationElement ce : cf) {

+			// loop for to get provider declaration

+			if (EXPRESSION_PARSER_ELT.equals(ce.getName())) {

+				id = ce.getAttribute(ID_ATTR);

+				try {

+					Object o = ce.createExecutableExtension(CLASS_ATTR);

+					if (o instanceof IXMLExpressionParser) {

+						expressionParserById.put(id, (IXMLExpressionParser) o);

+					}

+				} catch (Throwable t) {

+					Trace.trace(Trace.SEVERE,

+							"  Could not load expressionParser for id: " + id,

+							t);

+				}

+			}

+		}

+	}

+

+	public IXMLExpressionParser getParser(String parserId) {

+		if (StringUtils.isEmpty(parserId)) {

+			return null;

+		}

+		if (expressionParserById == null) {

+			loadParsers();

+		}

+

+		return expressionParserById.get(parserId);

+	}

+

+	private synchronized void loadParsers() {

+		if (expressionParserById != null) {

+			return;

+		}

+		Map<String, IXMLExpressionParser> expressionParserById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchEditorPlugin.PLUGIN_ID,

+					EXPRESSION_PARSERS_EXTENSION_POINT);

+			expressionParserById = new HashMap<String, IXMLExpressionParser>(

+					cf.length);

+			addParser(expressionParserById, cf);

+		} else {

+			expressionParserById = new HashMap<String, IXMLExpressionParser>();

+		}

+		this.expressionParserById = expressionParserById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return EXPRESSION_PARSERS_EXTENSION_POINT;

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchEditorPlugin.PLUGIN_ID;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecification.java
new file mode 100644
index 0000000..3eb85d5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecification.java
@@ -0,0 +1,55 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.searchers.java;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.wst.xml.search.editor.searchers.java.IExtendedClassProvider;

+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;

+

+public class JavaQuerySpecification implements IJavaQuerySpecification {

+

+	public static final IJavaQuerySpecification DEFAULT = null;

+	private IExtendedClassProvider implementsClassProvider;

+

+	public JavaQuerySpecification(

+			IExtendedClassProvider implementsClassProvider) {

+		this.implementsClassProvider = implementsClassProvider;

+	}

+

+	public static IJavaQuerySpecification newJavaQuerySpecification(

+			Object querySpecification) {

+		if (querySpecification != null) {

+			JavaQuerySpecification specification = new JavaQuerySpecification(

+					null);

+			if (querySpecification instanceof IExtendedClassProvider) {

+				specification

+						.setImplementsClassProvider((IExtendedClassProvider) querySpecification);

+			}

+			return specification;

+		}

+		return null;

+	}

+

+	private void setImplementsClassProvider(

+			IExtendedClassProvider implementsClassProvider) {

+		this.implementsClassProvider = implementsClassProvider;

+	}

+

+	public IType[] getExtends(Object selectedNode, IFile file) {

+		if (implementsClassProvider != null) {

+			return implementsClassProvider.getExtends(selectedNode,

+					file);

+		}

+		return null;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecificationrManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecificationrManager.java
new file mode 100644
index 0000000..777fd2c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/java/JavaQuerySpecificationrManager.java
@@ -0,0 +1,119 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.searchers.java;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;

+

+public class JavaQuerySpecificationrManager extends AbstractRegistryManager {

+

+	private static final String CLASS_ATTR = "class";

+	private static final String ID_ATTR = "id";

+	private static final String QUERY_SPECIFICATION_ELT = "querySpecification";

+	public static final JavaQuerySpecificationrManager INSTANCE = new JavaQuerySpecificationrManager();

+	private static final String JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT = "javaQuerySpecifications";

+

+	private Map<String, IJavaQuerySpecification> querySpecificationById = null;

+

+	public static JavaQuerySpecificationrManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (querySpecificationById == null) {// not loaded yet

+			return;

+		}

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addJavaFilter(querySpecificationById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	private synchronized void addJavaFilter(

+			Map<String, IJavaQuerySpecification> querySpecificationById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		for (IConfigurationElement ce : cf) {

+			// loop for to get provider declaration

+			if (QUERY_SPECIFICATION_ELT.equals(ce.getName())) {

+				id = ce.getAttribute(ID_ATTR);

+				try {

+					Object o = ce.createExecutableExtension(CLASS_ATTR);

+					IJavaQuerySpecification querySpecification = JavaQuerySpecification

+							.newJavaQuerySpecification(o);

+					if (querySpecification != null) {

+						querySpecificationById.put(id, querySpecification);

+					}

+				} catch (Throwable t) {

+					Trace.trace(Trace.SEVERE,

+							"  Could not load javaQuerySpecification for id: "

+									+ id, t);

+				}

+			}

+		}

+	}

+

+	public IJavaQuerySpecification getQuerySpecification(String id) {

+		if (StringUtils.isEmpty(id)) {

+			return null;

+		}

+		if (querySpecificationById == null) {

+			loadQuerySpecifications();

+		}

+

+		return querySpecificationById.get(id);

+	}

+

+	private synchronized void loadQuerySpecifications() {

+		if (querySpecificationById != null) {

+			return;

+		}

+		Map<String, IJavaQuerySpecification> querySpecificationById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchEditorPlugin.PLUGIN_ID,

+					JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT);

+			querySpecificationById = new HashMap<String, IJavaQuerySpecification>(

+					cf.length);

+			addJavaFilter(querySpecificationById, cf);

+		} else {

+			querySpecificationById = new HashMap<String, IJavaQuerySpecification>();

+		}

+		this.querySpecificationById = querySpecificationById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT;

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchEditorPlugin.PLUGIN_ID;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecification.java
new file mode 100644
index 0000000..b2f3a35
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecification.java
@@ -0,0 +1,106 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.searchers.javamethod;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.IClassNameExtractor;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.IClassNameExtractorProvider;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.XPathClassNameExtractor;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.DefaultJavaMethodRequestor;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestorProvider;

+import org.w3c.dom.Node;

+

+public class JavaMethodQuerySpecification implements

+		IJavaMethodQuerySpecification {

+

+	public static final IJavaMethodQuerySpecification DEFAULT = newDefaultJavaMethodQuerySpecification();

+

+	private IJavaMethodRequestor requestor;

+	private IJavaMethodRequestorProvider requestorProvider;

+	private IClassNameExtractor classNameExtractor;

+	private IClassNameExtractorProvider classNameExtractorProvider;

+

+	public JavaMethodQuerySpecification(IJavaMethodRequestor requestor,

+			IJavaMethodRequestorProvider requestorProvider,

+			IClassNameExtractor classNameExtractor,

+			IClassNameExtractorProvider classNameExtractorProvider) {

+		this.requestor = requestor;

+		this.requestorProvider = requestorProvider;

+		this.classNameExtractor = classNameExtractor;

+		this.classNameExtractorProvider = classNameExtractorProvider;

+	}

+

+	public static IJavaMethodQuerySpecification newDefaultJavaMethodQuerySpecification() {

+		return new JavaMethodQuerySpecification(

+				DefaultJavaMethodRequestor.INSTANCE, null,

+				XPathClassNameExtractor.INSTANCE, null);

+	}

+

+	public static IJavaMethodQuerySpecification newJavaMethodQuerySpecification(

+			Object querySpecification) {

+		JavaMethodQuerySpecification specification = (JavaMethodQuerySpecification) newDefaultJavaMethodQuerySpecification();

+		if (querySpecification instanceof IJavaMethodRequestor) {

+			specification

+					.setRequestor((IJavaMethodRequestor) querySpecification);

+		}

+		if (querySpecification instanceof IJavaMethodRequestorProvider) {

+			specification

+					.setRequestorProvider((IJavaMethodRequestorProvider) querySpecification);

+		}

+		if (querySpecification instanceof IClassNameExtractor) {

+			specification

+					.setClassNameExtractor((IClassNameExtractor) querySpecification);

+		}

+		if (querySpecification instanceof IClassNameExtractorProvider) {

+			specification

+					.setClassNameExtractorProvider((IClassNameExtractorProvider) querySpecification);

+		}

+		return specification;

+	}

+

+	private void setClassNameExtractorProvider(

+			IClassNameExtractorProvider classNameExtractorProvider) {

+		this.classNameExtractorProvider = classNameExtractorProvider;

+	}

+

+	private void setClassNameExtractor(IClassNameExtractor classNameExtractor) {

+		this.classNameExtractor = classNameExtractor;

+	}

+

+	private void setRequestorProvider(

+			IJavaMethodRequestorProvider requestorProvider) {

+		this.requestorProvider = requestorProvider;

+

+	}

+

+	private void setRequestor(IJavaMethodRequestor requestor) {

+		this.requestor = requestor;

+

+	}

+

+	public IJavaMethodRequestor getRequestor(Object selectedNode, IFile file) {

+		if (requestorProvider != null) {

+			return requestorProvider.getRequestor(selectedNode, file);

+		}

+		return requestor;

+	}

+

+	public IClassNameExtractor getClassNameExtractor(Object selectedNode,

+			IFile file) {

+		if (classNameExtractorProvider != null) {

+			return classNameExtractorProvider.getClassNameExtractor(

+					selectedNode, file);

+		}

+		return classNameExtractor;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecificationrManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecificationrManager.java
new file mode 100644
index 0000000..0cd3454
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/searchers/javamethod/JavaMethodQuerySpecificationrManager.java
@@ -0,0 +1,118 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.searchers.javamethod;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+

+public class JavaMethodQuerySpecificationrManager extends

+		AbstractRegistryManager {

+

+	private static final String CLASS_ATTR = "class";

+	private static final String ID_ATTR = "id";

+	private static final String QUERY_SPECIFICATION_ELT = "querySpecification";

+	public static final JavaMethodQuerySpecificationrManager INSTANCE = new JavaMethodQuerySpecificationrManager();

+	private static final String JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT = "javaMethodQuerySpecifications";

+

+	private Map<String, IJavaMethodQuerySpecification> querySpecificationById = null;

+

+	public static JavaMethodQuerySpecificationrManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (querySpecificationById == null) {// not loaded yet

+			return;

+		}

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addJavaMethodFilter(querySpecificationById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	private synchronized void addJavaMethodFilter(

+			Map<String, IJavaMethodQuerySpecification> querySpecificationById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		for (IConfigurationElement ce : cf) {

+			// loop for to get provider declaration

+			if (QUERY_SPECIFICATION_ELT.equals(ce.getName())) {

+				id = ce.getAttribute(ID_ATTR);

+				try {

+					Object o = ce.createExecutableExtension(CLASS_ATTR);

+					IJavaMethodQuerySpecification querySpecification = JavaMethodQuerySpecification

+							.newJavaMethodQuerySpecification(o);

+					querySpecificationById.put(id, querySpecification);

+				} catch (Throwable t) {

+					Trace.trace(Trace.SEVERE,

+							"  Could not load javaMethodQuerySpecification for id: "

+									+ id, t);

+				}

+			}

+		}

+	}

+

+	public IJavaMethodQuerySpecification getQuerySpecification(String id) {

+		if (StringUtils.isEmpty(id)) {

+			return null;

+		}

+		if (querySpecificationById == null) {

+			loadQuerySpecifications();

+		}

+

+		return querySpecificationById.get(id);

+	}

+

+	private synchronized void loadQuerySpecifications() {

+		if (querySpecificationById != null) {

+			return;

+		}

+		Map<String, IJavaMethodQuerySpecification> querySpecificationById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchEditorPlugin.PLUGIN_ID,

+					JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT);

+			querySpecificationById = new HashMap<String, IJavaMethodQuerySpecification>(

+					cf.length);

+			addJavaMethodFilter(querySpecificationById, cf);

+		} else {

+			querySpecificationById = new HashMap<String, IJavaMethodQuerySpecification>();

+		}

+		this.querySpecificationById = querySpecificationById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return JAVA_METHOD_QUERY_SPECIFICATIONS_EXTENSION_POINT;

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchEditorPlugin.PLUGIN_ID;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/IReferencesStyleConstantsXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/IReferencesStyleConstantsXML.java
new file mode 100644
index 0000000..17af9af
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/IReferencesStyleConstantsXML.java
@@ -0,0 +1,18 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.style;

+

+public interface IReferencesStyleConstantsXML {

+

+	public static final String ENABLED_COLOR = "enabledColor";//$NON-NLS-1$

+	public static final String TAG_REFERENCED_ATTRIBUTE_VALUE = "tagReferencedAttributeValue";//$NON-NLS-1$

+	public static final String XML_REFERENCED_CONTENT = "xmlReferencedContent";//$NON-NLS-1$

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/LineStyleProviderForXMLReferences.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/LineStyleProviderForXMLReferences.java
new file mode 100644
index 0000000..da70a0c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/style/LineStyleProviderForXMLReferences.java
@@ -0,0 +1,199 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.style;

+

+import org.eclipse.jface.preference.IPreferenceStore;

+import org.eclipse.jface.text.TextAttribute;

+import org.eclipse.jface.util.PropertyChangeEvent;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.graphics.RGB;

+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;

+import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;

+import org.eclipse.wst.sse.ui.internal.preferences.ui.ColorHelper;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;

+import org.eclipse.wst.xml.ui.internal.style.IStyleConstantsXML;

+import org.eclipse.wst.xml.ui.internal.style.LineStyleProviderForXML;

+import org.w3c.dom.Node;

+

+public class LineStyleProviderForXMLReferences extends LineStyleProviderForXML implements IReferencesStyleConstantsXML {

+

+	private IDOMModel model;

+

+	public LineStyleProviderForXMLReferences(IDOMModel model) {

+		this.model = model;

+	}

+

+	@Override

+	protected TextAttribute getAttributeFor(ITextRegionCollection collection,

+			ITextRegion region) {

+		if (!getXMLSearchEditorColorPreferences().getBoolean(ENABLED_COLOR)) {

+			return super.getAttributeFor(collection, region);

+		}

+		

+		if (region == null) {

+			return (TextAttribute) getTextAttributes().get(

+					IStyleConstantsXML.CDATA_TEXT);

+		}

+		String type = region.getType();

+		if ((type == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)) {

+			IDOMNode node = DOMUtils.getNodeByOffset(model, collection

+					.getStart());

+			if (node != null) {

+				IDOMAttr attr = DOMUtils.getAttrByOffset(node, collection

+						.getStart()

+						+ region.getStart());

+				if (attr != null) {

+					IXMLReference reference = XMLReferencesUtil

+							.getXMLReference(attr, model

+									.getContentTypeIdentifier());

+					if (reference != null) {

+						return (TextAttribute) getTextAttributes()

+								.get(

+										TAG_REFERENCED_ATTRIBUTE_VALUE);

+					}

+				}

+			}

+		} else if ((type == DOMRegionContext.XML_CONTENT)) {

+			IDOMNode node = DOMUtils.getNodeByOffset(model, collection

+					.getStart());

+			if (node != null && node.getNodeType() == Node.TEXT_NODE) {

+				IXMLReference reference = XMLReferencesUtil.getXMLReference(

+						node, model.getContentTypeIdentifier());

+				if (reference != null) {

+					return (TextAttribute) getTextAttributes()

+							.get(

+									XML_REFERENCED_CONTENT);

+				}

+			}

+		}

+		return super.getAttributeFor(collection, region);

+	}

+

+	@Override

+	protected void loadColors() {

+		super.loadColors();

+		addTextAttribute(TAG_REFERENCED_ATTRIBUTE_VALUE);

+		addTextAttribute(XML_REFERENCED_CONTENT);

+	}

+

+	/**

+	 * Looks up the colorKey in the preference store and adds the style

+	 * information to list of TextAttributes

+	 * 

+	 * @param colorKey

+	 */

+	protected void addTextAttribute(String colorKey) {

+		IPreferenceStore colorPreferences = null;

+		if (TAG_REFERENCED_ATTRIBUTE_VALUE

+				.equals(colorKey)

+				|| XML_REFERENCED_CONTENT

+						.equals(colorKey)) {

+			colorPreferences = getXMLSearchEditorColorPreferences();

+			;

+		} else {

+			colorPreferences = super.getColorPreferences();

+		}

+		if (colorPreferences != null) {

+

+			String prefString = colorPreferences.getString(colorKey);

+			String[] stylePrefs = ColorHelper

+					.unpackStylePreferences(prefString);

+			if (stylePrefs != null) {

+				RGB foreground = ColorHelper.toRGB(stylePrefs[0]);

+				RGB background = ColorHelper.toRGB(stylePrefs[1]);

+				boolean bold = Boolean.valueOf(stylePrefs[2]).booleanValue();

+				boolean italic = Boolean.valueOf(stylePrefs[3]).booleanValue();

+				boolean strikethrough = Boolean.valueOf(stylePrefs[4])

+						.booleanValue();

+				boolean underline = Boolean.valueOf(stylePrefs[5])

+						.booleanValue();

+				int style = SWT.NORMAL;

+				if (bold) {

+					style = style | SWT.BOLD;

+				}

+				if (italic) {

+					style = style | SWT.ITALIC;

+				}

+				if (strikethrough) {

+					style = style | TextAttribute.STRIKETHROUGH;

+				}

+				if (underline) {

+					style = style | TextAttribute.UNDERLINE;

+				}

+

+				TextAttribute createTextAttribute = createTextAttribute(

+						foreground, background, style);

+				getTextAttributes().put(colorKey, createTextAttribute);

+			}

+		}

+	}

+

+	protected IPreferenceStore getXMLSearchEditorColorPreferences() {

+		return XMLSearchEditorPlugin.getDefault().getPreferenceStore();

+	}

+

+	@Override

+	protected void registerPreferenceManager() {

+		super.registerPreferenceManager();

+		IPreferenceStore pref = getXMLSearchEditorColorPreferences();

+		if (pref != null) {

+			pref.addPropertyChangeListener(fPreferenceListener);

+		}

+	}

+

+	@Override

+	protected void unRegisterPreferenceManager() {

+		super.unRegisterPreferenceManager();

+		IPreferenceStore pref = getXMLSearchEditorColorPreferences();

+		if (pref != null) {

+			pref.removePropertyChangeListener(fPreferenceListener);

+		}

+	}

+

+	@Override

+	protected void handlePropertyChange(PropertyChangeEvent event) {

+		String styleKey = null;

+

+		if (event != null) {

+			String prefKey = event.getProperty();

+			// check if preference changed is a style preference

+			if (TAG_REFERENCED_ATTRIBUTE_VALUE

+					.equals(prefKey)) {

+				styleKey = TAG_REFERENCED_ATTRIBUTE_VALUE;

+			} else if (XML_REFERENCED_CONTENT

+					.equals(prefKey)) {

+				styleKey = XML_REFERENCED_CONTENT;

+			} else if (ENABLED_COLOR

+					.equals(prefKey)) {

+				if (fRecHighlighter != null)

+					fRecHighlighter.refreshDisplay();				

+			}

+		}

+

+		if (styleKey != null) {

+			// overwrite style preference with new value

+			addTextAttribute(styleKey);

+			// force a full update of the text viewer

+			if (fRecHighlighter != null)

+				fRecHighlighter.refreshDisplay();

+		} else {

+			super.handlePropertyChange(event);

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/DocumentHelper.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/DocumentHelper.java
new file mode 100644
index 0000000..ec432b7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/DocumentHelper.java
@@ -0,0 +1,61 @@
+package org.eclipse.wst.xml.search.editor.internal.util;

+

+import org.eclipse.jface.text.BadLocationException;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.Region;

+

+public class DocumentHelper {

+

+	public static class StringArgument {

+

+		private final IRegion region;

+		private final String matchingString;

+

+		public StringArgument(IRegion region, String matchingString) {

+			this.region = region;

+			this.matchingString = matchingString;

+		}

+

+		public IRegion getRegion() {

+			return region;

+		}

+

+		public String getMatchingString() {

+			return matchingString;

+		}

+

+	}

+

+	public static StringArgument findStringArgument(IDocument document, int offset,

+			boolean full) {

+		boolean stop = false;

+		StringBuilder matchingString = new StringBuilder("");

+		IRegion region = null;

+		String s = null;

+		try {

+			final IRegion li = document.getLineInformationOfOffset(offset);

+			for (int i = offset - 1; i >= li.getOffset() && !stop; i--) {

+				s = document.get(i, 1);

+				if (s.equals("\"")) {

+					stop = true;

+				}

+				if (!stop) {

+					matchingString.insert(0, s);

+				} else {

+					for (int j = offset; j <= li.getOffset() + li.getLength(); j++) {

+						s = document.get(j, 1);

+						if (s.equals("\"")) {

+							region = new Region(i + 1, j - i - 1);

+							return new StringArgument(region, matchingString.toString());

+						} else if (full) {

+							matchingString.append(s);

+						}

+					}

+				}

+			}

+		} catch (final BadLocationException e) {

+		}		

+		return null;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/EditorUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/EditorUtils.java
new file mode 100644
index 0000000..c55530a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/EditorUtils.java
@@ -0,0 +1,193 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.util;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IMarker;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IAdaptable;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.NullProgressMonitor;

+import org.eclipse.core.runtime.Path;

+import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;

+import org.eclipse.jface.action.IStatusLineManager;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.ui.IEditorPart;

+import org.eclipse.ui.IWorkbenchPage;

+import org.eclipse.ui.IWorkbenchWindow;

+import org.eclipse.ui.PartInitException;

+import org.eclipse.ui.ide.IDE;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.storage.StructuredStorageModelManager;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;

+

+public class EditorUtils {

+

+	public static final IProgressMonitor getProgressMonitor() {

+		IWorkbenchWindow activeWorkbenchWindow = XMLSearchEditorPlugin

+				.getActiveWorkbenchWindow();

+		if (activeWorkbenchWindow == null)

+			return new NullProgressMonitor();

+		IEditorPart editor = activeWorkbenchWindow.getActivePage()

+				.getActiveEditor();

+		if (editor != null

+				&& editor.getEditorSite() != null

+				&& editor.getEditorSite().getActionBars() != null

+				&& editor.getEditorSite().getActionBars()

+						.getStatusLineManager() != null

+				&& editor.getEditorSite().getActionBars()

+						.getStatusLineManager().getProgressMonitor() != null) {

+			IStatusLineManager manager = editor.getEditorSite().getActionBars()

+					.getStatusLineManager();

+			IProgressMonitor monitor = manager.getProgressMonitor();

+			manager.setMessage("Processing completion proposals");

+			manager.setCancelEnabled(true);

+			return monitor;

+		} else {

+			return new NullProgressMonitor();

+		}

+	}

+

+	public static String prepareMatchString(ContentAssistRequest request) {

+		String matchString = request.getMatchString();

+		return prepareMatchString(matchString);

+	}

+

+	public static String prepareMatchString(String matchString) {

+		if (matchString == null)

+			matchString = "";

+		if (matchString.length() > 0

+				&& (matchString.startsWith("\"") || matchString.startsWith("'")))

+			matchString = matchString.substring(1);

+		return matchString;

+	}

+

+	public static IFile getFile(ContentAssistRequest request) {

+		if (request == null) {

+			return null;

+		}

+

+		IStructuredDocumentRegion region = request.getDocumentRegion();

+		if (region == null) {

+			return null;

+		}

+

+		IDocument document = region.getParentDocument();

+		return DOMUtils.getFile(document);

+	}

+

+	public static IEditorPart openInEditor(IDOMNode node) {

+		IStorage storage = StructuredStorageModelManager.getModelManager()

+				.getStorage(node.getModel());

+		if (storage != null) {

+			return openStorageInEditor(node, storage);

+		}

+		return openFileInEditor(node, node.getModel().getBaseLocation());

+	}

+

+	private static IEditorPart openFileInEditor(IDOMNode node,

+			String baseLocation) {

+		IFile xmlFile = ResourcesPlugin.getWorkspace().getRoot().getFile(

+				new Path(baseLocation));

+		if (xmlFile.exists()) {

+			return openInEditor(xmlFile, node.getStartOffset(), node

+					.getLength(), true);

+		}

+		return null;

+	}

+

+	public static IEditorPart openInEditor(IFile file, int start, int length,

+			boolean activate) {

+		IEditorPart editor = null;

+		IWorkbenchPage page = XMLSearchEditorPlugin.getActivePage();

+		try {

+			if (start > 0) {

+				editor = IDE.openEditor(page, file, activate);

+				ITextEditor textEditor = null;

+				if (editor instanceof ITextEditor)

+					textEditor = (ITextEditor) editor;

+				else if (editor instanceof IAdaptable)

+					textEditor = (ITextEditor) editor

+							.getAdapter(ITextEditor.class);

+				if (textEditor != null) {

+					IDocument document = textEditor.getDocumentProvider()

+							.getDocument(editor.getEditorInput());

+					// int start = document.getLineOffset(line - 1);

+					textEditor.selectAndReveal(start, length);

+					page.activate(editor);

+				} else {

+					IMarker marker = file

+							.createMarker("org.eclipse.core.resources.textmarker");

+					marker.setAttribute("lineNumber", start);

+					editor = IDE.openEditor(page, marker, activate);

+					marker.delete();

+				}

+			} else {

+				editor = IDE.openEditor(page, file, activate);

+			}

+		} catch (CoreException e) {

+			Trace.trace(Trace.SEVERE, e.getMessage(), e);

+		}

+		return editor;

+	}

+

+	private static IEditorPart openStorageInEditor(IDOMNode node,

+			IStorage storage) {

+		return openInEditor(storage, node.getStartOffset(), node.getLength(),

+				true);

+	}

+

+	public static IEditorPart openInEditor(IStorage storage, int start,

+			int length, boolean activate) {

+		IEditorPart editor = null;

+		try {

+			editor = EditorUtility.openInEditor(storage, activate);

+		} catch (PartInitException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+		if (editor == null) {

+			return null;

+		}

+		if (start > 0) {

+			ITextEditor textEditor = null;

+			if (editor instanceof ITextEditor)

+				textEditor = (ITextEditor) editor;

+			else if (editor instanceof IAdaptable)

+				textEditor = (ITextEditor) editor.getAdapter(ITextEditor.class);

+			if (textEditor != null) {

+				IDocument document = textEditor.getDocumentProvider()

+						.getDocument(editor.getEditorInput());

+				// int start = document.getLineOffset(line - 1);

+				textEditor.selectAndReveal(start, length);

+				// page.activate(editor);

+			} else {

+				// IMarker marker = file

+				// .createMarker("org.eclipse.core.resources.textmarker");

+				// marker.setAttribute("lineNumber", start);

+				// editor = IDE.openEditor(page, marker, activate);

+				// marker.delete();

+			}

+		} else {

+			// editor = IDE.openEditor(page, file, activate);

+		}

+

+		return editor;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/ExceptionHandler.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/ExceptionHandler.java
new file mode 100644
index 0000000..ec6ae1c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/internal/util/ExceptionHandler.java
@@ -0,0 +1,73 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.internal.util;

+

+import java.io.StringWriter;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.jface.dialogs.ErrorDialog;

+import org.eclipse.jface.dialogs.MessageDialog;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.wst.xml.search.editor.internal.Messages;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+

+

+public class ExceptionHandler {

+

+	private static ExceptionHandler fgInstance = new ExceptionHandler();

+

+	/**

+	 * Handles the given <code>CoreException</code>.

+	 * 

+	 * @param e

+	 *            the <code>CoreException</code> to be handled

+	 * @param parent

+	 *            the dialog window's parent shell

+	 * @param title

+	 *            the dialog window's window title

+	 * @param message

+	 *            message to be displayed by the dialog window

+	 */

+	public static void handle(CoreException e, Shell parent, String title,

+			String message) {

+		fgInstance.perform(e, parent, title, message);

+	}

+

+	protected void perform(CoreException e, Shell shell, String title,

+			String message) {

+		Trace.trace(Trace.SEVERE, message, e);

+		IStatus status = e.getStatus();

+		if (status != null) {

+			ErrorDialog.openError(shell, title, message, status);

+		} else {

+			displayMessageDialog(e.getMessage(), shell, title, message);

+		}

+	}

+

+	// ---- Helper methods

+	// -----------------------------------------------------------------------

+

+	private void displayMessageDialog(String exceptionMessage, Shell shell,

+			String title, String message) {

+		StringWriter msg = new StringWriter();

+		if (message != null) {

+			msg.write(message);

+			msg.write("\n\n"); //$NON-NLS-1$

+		}

+		if (exceptionMessage == null || exceptionMessage.length() == 0)

+			msg.write(Messages.ExceptionDialog_seeErrorLogMessage);

+		else

+			msg.write(exceptionMessage);

+		MessageDialog.openError(shell, title, msg.toString());

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaElementMatcher.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaElementMatcher.java
new file mode 100644
index 0000000..3a1f712
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaElementMatcher.java
@@ -0,0 +1,22 @@
+package org.eclipse.wst.xml.search.editor.java;

+

+import org.eclipse.jdt.core.IJavaElement;

+

+public interface IJavaElementMatcher {

+

+	public static IJavaElementMatcher TRUE_MATCHER = new IJavaElementMatcher() {

+

+		public boolean match(IJavaElement element) {

+			return true;

+		}

+	};

+

+	public static IJavaElementMatcher FALSE_MATCHER = new IJavaElementMatcher() {

+

+		public boolean match(IJavaElement element) {

+			return true;

+		}

+	};

+

+	boolean match(IJavaElement element);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaReference.java
new file mode 100644
index 0000000..bb3946c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/IJavaReference.java
@@ -0,0 +1,7 @@
+package org.eclipse.wst.xml.search.editor.java;

+

+import org.eclipse.wst.xml.search.editor.references.IReference;

+

+public interface IJavaReference extends IReference, IJavaElementMatcher {

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReference.java
new file mode 100644
index 0000000..36e7954
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReference.java
@@ -0,0 +1,18 @@
+package org.eclipse.wst.xml.search.editor.java;

+

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.wst.xml.search.editor.references.AbstractReference;

+

+public class JavaReference extends AbstractReference implements IJavaReference {

+

+	private final IJavaElementMatcher matcher;

+

+	public JavaReference(IJavaElementMatcher matcher) {

+		this.matcher = matcher;

+	}

+

+	public boolean match(IJavaElement element) {

+		return matcher.match(element);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencePathFactory.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencePathFactory.java
new file mode 100644
index 0000000..f615b94
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencePathFactory.java
@@ -0,0 +1,27 @@
+package org.eclipse.wst.xml.search.editor.java;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencePathFactory;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+

+public class JavaReferencePathFactory {

+

+	private static final String MATCHER_ID = "matcherId";

+	public static final JavaReferencePathFactory INSTANCE = new JavaReferencePathFactory();

+

+	public IJavaReference createReference(IConfigurationElement element) {

+		IJavaElementMatcher matcher = getMatcher(element);

+		return new JavaReference(matcher);

+	}

+

+	private IJavaElementMatcher getMatcher(IConfigurationElement element) {

+		String matcherId = element.getAttribute(MATCHER_ID);

+		return JavaReferencesMatchersManager.getInstance().getMatcher(matcherId);

+	}

+

+	public IXMLReferenceTo createTo(IConfigurationElement element,

+			IJavaReference reference) {

+		return XMLReferencePathFactory.INSTANCE.createTo(element, reference);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesManager.java
new file mode 100644
index 0000000..0217865
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesManager.java
@@ -0,0 +1,134 @@
+package org.eclipse.wst.xml.search.editor.java;

+

+import java.util.ArrayList;

+import java.util.Collection;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.references.AbstractReferencesManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+

+public class JavaReferencesManager extends

+		AbstractReferencesManager<IJavaReference, IJavaElement> {

+

+	private static final JavaReferencesManager INSTANCE = new JavaReferencesManager();

+	private static final String JAVA_REFERENCES_EXTENSION_POINT = "javaReferences";

+

+	public static JavaReferencesManager getInstance() {

+		return INSTANCE;

+	}

+

+	private Collection<IJavaReference> references;

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (references == null) // not loaded yet

+			return;

+

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addJavaReferences(references, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	private synchronized void addJavaReferences(

+			Collection<IJavaReference> references, IConfigurationElement[] cf) {

+		for (IConfigurationElement ce : cf) {

+			if (REFERENCES_ELT.equals(ce.getName())) {

+

+				for (IConfigurationElement referenceDecl : ce.getChildren()) {

+					parseReferenceDecl(referenceDecl, references);

+				}

+			}

+		}

+	}

+

+	private void parseReferenceDecl(IConfigurationElement referenceDecl,

+			Collection<IJavaReference> references) {

+		try {

+			IJavaReference reference = null;

+			IXMLReferenceTo referenceTo = null;

+			// IXMLExpressionParser parser = getParser(referenceDecl);

+			// IXMLSearcher expressionSearcher = getSearcher(referenceDecl,

+			// DEFAULT_SEARCHER_FOR_EXPRESSION);

+			// reference declaration,

+			// loop for to get from+to declaration

+			for (IConfigurationElement fromOrTo : referenceDecl.getChildren()) {

+				if (FROM_ELT.equals(fromOrTo.getName())) {

+					reference = JavaReferencePathFactory.INSTANCE

+							.createReference(fromOrTo);

+				} else if (reference != null) {

+					referenceTo = JavaReferencePathFactory.INSTANCE.createTo(

+							fromOrTo, reference);

+					if (referenceTo != null) {

+						reference.addTo(referenceTo);

+					}

+				}

+			}

+			if (reference != null) {

+				registerJavaReference(reference, references);

+			}

+		} catch (Throwable t) {

+			Trace.trace(Trace.SEVERE, "  Could not load references", t);

+		}

+	}

+

+	public void registerJavaReference(IJavaReference reference) {

+		loadJavaReferencesIfNeeded();

+		registerJavaReference(reference, references);

+	}

+

+	private void registerJavaReference(IJavaReference reference,

+			Collection<IJavaReference> references) {

+		references.add(reference);

+

+	}

+

+	@Override

+	public IJavaReference getXMLReference(IJavaElement node,

+			String contentTypeId) {

+		loadJavaReferencesIfNeeded();

+		for (IJavaReference reference : references) {

+			if (reference.match(node)) {

+				return reference;

+			}

+		}

+		return null;

+	}

+

+	private void loadJavaReferencesIfNeeded() {

+		if (references == null) {

+			loadJavaReferences();

+		}

+	}

+

+	private synchronized void loadJavaReferences() {

+		if (references != null) {

+			return;

+		}

+		Collection<IJavaReference> references = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					getPluginId(), JAVA_REFERENCES_EXTENSION_POINT);

+			references = new ArrayList<IJavaReference>(cf.length);

+			addJavaReferences(references, cf);

+		} else {

+			references = new ArrayList<IJavaReference>();

+		}

+		this.references = references;

+		super.addRegistryListenerIfNeeded();

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return JAVA_REFERENCES_EXTENSION_POINT;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesMatchersManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesMatchersManager.java
new file mode 100644
index 0000000..6b866c8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/JavaReferencesMatchersManager.java
@@ -0,0 +1,118 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.java;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+

+public class JavaReferencesMatchersManager extends AbstractRegistryManager {

+

+	private static final JavaReferencesMatchersManager INSTANCE = new JavaReferencesMatchersManager();

+	private static final String JAVA_REFERENCES_MATCHERS_EXTENSION_POINT = "javaReferencesMatchers";

+

+	private Map<String, IJavaElementMatcher> matchersById = null;

+

+	public static JavaReferencesMatchersManager getInstance() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (matchersById == null) // not loaded yet

+			return;

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addQuerySpecifications(matchersById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	public IJavaElementMatcher getMatcher(

+			String querySpecificationId) {

+		if (StringUtils.isEmpty(querySpecificationId)) {

+			return IJavaElementMatcher.TRUE_MATCHER;

+		}

+		if (matchersById == null) {

+			loadQuerySpecifications();

+		}

+

+		IJavaElementMatcher querySpecification = matchersById

+				.get(querySpecificationId);

+		if (querySpecification == null) {

+			querySpecification = IJavaElementMatcher.TRUE_MATCHER;

+			matchersById.put(querySpecificationId,

+					querySpecification);

+		}

+		return querySpecification;

+	}

+

+	private synchronized void loadQuerySpecifications() {

+		if (matchersById != null) {

+			return;

+		}

+

+		Map<String, IJavaElementMatcher> querySpecificationsById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchEditorPlugin.PLUGIN_ID,

+					JAVA_REFERENCES_MATCHERS_EXTENSION_POINT);

+			querySpecificationsById = new HashMap<String, IJavaElementMatcher>(

+					cf.length);

+			addQuerySpecifications(querySpecificationsById, cf);

+		} else {

+			querySpecificationsById = new HashMap<String, IJavaElementMatcher>();

+		}

+		this.matchersById = querySpecificationsById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	private synchronized void addQuerySpecifications(

+			Map<String, IJavaElementMatcher> querySpecificationsById,

+			IConfigurationElement[] cf) {

+		String id = null;

+		IJavaElementMatcher querySpecification = null;

+		for (IConfigurationElement ce : cf) {

+			// querySpecification declaration,

+			id = ce.getAttribute("id");

+			try {

+				querySpecification = (IJavaElementMatcher)ce.createExecutableExtension("class");

+				querySpecificationsById.put(id, querySpecification);

+			} catch (Throwable t) {

+				Trace.trace(Trace.SEVERE,

+						"  Could not load querySpecification for id: " + id, t);

+			}

+		}

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchEditorPlugin.PLUGIN_ID;

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return JAVA_REFERENCES_MATCHERS_EXTENSION_POINT;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hover/Java2XHover.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hover/Java2XHover.java
new file mode 100644
index 0000000..3cec4b8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hover/Java2XHover.java
@@ -0,0 +1,119 @@
+package org.eclipse.wst.xml.search.editor.java.hover;

+

+import java.util.Collection;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.jdt.core.ICompilationUnit;

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;

+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;

+import org.eclipse.jdt.ui.text.java.hover.IJavaEditorTextHover;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.ITextViewer;

+import org.eclipse.ui.IEditorPart;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper;

+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper.StringArgument;

+import org.eclipse.wst.xml.search.editor.java.IJavaReference;

+import org.eclipse.wst.xml.search.editor.java.JavaReferencesManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+

+public class Java2XHover implements IJavaEditorTextHover {

+

+	private IEditorPart editor;

+	

+	public String getHoverInfo(final ITextViewer textViewer, final IRegion region) {

+		Assert.isNotNull(textViewer);

+		Assert.isNotNull(region);

+

+		final int offset = region.getOffset();

+

+		final IDocument document = textViewer.getDocument();

+		if (document == null) {

+			return null;

+		}

+

+		ICompilationUnit compilationUnit = (ICompilationUnit)EditorUtility.getEditorInputJavaElement(

+				editor, false);

+		if (compilationUnit == null) {

+			return null;

+		}

+

+		IFile file = null;

+		IJavaElement selectedNode = null;

+		try {

+			selectedNode = compilationUnit

+					.getElementAt(offset);

+			file = (IFile) compilationUnit.getCorrespondingResource();

+		} catch (JavaModelException e) {

+			e.printStackTrace();

+		}

+		if (selectedNode == null) {

+			return null;

+		}

+

+		

+		IJavaReference reference = JavaReferencesManager.getInstance()

+				.getXMLReference(selectedNode, null);

+		if (reference == null) {

+			return null;

+		} 

+		StringArgument stringArgument = DocumentHelper.findStringArgument(

+				document, offset, true);

+		if (stringArgument == null) {

+			return null;

+		}

+		

+		StringBuilder infos = null;

+		if (reference.isExpression()) {

+			IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;

+			IXMLSearcher searcher = expression.getSearcher();

+			if (searcher != null) {

+				String textInfo = searcher.searchForTextHover(selectedNode,

+						-1, stringArgument.getMatchingString(), -1, -1, file, expression);

+				infos = getTextHover(infos, textInfo);

+			}

+		} else {

+			Collection<IXMLReferenceTo> to = reference.getTo();

+			for (IXMLReferenceTo referenceTo : to) {

+				IXMLSearcher searcher = referenceTo.getSearcher();

+				if (searcher != null) {

+					String textInfo = searcher.searchForTextHover(

+							selectedNode, -1, stringArgument.getMatchingString(), -1, -1, file,

+							referenceTo);

+					infos = getTextHover(infos, textInfo);

+				}

+			}

+		}

+

+		if (infos != null && infos.length() > 0) {

+			return infos.toString();

+		}

+		return null;

+	}

+

+	public IRegion getHoverRegion(final ITextViewer textViewer, final int offset) {

+		return null;

+	}

+

+	public void setEditor(IEditorPart paramIEditorPart) {

+		editor = paramIEditorPart;		

+	}

+

+	private StringBuilder getTextHover(StringBuilder infos, String textInfo) {

+		if (!StringUtils.isEmpty(textInfo)) {

+			if (infos == null) {

+				infos = new StringBuilder();

+			} else {

+				infos.append("<br /><br />");

+			}

+			infos.append(textInfo);

+		}

+		return infos;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hyperlink/Java2XHyperLinkDetectetor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hyperlink/Java2XHyperLinkDetectetor.java
new file mode 100644
index 0000000..dfa8c01
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/java/hyperlink/Java2XHyperLinkDetectetor.java
@@ -0,0 +1,124 @@
+package org.eclipse.wst.xml.search.editor.java.hyperlink;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.jdt.core.ICompilationUnit;

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;

+import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;

+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.AbstractHyperlinkDetector;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper;

+import org.eclipse.wst.xml.search.editor.internal.util.DocumentHelper.StringArgument;

+import org.eclipse.wst.xml.search.editor.java.IJavaReference;

+import org.eclipse.wst.xml.search.editor.java.JavaReferencesManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+

+public class Java2XHyperLinkDetectetor extends AbstractHyperlinkDetector {

+

+	public IHyperlink[] detectHyperlinks(final ITextViewer textViewer,

+			final IRegion region, final boolean canShowMultipleHyperlinks) {

+		if ((region == null) || (textViewer == null)) {

+			return null;

+		}

+		final int offset = region.getOffset();

+

+		final IDocument document = textViewer.getDocument();

+		if (document == null) {

+			return null;

+		}

+		final JavaEditor editor = (JavaEditor) getAdapter(JavaEditor.class);

+		Assert.isNotNull(editor);

+

+		ICompilationUnit compilationUnit = (ICompilationUnit)EditorUtility.getEditorInputJavaElement(

+				editor, false);

+		if (compilationUnit == null) {

+			return null;

+		}

+

+		IFile file = null;

+		IJavaElement selectedNode = null;

+		try {

+			selectedNode = compilationUnit

+					.getElementAt(offset);

+			file = (IFile) compilationUnit.getCorrespondingResource();

+		} catch (JavaModelException e) {

+			e.printStackTrace();

+		}

+		if (selectedNode == null) {

+			return null;

+		}

+

+		

+		IJavaReference reference = JavaReferencesManager.getInstance()

+				.getXMLReference(selectedNode, null);

+		if (reference == null) {

+			return null;

+		}

+		List<IHyperlink> hyperLinks = new ArrayList<IHyperlink>();

+		ITextEditor textEditor = (ITextEditor) getAdapter(ITextEditor.class);

+

+		StringArgument stringArgument = DocumentHelper.findStringArgument(

+				document, offset, true);

+		if (stringArgument == null) {

+			return null;

+		}

+		IRegion hyperlinkRegion = stringArgument.getRegion();

+		String matchingString = stringArgument.getMatchingString();

+		if (reference.isExpression()) {

+			IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;

+			IXMLSearcher searcher = expression.getSearcher();

+			if (searcher != null) {

+				searcher.searchForHyperlink(selectedNode, offset,

+						matchingString, -1, -1, file, expression,

+						hyperlinkRegion, hyperLinks, textEditor);

+			}

+		} else {

+

+			Collection<IXMLReferenceTo> toPath = reference.getTo();

+			for (IXMLReferenceTo referenceTo : toPath) {

+				IXMLSearcher searcher = referenceTo.getSearcher();

+				if (searcher != null) {

+					searcher.searchForHyperlink(selectedNode, offset,

+							matchingString, -1, -1, file, referenceTo,

+							hyperlinkRegion, hyperLinks, textEditor);

+				}

+			}

+		}

+		if (hyperLinks.size() == 0) {

+			return null;

+		}

+		return hyperLinks.toArray(new IHyperlink[hyperLinks.size()]);

+	}

+

+	public static IRegion findStringArgumentInJava(final IDocument document,

+			final int offset) {

+		try {

+			final IRegion li = document.getLineInformationOfOffset(offset);

+			for (int i = offset - 1; i >= li.getOffset(); i--) {

+				if (document.get(i, 1).equals("\"")) {

+					for (int j = offset; j <= li.getOffset() + li.getLength(); j++) {

+						if (document.get(j, 1).equals("\"")) {

+							return new Region(i + 1, j - i - 1);

+						}

+					}

+				}

+			}

+		} catch (final BadLocationException e) {

+		}

+		return null;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectOutputFolder.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectOutputFolder.java
new file mode 100644
index 0000000..b907d7f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectOutputFolder.java
@@ -0,0 +1,27 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.queryspecifications;

+

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IResourceProvider;

+import org.eclipse.wst.xml.search.editor.util.JdtUtils;

+

+public class JavaProjectOutputFolder implements IResourceProvider {

+

+	public static final IResourceProvider INSTANCE = new JavaProjectOutputFolder();

+

+	public IResource getResource(Object selectedNode, IResource resource) {

+		IProject project = resource.getProject();

+		return JdtUtils.getJavaProjectOutputFolder(project);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectSrcFolders.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectSrcFolders.java
new file mode 100644
index 0000000..46070be
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/JavaProjectSrcFolders.java
@@ -0,0 +1,27 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.queryspecifications;

+

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;

+import org.eclipse.wst.xml.search.editor.util.JdtUtils;

+

+public class JavaProjectSrcFolders implements IMultiResourceProvider {

+

+	public static final IMultiResourceProvider INSTANCE = new JavaProjectSrcFolders();

+

+	public IResource[] getResources(Object selectedNode, IResource resource) {

+		IProject project = resource.getProject();

+		return JdtUtils.getJavaProjectSrcFolders(project);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/visitor/XPathPathNodeSetSearchVisitorWithFilter.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/visitor/XPathPathNodeSetSearchVisitorWithFilter.java
new file mode 100644
index 0000000..e230823
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/queryspecifications/visitor/XPathPathNodeSetSearchVisitorWithFilter.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.queryspecifications.visitor;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.XPathNodeSetSearchVisitor;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+

+public class XPathPathNodeSetSearchVisitorWithFilter extends

+		XPathNodeSetSearchVisitor {

+

+	private final IXMLReferenceFilter filter;

+

+	public XPathPathNodeSetSearchVisitorWithFilter(IXMLReferenceFilter filter) {

+		this.filter = filter;

+	}

+

+	@Override

+	protected boolean canAddNode(IDOMNode nodeToAdd, Object selectedNode) {

+		return filter.accept(nodeToAdd);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReference.java
new file mode 100644
index 0000000..c5f108f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReference.java
@@ -0,0 +1,95 @@
+package org.eclipse.wst.xml.search.editor.references;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencePath;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToJava;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToJavaMethod;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToProperty;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToResource;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToStatic;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+

+public abstract class AbstractReference extends ArrayList<IXMLReferenceTo> implements IReference {

+

+	public List<IXMLReferenceTo> getTo() {

+		return this;

+	}

+

+	public IReference addTo(IXMLReferenceTo to) {

+		super.add(to);

+		return this;

+	}

+

+	public IXMLReferenceToXML createToXML(

+			String id,

+			IXMLSearcher searcher,

+			String path,

+			String targetNodes,

+			Namespaces namespaces,

+			String querySpecificationId,

+			String tokenId,

+			IXMLReferenceFilter filter,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {

+		return new XMLReferencePath(this, id, searcher, path, targetNodes

+				.split(","), namespaces, querySpecificationId, tokenId, filter,

+				additionalProposalInfoProvider);

+	}

+

+	public IXMLReferenceToResource createToResource(

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider) {

+		return new XMLReferenceToResource(this, id, searcher,

+				querySpecificationId, tokenId, additionalProposalInfoProvider);

+	}

+

+	public IXMLReferenceToJava createToJava(String id, IXMLSearcher searcher,

+			String querySpecificationId, String tokenId,

+			IJavaQuerySpecification querySpecification) {

+		return new XMLReferenceToJava(this, id, searcher, querySpecificationId,

+				querySpecification, tokenId);

+	}

+

+	public IXMLReferenceToJavaMethod createToJavaMethod(String id,

+			IXMLSearcher searcher, String querySpecificationId, String tokenId,

+			String pathForClass,

+			IJavaMethodQuerySpecification querySpecification) {

+		return new XMLReferenceToJavaMethod(this, id, searcher,

+				querySpecificationId, pathForClass, querySpecification, tokenId);

+	}

+

+	public IXMLReferenceToStatic createToStatic(

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {

+		return new XMLReferenceToStatic(this, id, searcher,

+				querySpecificationId, tokenId, additionalProposalInfoProvider);

+	}

+

+	public IXMLReferenceToProperty createToProperty(

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider) {

+		return new XMLReferenceToProperty(this, id, searcher,

+				querySpecificationId, tokenId, additionalProposalInfoProvider);

+	}

+

+	public boolean isExpression() {

+		return false;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReferencesManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReferencesManager.java
new file mode 100644
index 0000000..6ba2c64
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/AbstractReferencesManager.java
@@ -0,0 +1,20 @@
+package org.eclipse.wst.xml.search.editor.references;

+

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.w3c.dom.Node;

+

+public abstract class AbstractReferencesManager<T extends IReference, E> extends AbstractRegistryManager {

+

+	protected static final String REFERENCES_ELT = "references";

+	// from

+	protected static final String FROM_ELT = "from";

+

+	

+	@Override

+	protected String getPluginId() {

+		return XMLSearchEditorPlugin.PLUGIN_ID;

+	}

+	

+	public abstract T getXMLReference(E node, String contentTypeId);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IReference.java
new file mode 100644
index 0000000..6bd9a28
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IReference.java
@@ -0,0 +1,61 @@
+package org.eclipse.wst.xml.search.editor.references;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+

+public interface IReference {

+

+	List<IXMLReferenceTo> getTo();

+	

+	IReference addTo(IXMLReferenceTo to);

+	

+	IXMLReferenceToXML createToXML(

+			String id,

+			IXMLSearcher searcher,

+			String path,

+			String targetNodes,

+			Namespaces namespaces,

+			String querySpecificationId,

+			String tokenId,

+			IXMLReferenceFilter filter,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider);

+

+	IXMLReferenceToResource createToResource(

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<IResource> additionalProposalInfoProvider);

+

+	IXMLReferenceToJava createToJava(String id, IXMLSearcher searcher,

+			String querySpecificationId, String tokenId,

+			IJavaQuerySpecification querySpecification);

+

+	IXMLReferenceToJavaMethod createToJavaMethod(String id,

+			IXMLSearcher searcher, String querySpecificationId, String tokenId,

+			String pathForClass,

+			IJavaMethodQuerySpecification querySpecification);

+

+	IXMLReferenceToStatic createToStatic(

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider);

+

+	IXMLReferenceToProperty createToProperty(

+			String id,

+			IXMLSearcher searcher,

+			String querySpecificationId,

+			String tokenId,

+			IContentAssistAdditionalProposalInfoProvider<?> additionalProposalInfoProvider);

+

+	boolean isExpression();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReference.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReference.java
new file mode 100644
index 0000000..68ca685
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReference.java
@@ -0,0 +1,32 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.java.IJavaQuerySpecification;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+

+public interface IXMLReference extends IReference {

+

+	IXMLReferencePath getFrom();

+	

+	String[] getContentTypeIds();

+

+	IXMLReferenceValidator getValidator();

+	

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferencePath.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferencePath.java
new file mode 100644
index 0000000..6b7177a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferencePath.java
@@ -0,0 +1,46 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import java.util.List;

+

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.IStringQueryBuilder;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.w3c.dom.Node;

+

+public interface IXMLReferencePath extends IXMLReferenceTo {

+

+	String getPath();

+

+	boolean match(Node node);

+

+	String[] getTargetNodes();

+

+//	String getQuery(String value, IStringQueryBuilder builder);

+

+	String getQuery(Object selectedNode, String mathingString,

+			IStringQueryBuilder builder);

+	

+	String getQuery(Object selectedNode, String mathingString,

+			IStringQueryBuilder builder, boolean reversed);

+

+	String getKeyPath();

+

+	List<String> getWildcardValues(Object selectedNode);

+	

+	IXMLReferenceFilter getFilter();

+	

+	boolean hasWildCard();

+	

+	Namespaces getNamespaces(); 

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceTo.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceTo.java
new file mode 100644
index 0000000..96f1909
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceTo.java
@@ -0,0 +1,33 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+

+public interface IXMLReferenceTo {

+

+	public enum ToType {

+		XML, RESOURCE, JAVA, JAVA_METHOD, STATIC, PROPERTY, EXPRESSION

+	}

+

+	String getId();

+

+	ToType getType();

+

+	IReference getOwnerReference();

+

+	String getQuerySpecificationId();

+

+	String getTokenId();

+	

+	IXMLSearcher getSearcher();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToExpression.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToExpression.java
new file mode 100644
index 0000000..e0108ee
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToExpression.java
@@ -0,0 +1,23 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import java.util.List;

+

+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;

+

+public interface IXMLReferenceToExpression extends IXMLReference,

+		IXMLReferenceTo {

+

+	IXMLExpressionParser getParser();

+

+	List<IXMLReferenceTo> getTo(String tokenId);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJava.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJava.java
new file mode 100644
index 0000000..ddcc65c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJava.java
@@ -0,0 +1,17 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import org.eclipse.wst.xml.search.editor.searchers.java.IExtendedClassProvider;

+

+public interface IXMLReferenceToJava extends IXMLReferenceTo, IExtendedClassProvider {

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJavaMethod.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJavaMethod.java
new file mode 100644
index 0000000..459363f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToJavaMethod.java
@@ -0,0 +1,33 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+import org.w3c.dom.Node;

+

+public interface IXMLReferenceToJavaMethod extends IXMLReferenceTo,

+		IJavaMethodQuerySpecification {

+

+	String getPathForClass();

+

+	String getFindByAttrName();

+

+	boolean isFindByParentNode();

+	

+	String extractClassName(Node selectedNode, IFile file,

+			String xpathFactoryProviderId, NamespaceInfos namespaceInfo)

+			throws XPathExpressionException;

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToProperty.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToProperty.java
new file mode 100644
index 0000000..dd199f1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToProperty.java
@@ -0,0 +1,18 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+

+public interface IXMLReferenceToProperty extends IXMLReferenceTo {

+

+	IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToResource.java
new file mode 100644
index 0000000..c4e60b6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToResource.java
@@ -0,0 +1,19 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+

+public interface IXMLReferenceToResource extends IXMLReferenceTo {

+

+	IContentAssistAdditionalProposalInfoProvider<IResource> getAdditionalProposalInfoProvider();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToStatic.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToStatic.java
new file mode 100644
index 0000000..c1c45d4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToStatic.java
@@ -0,0 +1,18 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+

+public interface IXMLReferenceToStatic extends IXMLReferenceTo {

+

+	IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToXML.java
new file mode 100644
index 0000000..7c486f4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/IXMLReferenceToXML.java
@@ -0,0 +1,20 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+

+

+public interface IXMLReferenceToXML extends IXMLReferencePath {

+

+	IContentAssistAdditionalProposalInfoProvider<?> getAdditionalProposalInfoProvider();

+	

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencePathResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencePathResult.java
new file mode 100644
index 0000000..2ce218a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencePathResult.java
@@ -0,0 +1,35 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import java.util.ArrayList;

+import java.util.Collection;

+

+public class XMLReferencePathResult extends ArrayList<IXMLReferencePath> {

+

+	private final boolean reversed;

+

+	public XMLReferencePathResult(int size, boolean reversed) {

+		super(size);

+		this.reversed = reversed;

+	}

+

+	public XMLReferencePathResult(

+			Collection<IXMLReferencePath> referencesByPathTo, boolean reversed) {

+		super.addAll(referencesByPathTo);

+		this.reversed = reversed;

+	}

+	

+	public boolean isReversed() {

+		return reversed;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencesUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencesUtil.java
new file mode 100644
index 0000000..e5c1e97
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/XMLReferencesUtil.java
@@ -0,0 +1,121 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import java.util.Collection;

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.util.FileUtils;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReference;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;

+import org.eclipse.wst.xml.search.editor.references.filters.IXMLReferenceFilter;

+import org.eclipse.wst.xml.search.editor.references.validators.IXMLReferenceValidator;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.expressions.IXMLExpressionParser;

+import org.w3c.dom.Node;

+

+public class XMLReferencesUtil {

+

+	public static IXMLReference getXMLReference(Node node, IFile file) {

+		return getXMLReference(node, FileUtils.getContentTypeId(file));

+	}

+

+	public static IXMLReference getXMLReference(Node node, String contentTypeId) {

+		return XMLReferencesManager.getInstance().getXMLReference(node,

+				contentTypeId);

+	}

+

+	public static List<IXMLReference> getXMLReferenceInversed(Node node,

+			String contentTypeId) {

+		return XMLReferencesManager.getInstance().getXMLReferenceInversed(node,

+				contentTypeId);

+	}

+

+	public static boolean match(Node node, IXMLReferencePath referencePath) {

+		return XMLReferencesManager.getInstance().match(node, referencePath);

+	}

+

+	public static IXMLReference createXMLReference(String fromPath,

+			String fromTargetNodes, Namespaces namespaces,

+			String querySpecificationId, String[] contentTypeIds,

+			IXMLReferenceFilter filter, IXMLReferenceValidator validator) {

+		return new XMLReference(fromPath, fromTargetNodes, namespaces,

+				querySpecificationId, contentTypeIds, filter, validator);

+	}

+

+	public static IXMLReferenceToExpression createXMLReferenceToExpression(

+			String fromPath, String fromTargetNodes, Namespaces namespaces,

+			String querySpecificationId, String[] contentTypeIds,

+			IXMLReferenceFilter filter, IXMLReferenceValidator validator,

+			IXMLExpressionParser parser, IXMLSearcher expressionSearcher) {

+		return new XMLReferenceToExpression(fromPath, fromTargetNodes,

+				namespaces, querySpecificationId, contentTypeIds, filter,

+				validator, parser, expressionSearcher);

+	}

+

+	public static void registerXMLReference(IXMLReference reference) {

+		XMLReferencesManager.getInstance().registerXMReference(reference);

+	}

+

+	public static XMLReferencePathResult getXMLReferencesByPathTo(String path,

+			String contentTypeId) {

+		return new XMLReferencePathResult(XMLReferencesManager.getInstance()

+				.getXMLReferencesByPathTo(path, contentTypeId), true);

+	}

+

+	public static XMLReferencePathResult getReferencePath(Node selectedNode,

+			IFile file) {

+		return getReferencePath(selectedNode, FileUtils.getContentTypeId(file));

+	}

+

+	public static XMLReferencePathResult getReferencePath(Node selectedNode,

+			String contentTypeId) {

+		List<IXMLReference> references = XMLReferencesUtil

+				.getXMLReferenceInversed(selectedNode, contentTypeId);

+		if (references != null && references.size() > 0) {

+			XMLReferencePathResult referencePaths = new XMLReferencePathResult(

+					references.size(), false);

+			for (IXMLReference reference : references) {

+				referencePaths.add(reference.getFrom());

+			}

+			return referencePaths;

+		} else {

+			IXMLReference reference = XMLReferencesUtil.getXMLReference(

+					selectedNode, contentTypeId);

+			if (reference != null) {

+				IXMLReferencePath referencePath = null;

+				for (IXMLReferenceTo referenceTo : reference.getTo()) {

+					if (referenceTo.getType() == ToType.XML) {

+						referencePath = (IXMLReferencePath) referenceTo;

+						break;

+					}

+				}

+

+				if (referencePath != null) {

+					return XMLReferencesUtil.getXMLReferencesByPathTo(

+							referencePath.getKeyPath(), contentTypeId);

+				}

+			}

+		}

+		return null;

+	}

+

+	public static Collection<IXMLReference> getAllReferencesWithOneReferenceTo(

+			ToType toType) {

+		return XMLReferencesManager.getInstance()

+				.getAllReferencesWithOneReferenceTo(toType);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/filters/IXMLReferenceFilter.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/filters/IXMLReferenceFilter.java
new file mode 100644
index 0000000..137cafa
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/filters/IXMLReferenceFilter.java
@@ -0,0 +1,19 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references.filters;

+

+import org.w3c.dom.Node;

+

+public interface IXMLReferenceFilter {

+

+	boolean accept(Node node);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/DefaultDOMNodeValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/DefaultDOMNodeValidator.java
new file mode 100644
index 0000000..036ce3d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/DefaultDOMNodeValidator.java
@@ -0,0 +1,172 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references.validators;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;

+import org.eclipse.wst.sse.ui.internal.reconcile.validator.AnnotationInfo;

+import org.eclipse.wst.sse.ui.internal.reconcile.validator.IncrementalReporter;

+import org.eclipse.wst.validation.internal.provisional.core.IReporter;

+import org.eclipse.wst.validation.internal.provisional.core.IValidator;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.validation.IMultiValidationResult;

+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;

+import org.eclipse.wst.xml.search.editor.validation.LocalizedMessage;

+import org.eclipse.wst.xml.search.editor.validation.ValidatorUtils;

+import org.w3c.dom.Node;

+

+public class DefaultDOMNodeValidator implements IXMLReferenceValidator {

+

+	public static final IXMLReferenceValidator INSTANCE = new DefaultDOMNodeValidator();

+

+	public void validate(IXMLReference reference, IDOMNode node, IFile file,

+			IValidator validator, IReporter reporter, boolean batchMode) {

+		if (reference != null && reference.getTo().size() > 0) {

+			doValidate(reference, node, file, validator, reporter, batchMode);

+		}

+	}

+

+	private int getStartOffset(IDOMNode node) {

+		int nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			return ((IDOMAttr) node).getValueRegionStartOffset();

+		}

+		return node.getStartOffset();

+	}

+

+	protected int getNbElements(IXMLReference reference, IFile file,

+			IDOMNode node) {

+		int nbElements = 0;

+		List<IXMLReferenceTo> to = reference.getTo();

+		for (IXMLReferenceTo referenceTo : to) {

+			IXMLSearcher searcher = referenceTo.getSearcher();

+			if (searcher != null) {

+				try {

+					IValidationResult result = searcher.searchForValidation(

+							node, DOMUtils.getNodeValue(node), -1, -1, file,

+							referenceTo);

+					if (result != null) {

+						nbElements += result.getNbElements();

+					}

+				} catch (Throwable e) {

+					Trace.trace(Trace.SEVERE, e.getMessage(), e);

+				}

+			}

+		}

+		return nbElements;

+	}

+

+	protected int getSeverity(IXMLReference reference, int nbElements,

+			IFile file, IDOMNode node) {

+		return ValidatorUtils.getSeverity(reference, nbElements);

+	}

+

+	protected String getMessageText(IXMLReference reference, int nbElements,

+			Node node, String textContent) {

+		if (textContent == null) {

+			return null;

+		}

+		return ValidatorUtils

+				.getMessageText(reference, nbElements, textContent);

+	}

+

+	protected LocalizedMessage createMessage(int start, int length,

+			String messageText, int severity,

+			IStructuredDocument structuredDocument) {

+		return ValidatorUtils.createMessage(start, length, messageText,

+				severity, structuredDocument);

+	}

+

+	protected void doValidate(IXMLReference reference, IDOMNode node,

+			IFile file, IValidator validator, IReporter reporter,

+			boolean batchMode) {

+		if (reference.isExpression()) {

+			IXMLReferenceToExpression expression = (IXMLReferenceToExpression) reference;

+			IXMLSearcher searcher = expression.getSearcher();

+			if (searcher != null) {

+				try {

+					IValidationResult result = searcher.searchForValidation(

+							node, DOMUtils.getNodeValue(node), -1, -1, file,

+							expression);

+					if (result != null) {

+						IMultiValidationResult multiResult = (IMultiValidationResult) result;

+						List<IValidationResult> result2 = multiResult

+								.getResults();

+						for (IValidationResult r : result2) {

+							int nbElements = r.getNbElements();

+							if (nbElements != 1) {

+								String messageText = getMessageText(reference,

+										nbElements, node, r.getValue());

+								if (messageText != null) {

+									int severity = getSeverity(reference,

+											nbElements, file, node);

+									int startOffset = getStartOffset(node)

+											+ r.getStartIndex() + 1;

+									int length = r.getValue().length();

+									addMessage(node, file, validator, reporter,

+											batchMode, messageText, severity,

+											startOffset, length);

+								}

+							}

+						}

+					}

+				} catch (Throwable e) {

+					Trace.trace(Trace.SEVERE, e.getMessage(), e);

+				}

+			}

+			return;

+		}

+

+		int nbElements = getNbElements(reference, file, node);

+		if (nbElements == 1) {

+			return;

+		}

+		String textContent = DOMUtils.getNodeValue(node);

+		String messageText = getMessageText(reference, nbElements, node,

+				textContent);

+		if (messageText == null) {

+			return;

+		}

+		int severity = getSeverity(reference, nbElements, file, node);

+		int startOffset = getStartOffset(node);

+		int length = textContent.trim().length() + 2;

+		addMessage(node, file, validator, reporter, batchMode, messageText,

+				severity, startOffset, length);

+	}

+

+	private void addMessage(IDOMNode node, IFile file, IValidator validator,

+			IReporter reporter, boolean batchMode, String messageText,

+			int severity, int startOffset, int length) {

+		LocalizedMessage message = createMessage(startOffset, length,

+				messageText, severity, node.getStructuredDocument());

+		if (message != null) {

+			if (batchMode) {

+				message.setTargetObject(file);

+				reporter.addMessage(validator, message);

+			} else {

+				AnnotationInfo info = new AnnotationInfo(message);

+				((IncrementalReporter) reporter).addAnnotationInfo(validator,

+						info);

+			}

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/IXMLReferenceValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/IXMLReferenceValidator.java
new file mode 100644
index 0000000..b67796e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/references/validators/IXMLReferenceValidator.java
@@ -0,0 +1,23 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references.validators;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.validation.internal.provisional.core.IReporter;

+import org.eclipse.wst.validation.internal.provisional.core.IValidator;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+

+public interface IXMLReferenceValidator {

+

+	public void validate(IXMLReference reference, IDOMNode node, IFile file, IValidator validator,

+			IReporter reporter, boolean batchMode);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractContentAssisitCollector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractContentAssisitCollector.java
new file mode 100644
index 0000000..5b20d19
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractContentAssisitCollector.java
@@ -0,0 +1,49 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers;

+

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+

+public class AbstractContentAssisitCollector<T extends IXMLReferenceTo> {

+

+	protected final IContentAssistProposalRecorder recorder;

+	protected final T referencePath;

+	protected final String forceBeforeText;

+	protected final String forceEndText;

+

+	public AbstractContentAssisitCollector(String forceBeforeText,

+			String forceEndText, T referencePath,

+			IContentAssistProposalRecorder recorder) {

+		this.forceBeforeText = forceBeforeText;

+		this.forceEndText = forceEndText;

+		this.recorder = recorder;

+		this.referencePath = referencePath;

+	}

+

+	protected String getReplaceText(String replaceText) {

+		if (forceBeforeText != null) {

+			replaceText = forceBeforeText + replaceText;

+		}

+		if (forceEndText != null) {

+			replaceText = replaceText + forceEndText;

+		}

+		return replaceText;

+	}

+

+	protected int getCursorPosition(String replaceText) {

+		if (forceBeforeText != null) {

+			return forceBeforeText.length() + replaceText.length();

+		}

+		return replaceText.length();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractHyperlinkCollector.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractHyperlinkCollector.java
new file mode 100644
index 0000000..2426094
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/AbstractHyperlinkCollector.java
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers;

+

+import java.util.List;

+

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+

+public abstract class AbstractHyperlinkCollector {

+

+	protected final List<IHyperlink> hyperLinks;

+	protected final IRegion hyperlinkRegion;

+

+	public AbstractHyperlinkCollector(IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks) {

+		this.hyperlinkRegion = hyperlinkRegion;

+		this.hyperLinks = hyperLinks;

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/DefaultTextInfo.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/DefaultTextInfo.java
new file mode 100644
index 0000000..48ac257
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/DefaultTextInfo.java
@@ -0,0 +1,51 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers;

+

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+

+public class DefaultTextInfo<T extends Object> {

+

+	private StringBuilder result = null;

+	protected final IContentAssistAdditionalProposalInfoProvider<T> provider;

+

+	public DefaultTextInfo(

+			IContentAssistAdditionalProposalInfoProvider<T> provider) {

+		this.provider = provider;

+	}

+

+	public boolean add(T node) {

+		String textInfo = getTextInfo(node);

+		if (StringUtils.isEmpty(textInfo)) {

+			return true;

+		}

+		if (result == null) {

+			result = new StringBuilder();

+		} else {

+			result.append("<br/><br/>");

+		}

+		result.append(textInfo);

+		return true;

+	}

+	

+	protected String getTextInfo(T node) {

+		return provider.getTextInfo(node);

+	}

+

+	public StringBuilder getResult() {

+		return result;

+	}

+

+	public String getTextInfo() {

+		return (result != null ? result.toString() : null);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/IXMLSearcher.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/IXMLSearcher.java
new file mode 100644
index 0000000..1abacb2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/IXMLSearcher.java
@@ -0,0 +1,43 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;

+

+public interface IXMLSearcher {

+

+	void searchForCompletion(Object selectedNode, String mathingString,

+			String forceBeforeText, String forceEndText, IFile file,

+			IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder);

+

+	void searchForHyperlink(Object selectedNode, int offset,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, ITextEditor textEditor);

+

+	IValidationResult searchForValidation(Object selectedNode,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo);

+

+	String searchForTextHover(Object selectedNode, int offset,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/XMLSearcherManager.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/XMLSearcherManager.java
new file mode 100644
index 0000000..75d9de7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/XMLSearcherManager.java
@@ -0,0 +1,113 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers;

+

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionDelta;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.wst.xml.search.core.AbstractRegistryManager;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+

+public class XMLSearcherManager extends AbstractRegistryManager {

+

+	private static final String SEARCHER_ELT = "searcher";

+	private static final String ID_ATTR = "id";

+	private static final String CLASS_ATTR = "class";	

+	

+	public static final XMLSearcherManager INSTANCE = new XMLSearcherManager();

+	private static final String SEARCHERS_EXTENSION_POINT = "searchers";

+

+	private Map<String, IXMLSearcher> searchersById = null;

+

+	public static XMLSearcherManager getDefault() {

+		return INSTANCE;

+	}

+

+	@Override

+	protected void handleExtensionDelta(IExtensionDelta delta) {

+		if (searchersById == null) {// not loaded yet

+			return;

+		}

+		if (delta.getKind() == IExtensionDelta.ADDED) {

+			IConfigurationElement[] cf = delta.getExtension()

+					.getConfigurationElements();

+			addSearcher(searchersById, cf);

+		} else {

+			// TODO : remove references

+		}

+	}

+

+	private synchronized void addSearcher(

+			Map<String, IXMLSearcher> searchersById, IConfigurationElement[] cf) {

+		IXMLSearcher searcher = null;

+		String id = null;

+		for (IConfigurationElement ce : cf) {

+			// loop for to get searcher declaration

+			if (SEARCHER_ELT.equals(ce.getName())) {

+				id = ce.getAttribute(ID_ATTR);

+				try {//					

+					searcher = (IXMLSearcher) ce

+							.createExecutableExtension(CLASS_ATTR);

+					searchersById.put(id, searcher);

+				} catch (Throwable t) {

+					Trace.trace(Trace.SEVERE,

+							"  Could not load searcher for id: " + id, t);

+				}

+			}

+		}

+	}

+

+	public IXMLSearcher getSearcher(String id) {

+		if (StringUtils.isEmpty(id)) {

+			return null;

+		}

+		if (searchersById == null) {

+			loadSearchers();

+		}

+

+		return searchersById.get(id);

+	}

+

+	private synchronized void loadSearchers() {

+		if (searchersById != null) {

+			return;

+		}

+		Map<String, IXMLSearcher> searchersById = null;

+		IExtensionRegistry registry = Platform.getExtensionRegistry();

+		if (registry != null) {

+			IConfigurationElement[] cf = registry.getConfigurationElementsFor(

+					XMLSearchEditorPlugin.PLUGIN_ID, SEARCHERS_EXTENSION_POINT);

+			searchersById = new HashMap<String, IXMLSearcher>(cf.length);

+			addSearcher(searchersById, cf);

+		} else {

+			searchersById = new HashMap<String, IXMLSearcher>();

+		}

+		this.searchersById = searchersById;

+		super.addRegistryListenerIfNeeded();

+

+	}

+

+	@Override

+	protected String getExtensionPoint() {

+		return SEARCHERS_EXTENSION_POINT;

+	}

+

+	@Override

+	protected String getPluginId() {

+		return XMLSearchEditorPlugin.PLUGIN_ID;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/AbstractExpressionParser.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/AbstractExpressionParser.java
new file mode 100644
index 0000000..fcc6cac
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/AbstractExpressionParser.java
@@ -0,0 +1,64 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.expressions;

+

+import java.util.List;

+

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.w3c.dom.Node;

+

+public abstract class AbstractExpressionParser implements IXMLExpressionParser {

+

+	public static final String ALL_TOKEN = "___ALL_TOKEN";

+

+	protected SearcherToken createSearcherToken(

+			IXMLReferenceToExpression toExpression, String tokenId,

+			String realMatchingString, String beforeText, String endText) {

+		SearcherToken searcherToken = new SearcherToken(tokenId,

+				realMatchingString.toString(), beforeText, endText);

+		populateTos(toExpression, tokenId, searcherToken);

+		return searcherToken;

+	}

+

+	protected SearcherToken createSearcherToken(

+			IXMLReferenceToExpression toExpression, String tokenId,

+			String realMatchingString, int startOffsetOfStartToken) {

+		SearcherToken searcherToken = new SearcherToken(tokenId,

+				realMatchingString.toString(), startOffsetOfStartToken);

+		populateTos(toExpression, tokenId, searcherToken);

+		return searcherToken;

+	}

+	

+	protected void populateTos(IXMLReferenceToExpression toExpression,

+			String tokenId, SearcherToken searcherToken) {

+		if (tokenId != null) {

+			List<IXMLReferenceTo> tos = null;

+			if (ALL_TOKEN.equals(tokenId)) {

+				tos = toExpression.getTo();

+

+			} else {

+				tos = toExpression.getTo(tokenId);

+			}

+			if (tos != null) {

+				for (IXMLReferenceTo to : tos) {

+					searcherToken.getTos().add(to);

+				}

+			}

+		}

+	}

+

+	protected String getTokenId(Node selectedNode,

+			IXMLReferenceToExpression toExpression, String matchingString,

+			int offset) {

+		return ALL_TOKEN;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/BaseTokenExpressionParser.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/BaseTokenExpressionParser.java
new file mode 100644
index 0000000..b74008a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/BaseTokenExpressionParser.java
@@ -0,0 +1,110 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.expressions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+

+public class BaseTokenExpressionParser extends AbstractExpressionParser {

+

+	private final char token;

+

+	public BaseTokenExpressionParser(char token) {

+		this.token = token;

+	}

+

+	public SearcherToken parse(String nodeValue, String matchingString,

+			IXMLReferenceToExpression toExpression) {

+		ResultToken resultToken = new ResultToken(token, nodeValue,

+				matchingString);

+		String realMatchingString = resultToken.getRealMatchingString();

+		List<String> tokens = resultToken.getTokens();

+		String tokenId = getTokenId(tokens, getTokenIndex(tokens));

+		String beforeText = getBeforeText(nodeValue, matchingString,

+				realMatchingString, tokenId, tokens);

+		String endText = getEndText(nodeValue, resultToken.getEndToken(),

+				matchingString, tokenId, tokens);

+		return createSearcherToken(toExpression, tokenId, realMatchingString,

+				beforeText, endText);

+	}

+

+	protected String getTokenId(List<String> tokens, int tokenIndex) {

+		return ALL_TOKEN;

+	}

+

+	protected String getEndText(String nodeValue, String endToken,

+			String matchingString, String tokenId, List<String> tokens) {

+		String endText = nodeValue

+				.substring(matchingString.length() + endToken.length(),

+						nodeValue.length());

+		if (endText.length() > 0) {

+			char firstChar = endText.charAt(0);

+			if (firstChar != token) {

+				if (addTokenAtFirst(tokenId, tokens)) {

+					return token + endText;

+				}

+			}

+		}

+		return endText;

+	}

+

+	protected boolean addTokenAtFirst(String tokenId, List<String> tokens) {

+		return true;

+	}

+

+	protected int getTokenIndex(List<String> tokens) {

+		return tokens.size() > 0 ? tokens.size() - 1 : 0;

+	}

+

+	protected String getBeforeText(String nodeValue, String matchingString,

+			String realMatchingString, String tokenId, List<String> tokens) {

+		return matchingString.substring(0, matchingString.length()

+				- realMatchingString.length());

+	}

+

+	public SearcherToken[] parse(String nodeValue,

+			IXMLReferenceToExpression toExpression) {

+

+		ResultToken resultToken = new ResultToken(token, nodeValue);

+		List<String> tokens = resultToken.getTokens();

+		String tokenId = null;

+

+		List<SearcherToken> searcherTokens = new ArrayList<SearcherToken>();

+		int startOffsetOfStartToken = 0;

+		String lastToken = null;

+		int i = 0;

+		for (String token : tokens) {

+			if (lastToken != null) {

+				startOffsetOfStartToken++;

+				startOffsetOfStartToken += lastToken.length();

+			}

+			lastToken = token;

+			tokenId = getTokenId(tokens, i++);

+			searcherTokens.add(createSearcherToken(toExpression, tokenId,

+					token, startOffsetOfStartToken));

+		}

+		return searcherTokens.toArray(SearcherToken.EMPTY);

+	}

+

+	public SearcherToken parse(String nodeValue, int offset,

+			IXMLReferenceToExpression toExpression) {

+

+		ResultToken resultToken = new ResultToken(token, nodeValue, offset);

+		String realMatchingString = resultToken.getRealMatchingString();

+		List<String> tokens = resultToken.getTokens();

+		String tokenId = getTokenId(tokens, getTokenIndex(tokens));

+		return createSearcherToken(toExpression, tokenId, realMatchingString,

+				resultToken.getStartOffsetOfStartToken());

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/IXMLExpressionParser.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/IXMLExpressionParser.java
new file mode 100644
index 0000000..633415e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/IXMLExpressionParser.java
@@ -0,0 +1,28 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.expressions;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.w3c.dom.Node;

+

+public interface IXMLExpressionParser {

+

+	SearcherToken parse(String nodeValue, String matchingString,

+			IXMLReferenceToExpression toExpression);

+	

+	SearcherToken[] parse(String nodeValue, IXMLReferenceToExpression toExpression);

+

+	SearcherToken parse(String nodeValue, int offset,

+			IXMLReferenceToExpression toExpression);

+

+	

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParser.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParser.java
new file mode 100644
index 0000000..9024473
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParser.java
@@ -0,0 +1,18 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.expressions;

+

+public class MultiAttrValuesExpressionParser extends BaseTokenExpressionParser {

+

+	public MultiAttrValuesExpressionParser() {

+		super(' ');

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/ResultToken.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/ResultToken.java
new file mode 100644
index 0000000..5508cdb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/ResultToken.java
@@ -0,0 +1,177 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.expressions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+class ResultToken {

+

+	private String realMatchingString;

+	private final List<String> tokens;

+	private String endToken;

+	private int startOffsetOfStartToken = -1;

+

+	public ResultToken(char token, String nodeValue, String matchingString) {

+		this(token, nodeValue, matchingString, -1);

+	}

+

+	public ResultToken(char token, String nodeValue, int offset) {

+		this(token, nodeValue, null, offset);

+	}

+

+	public ResultToken(char token, String nodeValue) {

+		this(token, nodeValue, null, -1);

+	}

+

+	private ResultToken(char token, String nodeValue, String matchingString,

+			int offset) {

+		tokens = new ArrayList<String>();

+		if (matchingString == null && offset == -1) {

+			parse(token, nodeValue, tokens);

+		} else if (matchingString != null) {

+			parse(token, nodeValue, matchingString, tokens);

+		} else if (offset != -1) {

+			parse(token, nodeValue, offset, tokens);

+		}

+	}

+

+	private void parse(char token, String nodeValue, String matchingString,

+			List<String> tokens) {

+		char c = 'X';

+		boolean isLastCharIsSeparator = false;

+		StringBuilder currentMatch = new StringBuilder();

+		char[] chars = matchingString.toCharArray();

+		for (int i = 0; i < chars.length; i++) {

+			c = chars[i];

+			if (c == token) {

+				if (i == 0 || isLastCharIsSeparator) {

+					currentMatch.append(c);

+				} else {

+					isLastCharIsSeparator = true;

+					tokens.add(currentMatch.toString());

+					currentMatch.setLength(0);

+				}

+			} else {

+				currentMatch.append(c);

+				isLastCharIsSeparator = false;

+			}

+		}

+		if (c == token) {

+			tokens.add("");

+		} else if (currentMatch.length() > 0) {

+			tokens.add(currentMatch.toString());

+		}

+

+		char[] nodeValueChars = nodeValue.toCharArray();

+		int startChar = chars.length;

+		if (startChar < nodeValueChars.length) {

+			StringBuilder endTokenBuilder = new StringBuilder();

+			for (int i = startChar; i < nodeValueChars.length; i++) {

+				c = nodeValueChars[i];

+				if (c == token) {

+					break;

+				} else {

+					endTokenBuilder.append(c);

+				}

+			}

+			endToken = endTokenBuilder.toString();

+		}

+		realMatchingString = currentMatch.toString();

+		if (endToken == null) {

+			endToken = "";

+		}

+	}

+

+	private void parse(char token, String nodeValue, int offset,

+			List<String> tokens) {

+		this.startOffsetOfStartToken = offset;

+		char c = 'X';

+		boolean isLastCharIsSeparator = false;

+		StringBuilder currentMatch = new StringBuilder();

+		char[] nodeValueChars = nodeValue.toCharArray();

+		int i = 0;

+		for (i = 0; i < offset; i++) {

+			c = nodeValueChars[i];

+			if (c == token) {

+				if (i == 0 || isLastCharIsSeparator) {

+					currentMatch.append(c);

+				} else {

+					isLastCharIsSeparator = true;

+					tokens.add(currentMatch.toString());

+					currentMatch.setLength(0);

+				}

+			} else {

+				currentMatch.append(c);

+				isLastCharIsSeparator = false;

+			}

+		}

+		if (c == token) {

+			tokens.add("");

+		} else if (currentMatch.length() > 0) {

+			tokens.add(currentMatch.toString());

+		}

+		this.startOffsetOfStartToken = i - currentMatch.length();

+		if (offset < nodeValueChars.length) {

+			for (i = offset; i < nodeValueChars.length; i++) {

+				c = nodeValueChars[i];

+				if (c == token) {

+					break;

+				} else {

+					currentMatch.append(c);

+				}

+			}

+		}

+		realMatchingString = currentMatch.toString();

+	}

+

+	private void parse(char token, String nodeValue, List<String> tokens) {

+		char c;

+		boolean isLastCharIsSeparator = false;

+		StringBuilder currentMatch = new StringBuilder();

+		char[] nodeValueChars = nodeValue.toCharArray();

+		for (int i = 0; i < nodeValueChars.length; i++) {

+			c = nodeValueChars[i];

+			if (c == token) {

+				if (i == 0 || isLastCharIsSeparator) {

+					currentMatch.append(c);

+				} else {

+					isLastCharIsSeparator = true;

+					tokens.add(currentMatch.toString());

+					currentMatch.setLength(0);

+				}

+			} else {

+				currentMatch.append(c);

+				isLastCharIsSeparator = false;

+			}

+		}

+		if (currentMatch.length() > 0) {

+			tokens.add(currentMatch.toString());

+		}

+		

+	}

+

+	public String getRealMatchingString() {

+		return realMatchingString;

+	}

+

+	public List<String> getTokens() {

+		return tokens;

+	}

+

+	public String getEndToken() {

+		return endToken;

+	}

+

+	public int getStartOffsetOfStartToken() {

+		return startOffsetOfStartToken;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/SearcherToken.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/SearcherToken.java
new file mode 100644
index 0000000..e849bb4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/SearcherToken.java
@@ -0,0 +1,82 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.expressions;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+

+public class SearcherToken {

+

+	// private final String tokenId;

+

+	public static final SearcherToken[] EMPTY = new SearcherToken[0];

+

+	private final String tokenId;

+	private final int startOffset;

+	private final int endOffset;

+	private final String realMatchingString;

+	private final String beforeText;

+	private final String endText;

+	private final List<IXMLReferenceTo> tos;

+

+	public SearcherToken(String tokenId, String realMatchingString,

+			String beforeText, String endText) {

+		this.tokenId = tokenId;

+		this.realMatchingString = realMatchingString;

+		this.beforeText = beforeText;

+		this.endText = endText;

+		this.tos = new ArrayList<IXMLReferenceTo>();

+		this.startOffset = beforeText.length();

+		this.endOffset = startOffset + realMatchingString.length();

+	}

+

+	public SearcherToken(String tokenId, String realMatchingString,

+			int startOffsetOfStartToken) {

+		this.tokenId = tokenId;

+		this.realMatchingString = realMatchingString;

+		this.beforeText = null;

+		this.endText = null;

+		this.tos = new ArrayList<IXMLReferenceTo>();

+		this.startOffset = startOffsetOfStartToken;

+		this.endOffset = startOffset + realMatchingString.length();

+	}

+

+	public String getTokenId() {

+		return tokenId;

+	}

+

+	public List<IXMLReferenceTo> getTos() {

+		return tos;

+	}

+

+	public int getStartOffset() {

+		return startOffset;

+	}

+

+	public int getEndOffset() {

+		return endOffset;

+	}

+

+	public String getRealMatchingString() {

+		return realMatchingString;

+	}

+

+	public String getBeforeText() {

+		return beforeText;

+	}

+

+	public String getEndText() {

+		return endText;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/XMLSearcherForExpression.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/XMLSearcherForExpression.java
new file mode 100644
index 0000000..0b9f855
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/expressions/XMLSearcherForExpression.java
@@ -0,0 +1,167 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.expressions;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.validation.IMultiValidationResult;

+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;

+import org.eclipse.wst.xml.search.editor.validation.MultiValidationResult;

+

+public class XMLSearcherForExpression implements IXMLSearcher {

+

+	public static final IXMLSearcher INSTANCE = new XMLSearcherForExpression();

+

+	public void searchForCompletion(Object selectedNode, String mathingString,

+			String forceBeforeText, String forceEndText, IFile file,

+			IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {

+		IXMLReferenceToExpression toExpression = (IXMLReferenceToExpression) referenceTo;

+

+		SearcherToken token = getToken(selectedNode, mathingString,

+				toExpression);

+

+		if (token != null) {

+			List<IXMLReferenceTo> tos = token.getTos();

+			for (IXMLReferenceTo to : tos) {

+				to.getSearcher().searchForCompletion(selectedNode,

+						token.getRealMatchingString(), token.getBeforeText(),

+						token.getEndText(), file, to, recorder);

+			}

+		}

+	}

+

+	public void searchForHyperlink(Object selectedNode, int offset,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, ITextEditor textEditor) {

+		IXMLReferenceToExpression toExpression = (IXMLReferenceToExpression) referenceTo;

+

+		SearcherToken token = getToken(selectedNode, mathingString, offset,

+				toExpression);

+

+		if (token != null) {

+			List<IXMLReferenceTo> tos = token.getTos();

+			for (IXMLReferenceTo to : tos) {

+				to.getSearcher().searchForHyperlink(selectedNode, offset,

+						token.getRealMatchingString(), token.getStartOffset(),

+						token.getEndOffset(), file, to, hyperlinkRegion,

+						hyperLinks, textEditor);

+			}

+		}

+	}

+

+	public IValidationResult searchForValidation(Object selectedNode,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToExpression toExpression = (IXMLReferenceToExpression) referenceTo;

+		SearcherToken[] tokens = getTokens(selectedNode, mathingString,

+				toExpression);

+		if (tokens == null) {

+			return null;

+		}

+

+		IValidationResult v = null;

+		int nbElements = 0;

+		IMultiValidationResult result = new MultiValidationResult();

+		SearcherToken token = null;

+		for (int i = 0; i < tokens.length; i++) {

+			token = tokens[i];

+			nbElements = 0;

+			v = null;

+			List<IXMLReferenceTo> tos = token.getTos();

+			for (IXMLReferenceTo to : tos) {

+				v = to.getSearcher().searchForValidation(selectedNode,

+						token.getRealMatchingString(), token.getStartOffset(),

+						token.getEndOffset(), file, to);

+				nbElements = v.getNbElements() + nbElements;

+			}

+			if (nbElements != 1 && v != null) {

+				v.setNbElements(nbElements);

+				result.add(v);

+			}

+		}

+		return result;

+	}

+

+	public String searchForTextHover(Object selectedNode, int offset,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToExpression toExpression = (IXMLReferenceToExpression) referenceTo;

+		SearcherToken[] tokens = getTokens(selectedNode, mathingString,

+				toExpression);

+		if (tokens == null) {

+			return null;

+		}

+		StringBuilder textHover = null;

+		SearcherToken token = null;

+		for (int i = 0; i < tokens.length; i++) {

+			token = tokens[i];

+			List<IXMLReferenceTo> tos = token.getTos();

+			for (IXMLReferenceTo to : tos) {

+				String s = to.getSearcher().searchForTextHover(selectedNode,

+						offset, token.getRealMatchingString(),

+						token.getStartOffset(), token.getEndOffset(), file, to);

+				if (s != null) {

+					if (textHover == null) {

+						textHover = new StringBuilder();

+						textHover.append(s);

+					} else {

+						textHover.append("<br>");

+						textHover.append("<br>");

+						textHover.append(s);

+					}

+				}

+			}

+

+		}

+		return textHover != null ? textHover.toString() : null;

+	}

+

+	private SearcherToken getToken(Object selectedNode, String mathingString,

+			IXMLReferenceToExpression toExpression) {

+		IXMLExpressionParser parser = toExpression.getParser();

+		if (parser == null) {

+			return null;

+		}

+		return parser.parse(DOMUtils.getNodeValue((IDOMNode) selectedNode),

+				mathingString, toExpression);

+	}

+

+	private SearcherToken getToken(Object selectedNode, String mathingString,

+			int offset, IXMLReferenceToExpression toExpression) {

+		IXMLExpressionParser parser = toExpression.getParser();

+		if (parser == null) {

+			return null;

+		}

+		return parser.parse(mathingString, offset, toExpression);

+	}

+

+	protected SearcherToken[] getTokens(Object selectedNode,

+			String matchingString, IXMLReferenceToExpression toExpression) {

+		IXMLExpressionParser parser = toExpression.getParser();

+		if (parser == null) {

+			return null;

+		}

+		SearcherToken[] tokens = parser.parse(matchingString, toExpression);

+		return tokens;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/DefaultExtendedClassProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/DefaultExtendedClassProvider.java
new file mode 100644
index 0000000..455cd68
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/DefaultExtendedClassProvider.java
@@ -0,0 +1,47 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.java;

+

+import java.util.ArrayList;

+import java.util.Collection;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.wst.xml.search.editor.util.JdtUtils;

+

+public class DefaultExtendedClassProvider implements IExtendedClassProvider {

+

+	private String[] extendedClasses;

+	

+	

+	public DefaultExtendedClassProvider(String[] implementsClass) {

+		this.extendedClasses = implementsClass;

+	}

+	

+	public IType[] getExtends(Object selectedNode, IFile file) {

+		Collection<IType> types = null;

+		for (int i = 0; i < extendedClasses.length; i++) {

+			String className = extendedClasses[i];

+			IType type = JdtUtils.getJavaType(file.getProject(), className);

+			if (type != null) {

+				if (types == null) {

+					types = new ArrayList<IType>();

+				}

+				types.add(type);

+			}

+		}

+		if (types != null) {

+			return types.toArray(JdtUtils.EMPTY_TYPE);

+		}

+		return null;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IExtendedClassProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IExtendedClassProvider.java
new file mode 100644
index 0000000..04d8173
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IExtendedClassProvider.java
@@ -0,0 +1,19 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.java;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jdt.core.IType;

+

+public interface IExtendedClassProvider {

+

+	IType[] getExtends(Object selectedNode, IFile file);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IJavaQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IJavaQuerySpecification.java
new file mode 100644
index 0000000..7cc1b66
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/IJavaQuerySpecification.java
@@ -0,0 +1,15 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.java;

+

+public interface IJavaQuerySpecification extends IExtendedClassProvider {

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/XMLSearcherForJava.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/XMLSearcherForJava.java
new file mode 100644
index 0000000..38a1c01
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/java/XMLSearcherForJava.java
@@ -0,0 +1,92 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.java;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jdt.core.IMember;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.internal.ui.text.java.ProposalInfo;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.internal.contentassist.JavaCompletionUtils;

+import org.eclipse.wst.xml.search.editor.internal.hyperlink.JavaElementHyperlink;

+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJava;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.util.JdtUtils;

+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;

+

+public class XMLSearcherForJava implements IXMLSearcher {

+

+	public static final IXMLSearcher INSTANCE = new XMLSearcherForJava();

+

+	// ------------------- Completions

+

+	/**

+	 * 

+	 */

+	public void searchForCompletion(Object selectedNode,

+			String mathingString, String forceBeforeText, String forceEndText,

+			IFile file, IXMLReferenceTo referenceTo,

+			IContentAssistProposalRecorder recorder) {

+		IXMLReferenceToJava referenceToJava = (IXMLReferenceToJava) referenceTo;

+		// Find class from

+		IType[] classes = referenceToJava.getExtends(selectedNode, file);

+		if (classes != null) {

+			for (int i = 0; i < classes.length; i++) {

+				JavaCompletionUtils.addTypeHierachyAttributeValueProposals(

+						mathingString, file, recorder, classes[i], 12);

+			}

+		} else {

+			JavaCompletionUtils.addClassValueProposals(mathingString, file,

+					recorder);

+		}

+	}

+

+	// ------------------- Hyperlinks

+

+	public void searchForHyperlink(Object selectedNode, int offset,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, ITextEditor textEditor) {

+		IType type = JdtUtils.getJavaType(file.getProject(), mathingString);

+		if (type != null) {

+			hyperLinks.add(new JavaElementHyperlink(hyperlinkRegion, type));

+		}

+	}

+

+	// ------------------- Validation

+

+	public IValidationResult searchForValidation(Object selectedNode,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IType type = JdtUtils.getJavaType(file.getProject(), mathingString);

+		return (type != null ? IValidationResult.OK : IValidationResult.NOK);

+	}

+

+	// ----------------- Text info

+

+	public String searchForTextHover(Object selectedNode, int offset,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IType type = JdtUtils.getJavaType(file.getProject(), mathingString);

+		if (type != null && type instanceof IMember) {

+			return new ProposalInfo((IMember) type).getInfo(EditorUtils

+					.getProgressMonitor());

+		}

+		return null;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/IJavaMethodQuerySpecification.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/IJavaMethodQuerySpecification.java
new file mode 100644
index 0000000..e5da51c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/IJavaMethodQuerySpecification.java
@@ -0,0 +1,19 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod;

+

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider.IClassNameExtractorProvider;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestorProvider;

+

+public interface IJavaMethodQuerySpecification extends

+		IJavaMethodRequestorProvider, IClassNameExtractorProvider {

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/XMLSearcherForJavaMethod.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/XMLSearcherForJavaMethod.java
new file mode 100644
index 0000000..88704b2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/XMLSearcherForJavaMethod.java
@@ -0,0 +1,335 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod;

+

+import java.util.List;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.core.Signature;

+import org.eclipse.jdt.internal.ui.text.java.ProposalInfo;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.internal.hyperlink.JavaElementHyperlink;

+import org.eclipse.wst.xml.search.editor.internal.util.EditorUtils;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJavaMethod;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;

+import org.eclipse.wst.xml.search.editor.util.JdtUtils;

+import org.eclipse.wst.xml.search.editor.validation.DefaultValidationResult;

+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Node;

+import org.w3c.dom.Text;

+

+public class XMLSearcherForJavaMethod implements IXMLSearcher {

+

+	public static final IXMLSearcher INSTANCE = new XMLSearcherForJavaMethod();

+

+	public void searchForCompletion(Object selectedNode,

+			String mathingString, String forceBeforeText, String forceEndText,

+			IFile file, IXMLReferenceTo referenceTo,

+			IContentAssistProposalRecorder recorder) {

+		IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;

+		try {

+			String className = getClassName(selectedNode, file, referenceTo);

+			if (className == null) {

+				return;

+			}

+			IType type = JdtUtils.getJavaType(file.getProject(), className);

+			if (type == null) {

+				return;

+			}

+			IJavaMethodRequestor filter = toJavaMethod.getRequestor(

+					selectedNode, file);

+			if (filter == null) {

+				return;

+			}

+			try {

+				createCompletion(selectedNode, mathingString, recorder, type,

+						filter);

+			} catch (JavaModelException e) {

+				Trace

+						.trace(Trace.SEVERE,

+								"Error while getting methods for class="

+										+ className, e);

+			}

+		} catch (XPathExpressionException e) {

+			e.printStackTrace();

+		}

+	}

+

+	private void createCompletion(Object selectedNode, String mathingString,

+			IContentAssistProposalRecorder recorder, IType type,

+			IJavaMethodRequestor requestor) throws JavaModelException {

+		if (type == null) {

+			return;

+		}

+		IMethod method = null;

+		IMethod[] methods = type.getMethods();

+		for (int i = 0; i < methods.length; i++) {

+			method = methods[i];

+			String methodName = requestor.matchPartial(selectedNode,

+					mathingString, method);

+			if (methodName != null) {

+				createMethodProposal(recorder, method, methodName);

+			}

+		}

+		createCompletion(selectedNode, mathingString, recorder, JdtUtils

+				.getSuperType(type), requestor);

+	}

+

+	public void searchForHyperlink(Object selectedNode, int offset,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, ITextEditor textEditor) {

+		IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;

+		try {

+			String className = getClassName(selectedNode, file, referenceTo);

+			if (className == null) {

+				return;

+			}

+			IType type = JdtUtils.getJavaType(file.getProject(), className);

+			if (type == null) {

+				return;

+			}

+			IJavaMethodRequestor filter = toJavaMethod.getRequestor(

+					selectedNode, file);

+			if (filter == null) {

+				return;

+			}

+			try {

+				String matching = mathingString;

+				createHyperlink(selectedNode, matching, hyperlinkRegion,

+						hyperLinks, type, filter);

+			} catch (JavaModelException e) {

+				Trace

+						.trace(Trace.SEVERE,

+								"Error while getting methods for class="

+										+ className, e);

+			}

+		} catch (XPathExpressionException e) {

+			e.printStackTrace();

+		}

+	}

+

+	private void createHyperlink(Object selectedNode, String matching,

+			IRegion hyperlinkRegion, List<IHyperlink> hyperLinks, IType type,

+			IJavaMethodRequestor requestor) throws JavaModelException {

+		if (type == null) {

+			return;

+		}

+		IMethod method = null;

+		IMethod[] methods = type.getMethods();

+		for (int i = 0; i < methods.length; i++) {

+			method = methods[i];

+			IStatus status = requestor.matchTotally(selectedNode, matching,

+					method);

+			if (status != null && status.isOK()) {

+				hyperLinks

+						.add(new JavaElementHyperlink(hyperlinkRegion, method));

+			}

+		}

+		createHyperlink(selectedNode, matching, hyperlinkRegion, hyperLinks,

+				JdtUtils.getSuperType(type), requestor);

+	}

+

+	public IValidationResult searchForValidation(Object selectedNode,

+			String matchingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;

+		DefaultValidationResult result = new DefaultValidationResult();

+		try {

+			String className = getClassName(selectedNode, file, referenceTo);

+			if (className == null) {

+				return null;

+			}

+			IType type = JdtUtils.getJavaType(file.getProject(), className);

+			if (type == null) {

+				return null;

+			}

+			IJavaMethodRequestor filter = toJavaMethod.getRequestor(

+					selectedNode, file);

+			if (filter == null) {

+				return null;

+			}

+			try {

+				createValidation(selectedNode, matchingString, result, type, filter);

+			} catch (JavaModelException e) {

+				Trace

+						.trace(Trace.SEVERE,

+								"Error while getting methods for class="

+										+ className, e);

+			}

+		} catch (XPathExpressionException e) {

+			e.printStackTrace();

+		}

+		return result;

+	}

+

+	private void createValidation(Object selectedNode, String matching,

+			DefaultValidationResult result, IType type,

+			IJavaMethodRequestor requestor) throws JavaModelException {

+		if (type == null) {

+			return;

+		}

+		IMethod method = null;

+		IMethod[] methods = type.getMethods();

+		for (int i = 0; i < methods.length; i++) {

+			method = methods[i];

+			IStatus status = requestor.matchTotally(selectedNode, matching,

+					method);

+			if (status != null && status.isOK()) {

+				result.addElement();

+			}

+		}

+		createValidation(selectedNode, matching, result, JdtUtils

+				.getSuperType(type), requestor);

+	}

+

+	private String getClassName(Object selectedNode, IFile file,

+			IXMLReferenceTo referenceTo) throws XPathExpressionException {

+		IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;

+		return toJavaMethod.extractClassName(getOwnerNode((Node)selectedNode), file,

+				null, null);

+	}

+

+	private Node getOwnerNode(Node node) {

+		short nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			return ((Attr) node).getOwnerElement();

+		case Node.TEXT_NODE:

+			return ((Text) node).getParentNode();

+		}

+		return node;

+	}

+

+	protected void createMethodProposal(

+			IContentAssistProposalRecorder recorder, IMethod method,

+			String methodNameToUse) {

+		try {

+			String parameterNames[] = method.getParameterNames();

+			String parameterTypes[] = JdtUtils.getParameterTypesString(method);

+			String returnType = JdtUtils.getReturnTypeString(method, true);

+			String methodName = method.getElementName();

+			String replaceText = methodName;

+			StringBuilder buf = new StringBuilder();

+			buf.append(replaceText);

+			if (parameterTypes.length > 0 && parameterNames.length > 0) {

+				buf.append(" (");

+				for (int i = 0; i < parameterTypes.length; i++) {

+					buf.append(parameterTypes[i]);

+					buf.append(' ');

+					buf.append(parameterNames[i]);

+					if (i < parameterTypes.length - 1)

+						buf.append(", ");

+				}

+

+				buf.append(") ");

+			} else {

+				buf.append("() ");

+			}

+			if (returnType != null) {

+				buf.append(Signature.getSimpleName(returnType));

+				buf.append(" - ");

+			} else {

+				buf.append(" void - ");

+			}

+			buf.append(method.getParent().getElementName());

+			String displayText = buf.toString();

+			org.eclipse.swt.graphics.Image image = XMLSearchEditorPlugin

+					.getDefault().getJavaElementLabelProvider().getImageLabel(

+							method, method.getFlags() | 2);

+			recorder.recordProposal(image, 10, displayText, methodNameToUse,

+					null

+			/*

+			 * new ProposalInfo((IMember) method).getInfo(EditorUtils

+			 * .getProgressMonitor())

+			 */);

+		} catch (JavaModelException _ex) {

+		}

+	}

+

+	// ----------------- Text info

+

+	public String searchForTextHover(Object selectedNode, int offset,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToJavaMethod toJavaMethod = (IXMLReferenceToJavaMethod) referenceTo;

+		StringBuilder result = new StringBuilder();

+		try {

+			String className = getClassName(selectedNode, file, referenceTo);

+			if (className == null) {

+				return null;

+			}

+			IType type = JdtUtils.getJavaType(file.getProject(), className);

+			if (type == null) {

+				return null;

+			}

+			IJavaMethodRequestor filter = toJavaMethod.getRequestor(

+					selectedNode, file);

+			if (filter == null) {

+				return null;

+			}

+			try {

+				createTextInfo(selectedNode, mathingString, result, type, filter);

+			} catch (JavaModelException e) {

+				Trace

+						.trace(Trace.SEVERE,

+								"Error while getting methods for class="

+										+ className, e);

+			}

+		} catch (XPathExpressionException e) {

+			e.printStackTrace();

+		}

+		return result.toString();

+	}

+

+	private void createTextInfo(Object selectedNode, String matching,

+			StringBuilder result, IType type, IJavaMethodRequestor requestor)

+			throws JavaModelException {

+		if (type == null) {

+			return;

+		}

+		IMethod method = null;

+		IMethod[] methods = type.getMethods();

+		for (int i = 0; i < methods.length; i++) {

+			method = methods[i];

+			IStatus status = requestor.matchTotally(selectedNode, matching,

+					method);

+			if (status != null && status.isOK()) {

+				String info = new ProposalInfo(method).getInfo(EditorUtils

+						.getProgressMonitor());

+				if (info != null) {

+					if (result.length() > 0) {

+						result.append("<br/></br/>");

+					}

+					result.append(info);

+				}

+			}

+		}

+		createTextInfo(selectedNode, matching, result, JdtUtils

+				.getSuperType(type), requestor);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/AbstractClassNameExtractor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/AbstractClassNameExtractor.java
new file mode 100644
index 0000000..4918917
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/AbstractClassNameExtractor.java
@@ -0,0 +1,37 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.w3c.dom.Node;

+

+public abstract class AbstractClassNameExtractor implements IClassNameExtractor {

+

+	public final String extractClassName(Node node, IFile file,

+			String pathForClass, String findByAttrName,

+			boolean findByParentNode, String xpathFactoryProviderId,

+			NamespaceInfos namespaceInfo) throws XPathExpressionException {

+		if (node == null) {

+			return null;

+		}

+		return doExtractClassName(node, file, pathForClass, findByAttrName,

+				findByParentNode, xpathFactoryProviderId, namespaceInfo);

+	}

+

+	protected abstract String doExtractClassName(Node node, IFile file,

+			String pathForClass, String findByAttrName,

+			boolean findByParentNode, String xpathFactoryProviderId,

+			NamespaceInfos namespaceInfo) throws XPathExpressionException;

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractor.java
new file mode 100644
index 0000000..0559558
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractor.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.w3c.dom.Node;

+

+public interface IClassNameExtractor {

+

+	String extractClassName(Node node, IFile file, String pathForClass,

+			String findByAttrName, boolean findByParentNode,

+			String xpathFactoryProviderId, NamespaceInfos namespaceInfo)

+			throws XPathExpressionException;

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractorProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractorProvider.java
new file mode 100644
index 0000000..df10df1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/IClassNameExtractorProvider.java
@@ -0,0 +1,20 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider;

+

+import org.eclipse.core.resources.IFile;

+import org.w3c.dom.Node;

+

+public interface IClassNameExtractorProvider {

+

+	IClassNameExtractor getClassNameExtractor(Object selectedNode, IFile file);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/XPathClassNameExtractor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/XPathClassNameExtractor.java
new file mode 100644
index 0000000..452c578
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/classnameprovider/XPathClassNameExtractor.java
@@ -0,0 +1,47 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.classnameprovider;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+

+public class XPathClassNameExtractor extends AbstractClassNameExtractor {

+

+	public static final IClassNameExtractor INSTANCE = new XPathClassNameExtractor();

+

+	public String doExtractClassName(Node node, IFile file,

+			String pathForClass, String findByAttrName,

+			boolean findByParentNode, String xpathFactoryProviderId,

+			NamespaceInfos namespaceInfo) throws XPathExpressionException {

+		if (findByAttrName != null && node.getNodeType() == Node.ELEMENT_NODE) {

+			Element element = ((Element) node);

+			// Optimisation : don't execute XPath if class come from for

+			// attribute name

+			if (findByParentNode) {

+				Node parent = element.getParentNode();

+				if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {

+					return ((Element) parent).getAttribute(findByAttrName);

+				}

+				return null;

+			}

+			return element.getAttribute(findByAttrName);

+		}

+

+		return XPathManager.getManager().evaluateString(xpathFactoryProviderId,

+				node, pathForClass, namespaceInfo, null);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/AbstractJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/AbstractJavaMethodRequestor.java
new file mode 100644
index 0000000..6c2bfcf
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/AbstractJavaMethodRequestor.java
@@ -0,0 +1,100 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.jdt.core.Flags;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+

+public abstract class AbstractJavaMethodRequestor implements

+		IJavaMethodRequestor {

+

+	public String matchPartial(Object selectedNode, String matching,

+			IMethod method) {

+		IStatus status = validate(method);

+		if (status == null || !status.isOK()) {

+			return null;

+		}

+		String methodNameTest = formatMethodName(selectedNode, method);

+		if (methodNameTest != null && isMatchPartial(matching, methodNameTest)) {

+			return methodNameTest;

+		}

+		return null;

+	}

+

+	protected boolean isMatchPartial(String matching, String methodNameTest) {

+		if (methodNameTest.startsWith(matching)) {

+			return true;

+		}

+		return false;

+	}

+

+	public IStatus matchTotally(Object selectedNode, String matching,

+			IMethod method) {

+		String methodNameTest = formatMethodName(selectedNode, method);

+		if (methodNameTest != null && isMatchTotally(matching, methodNameTest)) {

+			return validate(method);

+		}

+		return Status.CANCEL_STATUS;

+	}

+

+	protected boolean isMatchTotally(String methodNameFromXML,

+			String methodNameTest) {

+		if (methodNameFromXML.equals(methodNameTest)) {

+			return true;

+		}

+		return false;

+	}

+

+	protected abstract String formatMethodName(Object selectedNode,

+			IMethod method);

+

+	protected IStatus validate(IMethod method) {

+		return doValidate(method);

+	}

+

+	protected IStatus doValidate(IMethod method) {

+		try {

+			if (method.isConstructor()) {

+				return Status.CANCEL_STATUS;

+			}

+			int flags = method.getFlags();

+			Boolean checkIsPublic = checkIsPublic();

+			if (checkIsPublic != null) {

+				if (!Flags.isPublic(flags) == checkIsPublic.booleanValue()) {

+					return Status.CANCEL_STATUS;

+				}

+			}

+			Boolean checkIsInterface = checkIsInterface();

+			if (checkIsInterface != null) {

+				if (!Flags.isInterface(flags) == checkIsInterface.booleanValue()) {

+					return Status.CANCEL_STATUS;

+				}

+			}

+

+		} catch (JavaModelException e) {

+			Trace.trace(Trace.SEVERE, "Method constructor", e);

+		}

+		return Status.OK_STATUS;

+	}

+

+	protected Boolean checkIsPublic() {

+		return true;

+	}

+

+	protected Boolean checkIsInterface() {

+		return false;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/BeansJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/BeansJavaMethodRequestor.java
new file mode 100644
index 0000000..56dd2ab
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/BeansJavaMethodRequestor.java
@@ -0,0 +1,111 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+public class BeansJavaMethodRequestor extends AbstractJavaMethodRequestor {

+

+	protected static final String SET_PREFIX = "set";

+	protected static final String GET_PREFIX = "get";

+	protected static final String IS_PREFIX = "is";

+

+	private final String prefix;

+	private final int prefixLength;

+	private final boolean checkCaseForFirstChar;

+

+	public BeansJavaMethodRequestor(String prefix, boolean checkCaseForFirstChar) {

+		this.prefix = prefix;

+		this.prefixLength = prefix.length();

+		this.checkCaseForFirstChar = checkCaseForFirstChar;

+	}

+

+	@Override

+	protected String formatMethodName(Object selectedNode, IMethod method) {

+		if (!isStartPefix(method)) {

+			return null;

+		}

+		if (method.getElementName().length() <= prefixLength) {

+			return null;

+		}

+		String formattedMethodName = method.getElementName().substring(

+				prefixLength, method.getElementName().length());

+		Boolean b = isUpperCaseForFirstChar();

+		if (b == null) {

+			return formattedMethodName;

+		}

+		String fisrtChar = formattedMethodName.substring(0, 1);

+		if (b.booleanValue()) {

+			return fisrtChar.toUpperCase()

+					+ formattedMethodName.substring(1, formattedMethodName

+							.length());

+		}

+		return fisrtChar.toLowerCase()

+				+ formattedMethodName

+						.substring(1, formattedMethodName.length());

+	}

+

+	@Override

+	protected IStatus validate(IMethod method) {

+		IStatus status = super.validate(method);

+		if (status == null || status.isOK()) {

+			if (!isStartPefix(method)) {

+				return Status.CANCEL_STATUS;

+			}

+			return Status.OK_STATUS;

+		}

+		return status;

+	}

+

+	protected boolean isStartPefix(IMethod method) {

+		String methodName = method.getElementName();

+		return methodName.startsWith(prefix);

+	}

+	

+	@Override

+	protected boolean isMatchPartial(String matching, String methodNameTest) {

+		if (matching.length() == 0) {

+			return true;

+		}

+		if (super.isMatchPartial(matching.substring(1,

+				matching.length()), methodNameTest.substring(1,

+				methodNameTest.length()))) {

+			String s1 = matching.substring(0, 1);

+			String s2 = methodNameTest.substring(0, 1);

+			return s1.equalsIgnoreCase(s2);

+		}

+		return false;

+	}

+

+	@Override

+	protected boolean isMatchTotally(String methodNameFromXML,

+			String methodNameTest) {

+		if (methodNameFromXML.length() < prefixLength) {

+			return false;

+		}

+		if (super.isMatchTotally(methodNameFromXML.substring(1,

+				methodNameFromXML.length()), methodNameTest.substring(1,

+				methodNameTest.length()))) {

+			String s1 = methodNameFromXML.substring(0, 1);

+			String s2 = methodNameTest.substring(0, 1);

+			return s1.equalsIgnoreCase(s2);

+		}

+		return false;

+	}

+

+	protected Boolean isUpperCaseForFirstChar() {

+		return false;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/DefaultJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/DefaultJavaMethodRequestor.java
new file mode 100644
index 0000000..5e82d86
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/DefaultJavaMethodRequestor.java
@@ -0,0 +1,24 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;

+

+import org.eclipse.jdt.core.IMethod;

+

+public class DefaultJavaMethodRequestor extends AbstractJavaMethodRequestor {

+

+	public static final IJavaMethodRequestor INSTANCE = new DefaultJavaMethodRequestor();

+

+	@Override

+	protected String formatMethodName(Object selectedNode, IMethod method) {

+		return method.getElementName();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/GetterJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/GetterJavaMethodRequestor.java
new file mode 100644
index 0000000..1de1c61
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/GetterJavaMethodRequestor.java
@@ -0,0 +1,24 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;

+

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.BeansJavaMethodRequestor;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;

+

+public class GetterJavaMethodRequestor extends BeansJavaMethodRequestor {

+

+	public static final IJavaMethodRequestor INSTANCE = new GetterJavaMethodRequestor();

+

+	public GetterJavaMethodRequestor() {

+		super(GET_PREFIX, false);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestor.java
new file mode 100644
index 0000000..d61fe79
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestor.java
@@ -0,0 +1,24 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+public interface IJavaMethodRequestor {

+

+	String matchPartial(Object selectedNode, String mathingString,

+			IMethod method);

+

+	IStatus matchTotally(Object selectedNode, String mathingString,

+			IMethod method);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestorProvider.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestorProvider.java
new file mode 100644
index 0000000..0c45873
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/javamethod/requestor/IJavaMethodRequestorProvider.java
@@ -0,0 +1,18 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor;

+

+import org.eclipse.core.resources.IFile;

+

+public interface IJavaMethodRequestorProvider {

+

+	IJavaMethodRequestor getRequestor(Object selectedNode, IFile file);

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ContentAssisitCollectorForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ContentAssisitCollectorForProperties.java
new file mode 100644
index 0000000..6ab3f63
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ContentAssisitCollectorForProperties.java
@@ -0,0 +1,62 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.properties;

+

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;

+

+public class ContentAssisitCollectorForProperties implements

+		IPropertiesCollector {

+

+	private final Object selectedNode;

+	private IContentAssistProposalRecorder recorder;

+	private IXMLReferenceToProperty referenceToProperty;

+

+	public ContentAssisitCollectorForProperties(Object selectedNode,

+			IXMLReferenceToProperty referenceToProperty,

+			IContentAssistProposalRecorder recorder) {

+		this.selectedNode = selectedNode;

+		this.recorder = recorder;

+		this.referenceToProperty = referenceToProperty;

+	}

+

+	public boolean add(IStorage propertiesFile, String key, String name) {

+		// TODO Auto-generated method stub

+		Image image = null;

+		int relevance = 1;

+		String value = key;// resolver.resolve(selectedNode, rootContainer,

+							// file);

+		String displayText = value;

+		String replaceText = value;

+		Object proposedObject = null;

+

+		IContentAssistAdditionalProposalInfoProvider<PropertyInfo> provider = (IContentAssistAdditionalProposalInfoProvider<PropertyInfo>) referenceToProperty

+				.getAdditionalProposalInfoProvider();

+		if (provider != null) {

+			PropertyInfo info = new PropertyInfo(propertiesFile, key, name);

+			String newDisplayText = provider.getDisplayText(displayText, info);

+			if (!StringUtils.isEmpty(newDisplayText)) {

+				displayText = newDisplayText;

+			}

+			image = provider.getImage(info);

+			proposedObject = provider.getTextInfo(info);

+		}

+		recorder.recordProposal(image, relevance, displayText, replaceText,

+				proposedObject);

+

+		return true;

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/HyperlinkCollectorForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/HyperlinkCollectorForProperties.java
new file mode 100644
index 0000000..7c3964d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/HyperlinkCollectorForProperties.java
@@ -0,0 +1,40 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.properties;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.IEditorPart;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;

+import org.eclipse.wst.xml.search.editor.internal.hyperlink.PropertiesFileHyperlink;

+

+public class HyperlinkCollectorForProperties implements IPropertiesCollector {

+

+	private List<IHyperlink> hyperLinks;

+	private IRegion hyperlinkRegion;

+	private IEditorPart editor;

+

+	public HyperlinkCollectorForProperties(IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, IEditorPart editor) {

+		this.hyperlinkRegion = hyperlinkRegion;

+		this.hyperLinks = hyperLinks;

+		this.editor = editor;

+	}

+

+	public boolean add(IStorage propertiesFile, String key, String name) {

+		hyperLinks.add(new PropertiesFileHyperlink(hyperlinkRegion,

+				propertiesFile, key, editor));

+		return true;

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/PropertyInfo.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/PropertyInfo.java
new file mode 100644
index 0000000..fdaaee2
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/PropertyInfo.java
@@ -0,0 +1,39 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.properties;

+

+import org.eclipse.core.resources.IStorage;

+

+public class PropertyInfo {

+

+	private final IStorage propertiesFile;

+	private final String key;

+	private final String name;

+

+	public PropertyInfo(IStorage propertiesFile, String key, String name) {

+		this.propertiesFile = propertiesFile;

+		this.key = key;

+		this.name = name;

+	}

+

+	public IStorage getPropertiesFile() {

+		return propertiesFile;

+	}

+

+	public String getKey() {

+		return key;

+	}

+

+	public String getName() {

+		return name;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/TextHoverForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/TextHoverForProperties.java
new file mode 100644
index 0000000..24cbebd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/TextHoverForProperties.java
@@ -0,0 +1,32 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.properties;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;

+import org.eclipse.wst.xml.search.core.resource.IURIResolver;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.searchers.DefaultTextInfo;

+

+public class TextHoverForProperties extends DefaultTextInfo<Object> implements

+		IPropertiesCollector {

+

+	public TextHoverForProperties(

+			IContentAssistAdditionalProposalInfoProvider<Object> provider) {

+		super(provider);

+	}

+

+	public boolean add(IStorage storage, String key, String name) {

+		return true;//super.add(file);

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ValidationResultForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ValidationResultForProperties.java
new file mode 100644
index 0000000..708352d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/ValidationResultForProperties.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.properties;

+

+import org.eclipse.core.resources.IStorage;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;

+import org.eclipse.wst.xml.search.editor.validation.AbstractValidationResult;

+

+public class ValidationResultForProperties extends AbstractValidationResult

+		implements IPropertiesCollector {

+	

+	public boolean add(IStorage storage, String key, String name) {

+		nbElements++;

+		return true;

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/XMLSearcherForProperties.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/XMLSearcherForProperties.java
new file mode 100644
index 0000000..2840f88
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/properties/XMLSearcherForProperties.java
@@ -0,0 +1,101 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.properties;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesCollector;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesQuerySpecification;

+import org.eclipse.wst.xml.search.core.properties.IPropertiesRequestor;

+import org.eclipse.wst.xml.search.core.properties.PropertiesSearchEngine;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.util.PropertiesQuerySpecificationUtil;

+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;

+

+public class XMLSearcherForProperties implements IXMLSearcher {

+

+	public void searchForCompletion(Object selectedNode, String mathingString,

+			String forceBeforeText, String forceEndText, IFile file,

+			IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {

+		IXMLReferenceToProperty referenceToProperty = (IXMLReferenceToProperty) referenceTo;

+		// 1) Create a collector for content assist

+		ContentAssisitCollectorForProperties collector = new ContentAssisitCollectorForProperties(

+				selectedNode, referenceToProperty, recorder);

+		// 2) call properties search engine.

+		internalSearch(selectedNode, file, referenceToProperty, collector,

+				mathingString, false);

+	}

+

+	public void searchForHyperlink(Object selectedNode, int offset,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, ITextEditor textEditor) {

+		IXMLReferenceToProperty referenceToProperty = (IXMLReferenceToProperty) referenceTo;

+		HyperlinkCollectorForProperties collector = new HyperlinkCollectorForProperties(

+				hyperlinkRegion, hyperLinks, textEditor);

+		internalSearch(selectedNode, file, referenceToProperty, collector,

+				mathingString, true);

+

+	}

+

+	public String searchForTextHover(Object selectedNode, int offset,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		return null;

+	}

+

+	public IValidationResult searchForValidation(Object selectedNode,

+			String matchingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToProperty referencetoResource = (IXMLReferenceToProperty) referenceTo;

+		ValidationResultForProperties collector = new ValidationResultForProperties();

+		internalSearch(selectedNode, file, referencetoResource, collector,

+				matchingString, true);

+		return collector;

+	}

+

+	protected void internalSearch(Object selectedNode, IFile file,

+			IXMLReferenceToProperty referenceToProperty,

+			IPropertiesCollector collector, String mathingString,

+			boolean fullMatch) {

+		IPropertiesQuerySpecification[] querySpecifications = PropertiesQuerySpecificationUtil

+				.getQuerySpecifications(referenceToProperty);

+		if (querySpecifications == null || querySpecifications.length < 1)

+			return;

+		IPropertiesQuerySpecification querySpecification = null;

+		for (int i = 0; i < querySpecifications.length; i++) {

+			querySpecification = querySpecifications[i];

+			IPropertiesRequestor requestor = querySpecification.getRequestor();

+			if (querySpecification.isMultiResource()) {

+				IResource[] containers = querySpecification.getResources(

+						selectedNode, file);

+				PropertiesSearchEngine.getDefault().search(selectedNode,

+						containers, requestor, collector, mathingString,

+						fullMatch, null);

+			} else {

+				IResource container = querySpecification.getResource(

+						selectedNode, file);

+				PropertiesSearchEngine.getDefault().search(selectedNode,

+						container, requestor, collector, mathingString,

+						fullMatch, null);

+			}

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ContentAssisitCollectorForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ContentAssisitCollectorForResource.java
new file mode 100644
index 0000000..929af56
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ContentAssisitCollectorForResource.java
@@ -0,0 +1,60 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.resource;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;

+import org.eclipse.wst.xml.search.core.resource.IURIResolver;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;

+

+public class ContentAssisitCollectorForResource<T> implements IResourceCollector {

+

+	private final T selectedNode;

+	private IContentAssistProposalRecorder recorder;

+	private final IContentAssistAdditionalProposalInfoProvider<IResource> provider;

+	

+	public ContentAssisitCollectorForResource(T selectedNode,

+			IContentAssistProposalRecorder recorder,

+			IContentAssistAdditionalProposalInfoProvider<IResource> provider) {

+		this.selectedNode = selectedNode;

+		this.recorder = recorder;

+		this.provider = provider;

+	}

+

+	public boolean add(IResource file, IResource rootContainer,

+			IURIResolver resolver) {

+		Image image = null;

+		int relevance = 1;

+		String value = resolver.resolve(selectedNode, rootContainer, file);

+		String displayText = value;

+		String replaceText = value;

+		Object proposedObject = null;

+

+		if (provider != null) {

+			String newDisplayText = provider.getDisplayText(displayText,

+					file);

+			if (!StringUtils.isEmpty(newDisplayText)) {

+				displayText = newDisplayText;

+			}

+			image = provider.getImage(file);

+			proposedObject = provider.getTextInfo(file);

+		}

+		recorder.recordProposal(image, relevance, displayText, replaceText,

+				proposedObject);

+

+		return true;

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/HyperlinkCollectorForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/HyperlinkCollectorForResource.java
new file mode 100644
index 0000000..20789d1
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/HyperlinkCollectorForResource.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.resource;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;

+import org.eclipse.wst.xml.search.core.resource.IURIResolver;

+import org.eclipse.wst.xml.search.editor.internal.hyperlink.ResourceHyperlink;

+import org.eclipse.wst.xml.search.editor.searchers.AbstractHyperlinkCollector;

+

+public class HyperlinkCollectorForResource extends AbstractHyperlinkCollector

+		implements IResourceCollector {

+

+	public HyperlinkCollectorForResource(IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks) {

+		super(hyperlinkRegion, hyperLinks);

+	}

+

+	public boolean add(IResource file, IResource rootContainer,

+			IURIResolver resolver) {

+		hyperLinks.add(new ResourceHyperlink(hyperlinkRegion, file));

+		return true;

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/TextHoverForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/TextHoverForResource.java
new file mode 100644
index 0000000..6c4117f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/TextHoverForResource.java
@@ -0,0 +1,32 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.resource;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;

+import org.eclipse.wst.xml.search.core.resource.IURIResolver;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.searchers.DefaultTextInfo;

+

+public class TextHoverForResource extends DefaultTextInfo<IResource> implements

+		IResourceCollector {

+

+	public TextHoverForResource(

+			IContentAssistAdditionalProposalInfoProvider<IResource> provider) {

+		super(provider);

+	}

+

+	public boolean add(IResource file, IResource rootContainer,

+			IURIResolver resolver) {

+		return super.add(file);

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ValidationResultForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ValidationResultForResource.java
new file mode 100644
index 0000000..5947e19
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/ValidationResultForResource.java
@@ -0,0 +1,27 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.resource;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;

+import org.eclipse.wst.xml.search.core.resource.IURIResolver;

+import org.eclipse.wst.xml.search.editor.validation.AbstractValidationResult;

+

+public class ValidationResultForResource extends AbstractValidationResult

+		implements IResourceCollector {

+

+	public boolean add(IResource file, IResource rootContainer,

+			IURIResolver resolver) {

+		nbElements++;

+		return true;

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/XMLSearcherForResource.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/XMLSearcherForResource.java
new file mode 100644
index 0000000..c9b3296
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/resource/XMLSearcherForResource.java
@@ -0,0 +1,120 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.resource;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.search.core.resource.IResourceCollector;

+import org.eclipse.wst.xml.search.core.resource.IResourceQuerySpecification;

+import org.eclipse.wst.xml.search.core.resource.IResourceRequestor;

+import org.eclipse.wst.xml.search.core.resource.ResourceSearchEngine;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.util.ResourceQuerySpecificationUtil;

+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;

+

+public class XMLSearcherForResource implements IXMLSearcher {

+

+	// ------------------- Completions

+

+	/**

+	 * 

+	 */

+	public void searchForCompletion(Object selectedNode, String mathingString,

+			String forceBeforeText, String forceEndText, IFile file,

+			IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {

+		IXMLReferenceToResource referencetoResource = (IXMLReferenceToResource) referenceTo;

+		ContentAssisitCollectorForResource collector = new ContentAssisitCollectorForResource(

+				selectedNode, recorder,

+				referencetoResource.getAdditionalProposalInfoProvider());

+		internalSearch(selectedNode, file, referencetoResource, collector,

+				mathingString, false);

+	}

+

+	public void searchForHyperlink(Object selectedNode, int offset,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, ITextEditor textEditor) {

+		IXMLReferenceToResource referencetoResource = (IXMLReferenceToResource) referenceTo;

+		HyperlinkCollectorForResource collector = new HyperlinkCollectorForResource(

+				hyperlinkRegion, hyperLinks);

+		internalSearch(selectedNode, file, referencetoResource, collector,

+				mathingString, true);

+	}

+

+	/**

+	 * 

+	 */

+	public IValidationResult searchForValidation(Object selectedNode,

+			String matchingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToResource referencetoResource = (IXMLReferenceToResource) referenceTo;

+		ValidationResultForResource collector = new ValidationResultForResource();

+		internalSearch(selectedNode, file, referencetoResource, collector,

+				matchingString, true);

+		return collector;

+	}

+

+	protected void internalSearch(Object selectedNode, IFile file,

+			IXMLReferenceToResource referencetoResource,

+			IResourceCollector collector, String mathingString,

+			boolean fullMatch) {

+		IResourceQuerySpecification[] querySpecifications = ResourceQuerySpecificationUtil

+				.getQuerySpecifications(referencetoResource);

+		if (querySpecifications == null || querySpecifications.length < 1)

+			return;

+		IResourceQuerySpecification querySpecification = null;

+		for (int i = 0; i < querySpecifications.length; i++) {

+			querySpecification = querySpecifications[i];

+			IResourceRequestor requestor = querySpecification.getRequestor();

+			if (querySpecification.isMultiResource()) {

+				IResource[] containers = querySpecification.getResources(

+						selectedNode, file);

+				ResourceSearchEngine.getDefault().search(selectedNode,

+						containers, requestor, collector,

+						querySpecification.getURIResolver(file, selectedNode),

+						mathingString, fullMatch, null);

+			} else {

+				IResource container = querySpecification.getResource(

+						selectedNode, file);

+				ResourceSearchEngine.getDefault().search(selectedNode,

+						container, requestor, collector,

+						querySpecification.getURIResolver(file, selectedNode),

+						mathingString, fullMatch, null);

+			}

+		}

+	}

+

+	// ----------------- Text info

+

+	public String searchForTextHover(Object selectedNode, int offset,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToResource referencetoResource = (IXMLReferenceToResource) referenceTo;

+		IContentAssistAdditionalProposalInfoProvider<IResource> provider = (IContentAssistAdditionalProposalInfoProvider<IResource>) referencetoResource

+				.getAdditionalProposalInfoProvider();

+		if (provider == null) {

+			return null;

+		}

+		TextHoverForResource collector = new TextHoverForResource(provider);

+		internalSearch(selectedNode, file, referencetoResource, collector,

+				mathingString, true);

+		return collector.getTextInfo();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ContentAssisitCollectorForStatics.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ContentAssisitCollectorForStatics.java
new file mode 100644
index 0000000..f417ab6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ContentAssisitCollectorForStatics.java
@@ -0,0 +1,67 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.statics;

+

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.search.core.statics.IStaticValue;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;

+import org.eclipse.wst.xml.search.editor.searchers.AbstractContentAssisitCollector;

+

+public class ContentAssisitCollectorForStatics extends

+		AbstractContentAssisitCollector<IXMLReferenceToStatic> implements

+		IStaticValueCollector {

+

+	public ContentAssisitCollectorForStatics(String forceBeforeText,

+			String forceEndText, IXMLReferenceToStatic referencePath,

+			IContentAssistProposalRecorder recorder) {

+		super(forceBeforeText, forceEndText, referencePath, recorder);

+	}

+

+	public boolean add(IStaticValue value) {

+		collect(recorder, value, referencePath);

+		return false;

+	}

+

+	private void collect(final IContentAssistProposalRecorder recorder,

+			IStaticValue staticValue, IXMLReferenceToStatic referenceToStatic) {

+		String value = staticValue.getKey();

+		if (value == null) {

+			return;

+		}

+

+		Image image = null;

+		int relevance = 1;

+		String displayText = value;

+		String replaceText = getReplaceText(value);

+		Object proposedObject = staticValue.getDescription();

+

+		IContentAssistAdditionalProposalInfoProvider provider = referenceToStatic

+				.getAdditionalProposalInfoProvider();

+		if (provider != null) {

+			String newDisplayText = provider.getDisplayText(displayText,

+					staticValue);

+			if (!StringUtils.isEmpty(newDisplayText)) {

+				displayText = newDisplayText;

+			}

+			image = provider.getImage(staticValue);

+			proposedObject = provider.getTextInfo(staticValue);

+		}

+		int cursorPosition = getCursorPosition(value);

+

+		recorder.recordProposal(image, relevance, displayText, replaceText,

+				cursorPosition, proposedObject);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/HyperlinkCollectorForStatics.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/HyperlinkCollectorForStatics.java
new file mode 100644
index 0000000..744d752
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/HyperlinkCollectorForStatics.java
@@ -0,0 +1,42 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.statics;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.wst.xml.search.core.statics.IStaticValue;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;

+import org.eclipse.wst.xml.search.editor.internal.hyperlink.ResourceHyperlink;

+import org.eclipse.wst.xml.search.editor.searchers.AbstractHyperlinkCollector;

+import org.eclipse.wst.xml.search.editor.statics.StaticValueDocument;

+

+public class HyperlinkCollectorForStatics extends AbstractHyperlinkCollector

+		implements IStaticValueCollector {

+

+	public HyperlinkCollectorForStatics(IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks) {

+		super(hyperlinkRegion, hyperLinks);

+	}

+

+	public boolean add(IStaticValue value) {

+		if (value instanceof StaticValueDocument) {

+			StaticValueDocument document = (StaticValueDocument) value;

+			IResource file = document.getResource();

+			hyperLinks.add(new ResourceHyperlink(hyperlinkRegion, file,

+					document.getStartOffset(), document.getLength()));

+		}

+		return true;

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/TextInfoForStatic.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/TextInfoForStatic.java
new file mode 100644
index 0000000..ce27826
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/TextInfoForStatic.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.statics;

+

+import org.eclipse.wst.xml.search.core.statics.IStaticValue;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.searchers.DefaultTextInfo;

+

+public class TextInfoForStatic extends DefaultTextInfo<IStaticValue> implements

+		IStaticValueCollector {

+

+	public TextInfoForStatic(

+			IContentAssistAdditionalProposalInfoProvider<IStaticValue> provider) {

+		super(provider);

+	}

+

+	@Override

+	protected String getTextInfo(IStaticValue value) {

+		if (provider == null) {

+			return value.getDescription();

+		}

+		return super.getTextInfo(value);

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ValidationResultForStatics.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ValidationResultForStatics.java
new file mode 100644
index 0000000..60bad5e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/ValidationResultForStatics.java
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.statics;

+

+import org.eclipse.wst.xml.search.core.statics.IStaticValue;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;

+import org.eclipse.wst.xml.search.editor.validation.AbstractValidationResult;

+

+public class ValidationResultForStatics extends AbstractValidationResult

+		implements IStaticValueCollector {

+

+	public ValidationResultForStatics(String value, int startIndex, int endIndex) {

+		super(value, startIndex, endIndex);

+	}

+

+	public boolean add(IStaticValue value) {

+		nbElements++;

+		return true;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/XMLSearcherForStatic.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/XMLSearcherForStatic.java
new file mode 100644
index 0000000..1e4f782
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/statics/XMLSearcherForStatic.java
@@ -0,0 +1,126 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.statics;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.search.core.statics.IStaticValue;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueQuerySpecification;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitor;

+import org.eclipse.wst.xml.search.core.statics.StaticValueSearchEngine;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.util.StaticQuerySpecificationUtil;

+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;

+

+public class XMLSearcherForStatic implements IXMLSearcher {

+

+	public static final IXMLSearcher INSTANCE = new XMLSearcherForStatic();

+

+	// ------------------- Completions

+

+	/**

+	 * 

+	 */

+	public void searchForCompletion(Object selectedNode, String matchingString,

+			String forceBeforeText, String forceEndText, IFile file,

+			IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {

+		IXMLReferenceToStatic referenceToStatic = (IXMLReferenceToStatic) referenceTo;

+		IStaticValueCollector collector = new ContentAssisitCollectorForStatics(

+				forceBeforeText, forceEndText, referenceToStatic, recorder);

+		internalSearch(selectedNode, file, collector, matchingString, true,

+				referenceToStatic);

+	}

+

+	// ------------------- Hyperlinks

+

+	/**

+	 * 

+	 */

+	public void searchForHyperlink(Object selectedNode, int offset,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, ITextEditor textEditor) {

+		IXMLReferenceToStatic referenceToStatic = (IXMLReferenceToStatic) referenceTo;

+		IStaticValueQuerySpecification querySpecification = StaticQuerySpecificationUtil

+				.getStaticQuerySpecification(referenceToStatic);

+		if (querySpecification != null) {

+		}

+

+		HyperlinkCollectorForStatics collector = new HyperlinkCollectorForStatics(

+				hyperlinkRegion, hyperLinks);

+		internalSearch(selectedNode, file, collector, mathingString, false,

+				referenceToStatic);

+	}

+

+	// ------------------- Validation

+

+	/**

+	 * 

+	 */

+	public IValidationResult searchForValidation(Object selectedNode,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToStatic referenceToStatic = (IXMLReferenceToStatic) referenceTo;

+		ValidationResultForStatics collector = new ValidationResultForStatics(

+				mathingString, startIndex, endIndex);

+		internalSearch(selectedNode, file, collector, mathingString, false,

+				referenceToStatic);

+		return collector;

+	}

+

+	/**

+	 * 

+	 * @param file

+	 * @param collector

+	 * @param matchingString

+	 * @param startsWith

+	 * @param referenceToStatic

+	 */

+	private void internalSearch(Object selectedNode, IFile file,

+			IStaticValueCollector collector, String matchingString,

+			boolean startsWith, IXMLReferenceToStatic referenceToStatic) {

+		IStaticValueQuerySpecification querySpecification = StaticQuerySpecificationUtil

+				.getStaticQuerySpecification(referenceToStatic);

+		if (querySpecification != null) {

+			IStaticValueVisitor visitor = querySpecification.getVisitor(

+					selectedNode, file);

+			if (visitor == null) {

+				return;

+			}

+			StaticValueSearchEngine.getDefault().search(selectedNode, file,

+					visitor, collector, matchingString, startsWith, null);

+		}

+	}

+

+	// ----------------- Text info

+

+	public String searchForTextHover(Object selectedNode, int offset,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToStatic referenceToStatic = (IXMLReferenceToStatic) referenceTo;

+		IContentAssistAdditionalProposalInfoProvider<IStaticValue> provider = (IContentAssistAdditionalProposalInfoProvider<IStaticValue>) referenceToStatic

+				.getAdditionalProposalInfoProvider();

+		TextInfoForStatic collector = new TextInfoForStatic(provider);

+		internalSearch(selectedNode, file, collector,

+				mathingString != null ? mathingString : mathingString, false,

+				referenceToStatic);

+		return collector.getTextInfo();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ContentAssisitCollectorForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ContentAssisitCollectorForXML.java
new file mode 100644
index 0000000..04186dd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ContentAssisitCollectorForXML.java
@@ -0,0 +1,96 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.xml;

+

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToXML;

+import org.eclipse.wst.xml.search.editor.searchers.AbstractContentAssisitCollector;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Element;

+import org.w3c.dom.Node;

+import org.w3c.dom.Text;

+

+public class ContentAssisitCollectorForXML extends

+		AbstractContentAssisitCollector<IXMLReferenceToXML> implements

+		IXMLSearchDOMNodeCollector {

+

+	public ContentAssisitCollectorForXML(String forceBeforeText,

+			String forceEndText, IXMLReferenceToXML referencePath,

+			IContentAssistProposalRecorder recorder) {

+		super(forceBeforeText, forceEndText, referencePath, recorder);

+	}

+

+	public boolean add(IDOMNode node) {

+		collect(recorder, node, referencePath);

+		return true;

+	}

+

+	private void collect(final IContentAssistProposalRecorder recorder,

+			IDOMNode node, IXMLReferenceToXML referencePath) {

+		String value = null;

+		int nodeType = node.getNodeType();

+		switch (nodeType) {

+		case Node.ATTRIBUTE_NODE:

+			value = ((Attr) node).getValue();

+			break;

+		case Node.TEXT_NODE:

+			value = DOMUtils.getTextContent((Text) node);

+			break;

+		case Node.ELEMENT_NODE:

+			String targetNode = referencePath.getTargetNodes()[0];

+			if (targetNode.startsWith("@")) {

+				String attrName = targetNode.substring(1, targetNode.length());

+				String attrValue = ((Element) node).getAttribute(attrName);

+				value = attrValue;

+			} else {

+				// text node

+				Element element = ((Element) node);

+				Node firstChild = element.getFirstChild();

+				if (firstChild != null

+						&& firstChild.getNodeType() == Node.TEXT_NODE) {

+					value = DOMUtils.getTextContent((Text) firstChild);

+				}

+			}

+			break;

+		}

+		if (value == null) {

+			return;

+		}

+

+		Image image = null;

+		int relevance = 1;

+		String displayText = value;

+		String replaceText = getReplaceText(value);

+

+		Object proposedObject = null;

+

+		IContentAssistAdditionalProposalInfoProvider provider = referencePath

+				.getAdditionalProposalInfoProvider();

+		if (provider != null) {

+			String newDisplayText = provider.getDisplayText(displayText, node);

+			if (!StringUtils.isEmpty(newDisplayText)) {

+				displayText = newDisplayText;

+			}

+			image = provider.getImage(node);

+			proposedObject = provider.getTextInfo(node);

+		}

+		int cursorPosition = getCursorPosition(value);

+		recorder.recordProposal(image, relevance, displayText, replaceText,

+				cursorPosition, proposedObject);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/HyperlinkCollectorForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/HyperlinkCollectorForXML.java
new file mode 100644
index 0000000..dfb2282
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/HyperlinkCollectorForXML.java
@@ -0,0 +1,30 @@
+package org.eclipse.wst.xml.search.editor.searchers.xml;

+

+import java.util.List;

+

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.editor.internal.hyperlink.DOMNodeHyperlink;

+import org.eclipse.wst.xml.search.editor.searchers.AbstractHyperlinkCollector;

+

+public class HyperlinkCollectorForXML extends AbstractHyperlinkCollector

+		implements IXMLSearchDOMNodeCollector {

+

+	private final int startOffset;

+	private final int endOffset;

+

+	public HyperlinkCollectorForXML(IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, int startOffset, int endOffset) {

+		super(hyperlinkRegion, hyperLinks);

+		this.startOffset = startOffset;

+		this.endOffset = endOffset;

+	}

+

+	public boolean add(IDOMNode node) {

+		hyperLinks.add(new DOMNodeHyperlink(hyperlinkRegion, node, startOffset,

+				endOffset));

+		return true;

+	}

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/TextInfoForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/TextInfoForXML.java
new file mode 100644
index 0000000..e03ffbb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/TextInfoForXML.java
@@ -0,0 +1,26 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.xml;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.searchers.DefaultTextInfo;

+

+public class TextInfoForXML extends DefaultTextInfo<IDOMNode> implements

+		IXMLSearchDOMNodeCollector {

+

+	public TextInfoForXML(

+			IContentAssistAdditionalProposalInfoProvider<IDOMNode> provider) {

+		super(provider);

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ValidationResultForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ValidationResultForXML.java
new file mode 100644
index 0000000..7f3bb86
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/ValidationResultForXML.java
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.xml;

+

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.editor.validation.AbstractValidationResult;

+

+public class ValidationResultForXML extends AbstractValidationResult implements

+		IXMLSearchDOMNodeCollector {

+

+	public ValidationResultForXML(String value, int startIndex, int endIndex) {

+		super(value, startIndex, endIndex);

+	}

+

+	public boolean add(IDOMNode node) {

+		nbElements++;

+		return true;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/XMLSearcherForXML.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/XMLSearcherForXML.java
new file mode 100644
index 0000000..8ea5612
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/searchers/xml/XMLSearcherForXML.java
@@ -0,0 +1,91 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.xml;

+

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.jface.text.hyperlink.IHyperlink;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistAdditionalProposalInfoProvider;

+import org.eclipse.wst.xml.search.editor.contentassist.IContentAssistProposalRecorder;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToXML;

+import org.eclipse.wst.xml.search.editor.searchers.IXMLSearcher;

+import org.eclipse.wst.xml.search.editor.util.XMLSearcherForXMLUtils;

+import org.eclipse.wst.xml.search.editor.validation.IValidationResult;

+

+public class XMLSearcherForXML implements IXMLSearcher {

+

+	public static final IXMLSearcher INSTANCE = new XMLSearcherForXML();

+

+	// ------------------- Completions

+

+	/**

+	 * 

+	 */

+	public void searchForCompletion(Object selectedNode, String mathingString,

+			String forceBeforeText, String forceEndText, IFile file,

+			IXMLReferenceTo referenceTo, IContentAssistProposalRecorder recorder) {

+		ContentAssisitCollectorForXML collector = new ContentAssisitCollectorForXML(

+				forceBeforeText, forceEndText,

+				(IXMLReferenceToXML) referenceTo, recorder);

+		XMLSearcherForXMLUtils.search(selectedNode, mathingString, file,

+				referenceTo, collector, true);

+	}

+

+	// ------------------- Hyperlinks

+

+	/**

+	 * 

+	 */

+	public void searchForHyperlink(Object selectedNode, int offset,

+			String mathingString, int startOffset, int endOffset, IFile file,

+			IXMLReferenceTo referenceTo, IRegion hyperlinkRegion,

+			List<IHyperlink> hyperLinks, ITextEditor textEditor) {

+		HyperlinkCollectorForXML collector = new HyperlinkCollectorForXML(

+				hyperlinkRegion, hyperLinks, startOffset, endOffset);

+		XMLSearcherForXMLUtils.search(selectedNode, mathingString, file,

+				referenceTo, collector, false);

+	}

+

+	/**

+	 * 

+	 */

+	public IValidationResult searchForValidation(Object selectedNode,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		ValidationResultForXML collector = new ValidationResultForXML(

+				mathingString, startIndex, endIndex);

+		XMLSearcherForXMLUtils.search(selectedNode, mathingString, file,

+				referenceTo, collector, false);

+		return collector;

+	}

+

+	// ----------------- Text info

+

+	public String searchForTextHover(Object selectedNode, int offset,

+			String mathingString, int startIndex, int endIndex, IFile file,

+			IXMLReferenceTo referenceTo) {

+		IXMLReferenceToXML referenceToXML = (IXMLReferenceToXML) referenceTo;

+		IContentAssistAdditionalProposalInfoProvider<IDOMNode> provider = (IContentAssistAdditionalProposalInfoProvider<IDOMNode>) referenceToXML

+				.getAdditionalProposalInfoProvider();

+		if (provider == null) {

+			return null;

+		}

+		TextInfoForXML collector = new TextInfoForXML(provider);

+		XMLSearcherForXMLUtils.search(selectedNode, mathingString, file,

+				referenceTo, collector, false);

+		return collector.getTextInfo();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/JavaStringLiteralDocumentVisitor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/JavaStringLiteralDocumentVisitor.java
new file mode 100644
index 0000000..fc4ddc9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/JavaStringLiteralDocumentVisitor.java
@@ -0,0 +1,61 @@
+package org.eclipse.wst.xml.search.editor.statics;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jdt.core.JavaCore;

+import org.eclipse.jdt.core.dom.AST;

+import org.eclipse.jdt.core.dom.ASTNode;

+import org.eclipse.jdt.core.dom.ASTParser;

+import org.eclipse.jdt.core.dom.ASTVisitor;

+import org.eclipse.jdt.core.dom.CompilationUnit;

+import org.eclipse.jdt.core.dom.StringLiteral;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitor;

+

+public class JavaStringLiteralDocumentVisitor implements IStaticValueVisitor {

+

+	public void visit(Object selectedNode, IFile file, final String matching,

+			final boolean startsWith, final IStaticValueCollector collector) {

+		final IFile javaFile = getFile(selectedNode, file);

+

+		final ASTParser parser = ASTParser.newParser(AST.JLS3);

+		parser.setResolveBindings(true);

+		parser.setSource(JavaCore.createCompilationUnitFrom(javaFile));

+		final CompilationUnit cu = (CompilationUnit) parser.createAST(null);

+

+		ASTVisitor visitor = new ASTVisitor() {

+

+			public boolean visit(org.eclipse.jdt.core.dom.StringLiteral node) {

+

+				ASTNode parent = accept(node);

+				if (parent != null) {

+					String stringValue = node.getLiteralValue();

+

+					boolean match = (startsWith ? stringValue

+							.startsWith(matching) : stringValue

+							.equals(matching));

+					if (match) {

+						collector.add(new StaticValueDocument(stringValue,

+								parent.toString(), node.getStartPosition() + 1,

+								stringValue.length(), javaFile));

+					}

+				}

+

+				return true;

+			};

+

+		};

+		cu.accept(visitor);

+	}

+

+	protected ASTNode accept(StringLiteral node) {

+		ASTNode parent = node.getParent();

+		return (parent != null

+				&& parent.getNodeType() == ASTNode.CLASS_INSTANCE_CREATION ? parent

+				: null);

+	}

+

+	protected IFile getFile(Object selectedNode, IFile file) {

+		return file;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocument.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocument.java
new file mode 100644
index 0000000..558e65e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocument.java
@@ -0,0 +1,42 @@
+package org.eclipse.wst.xml.search.editor.statics;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.xml.search.core.statics.StaticValue;

+

+public class StaticValueDocument extends StaticValue {

+

+	private final String line;

+	private final int startOffset;

+	private final int length;

+	private final IResource resource;

+

+	public StaticValueDocument(String key, String line, int startOffset,

+			int length, IResource resource) {

+		super(key, getDescription(line, key));

+		this.line = line;

+		this.startOffset = startOffset;

+		this.length = length;

+		this.resource = resource;

+	}

+

+	public String getLine() {

+		return line;

+	}

+

+	public int getStartOffset() {

+		return startOffset;

+	}

+

+	public static String getDescription(String line, String key) {

+		return line.replaceAll("\"" + key + "\"", "\"<b>" + key + "</b>\"");

+	}

+

+	public IResource getResource() {

+		return resource;

+	}

+

+	public int getLength() {

+		return length;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocumentVisitor.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocumentVisitor.java
new file mode 100644
index 0000000..bfe80ae
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/statics/StaticValueDocumentVisitor.java
@@ -0,0 +1,73 @@
+package org.eclipse.wst.xml.search.editor.statics;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.ui.editors.text.TextFileDocumentProvider;

+import org.eclipse.ui.texteditor.IDocumentProvider;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueCollector;

+import org.eclipse.wst.xml.search.core.statics.IStaticValueVisitor;

+

+public class StaticValueDocumentVisitor implements IStaticValueVisitor {

+

+	public void visit(Object selectedNode, IFile file, String matching,

+			boolean startsWith, IStaticValueCollector collector) {

+		final IFile documentFile = getFile(selectedNode, file);

+

+		final IDocumentProvider provider = new TextFileDocumentProvider();

+		try {

+			provider.connect(documentFile);

+

+			int startOffset = 0;

+			boolean match = false;

+			final IDocument jdoc = provider.getDocument(documentFile);

+			int nol = jdoc.getNumberOfLines();

+			for (int lidx = 0; lidx < nol; lidx++) {

+				IRegion li = jdoc.getLineInformation(lidx);

+				String line = jdoc.get(li.getOffset(), li.getLength());

+				startOffset = li.getOffset();

+				String[] ss = line.split("\"");

+				if (ss.length > 1) {

+					for (int i = 1; i < ss.length; i += 2) {

+						if (i == 1) {

+							startOffset += ss[0].length();

+						}

+						final String proposedWid = ss[i];

+						if (proposedWid.length() > 0

+								&& !proposedWid.contains(" ")) {

+							match = (startsWith ? proposedWid

+									.startsWith(matching) : proposedWid

+									.equals(matching));

+							if (match) {

+								collector.add(new StaticValueDocument(

+										proposedWid, line, startOffset + 1,

+										proposedWid.length(), documentFile));

+							} else {

+								startOffset += proposedWid.length();

+							}

+

+							// proposals.add(new

+							// CustomCompletionProposal(proposedWid,

+							// rtr.getOffset(), existingWid.length(),

+							// rtr.getOffset(), img, proposedWid, null,

+							// line.replaceAll("\"" + proposedWid + "\"",

+							// "\"<b>" + proposedWid + "</b>\""), 0, true));

+

+						} else {

+							startOffset += proposedWid.length();

+						}

+					}

+				}

+			}

+		} catch (Throwable e) {

+			e.printStackTrace();

+		} finally {

+			provider.disconnect(documentFile);

+		}

+	}

+

+	protected IFile getFile(Object selectedNode, IFile file) {

+		return file;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JavaMethodQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JavaMethodQuerySpecificationUtil.java
new file mode 100644
index 0000000..5ea752e
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JavaMethodQuerySpecificationUtil.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.util;

+

+import org.eclipse.wst.xml.search.editor.internal.searchers.javamethod.JavaMethodQuerySpecificationrManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToJavaMethod;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.IJavaMethodQuerySpecification;

+

+public class JavaMethodQuerySpecificationUtil {

+

+	public static IJavaMethodQuerySpecification getQuerySpecification(

+			IXMLReferenceToJavaMethod referenceToJavaMethod) {

+		return JavaMethodQuerySpecificationrManager.getDefault()

+				.getQuerySpecification(

+						referenceToJavaMethod.getQuerySpecificationId());

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JdtUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JdtUtils.java
new file mode 100644
index 0000000..b444dd7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/JdtUtils.java
@@ -0,0 +1,573 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.util;

+

+import java.beans.Introspector;

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.List;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IFolder;

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.NullProgressMonitor;

+import org.eclipse.jdt.core.IImportDeclaration;

+import org.eclipse.jdt.core.IJarEntryResource;

+import org.eclipse.jdt.core.IJavaElement;

+import org.eclipse.jdt.core.IJavaProject;

+import org.eclipse.jdt.core.IMethod;

+import org.eclipse.jdt.core.IPackageFragment;

+import org.eclipse.jdt.core.IPackageFragmentRoot;

+import org.eclipse.jdt.core.IType;

+import org.eclipse.jdt.core.ITypeHierarchy;

+import org.eclipse.jdt.core.JavaCore;

+import org.eclipse.jdt.core.JavaModelException;

+import org.eclipse.jdt.core.Signature;

+import org.eclipse.jdt.internal.core.NamedMember;

+import org.eclipse.wst.xml.search.core.queryspecifications.container.IMultiResourceProvider;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.jdt.SuperTypeHierarchyCache;

+import org.eclipse.wst.xml.search.editor.searchers.javamethod.requestor.IJavaMethodRequestor;

+

+/**

+ * Utility class that provides several helper methods for working with Eclipse's

+ * JDT.

+ * 

+ */

+public class JdtUtils {

+

+	public static IType[] EMPTY_TYPE = new IType[0];

+

+	/**

+	 * 

+	 * Returns the corresponding Java project or <code>null</code> a for given

+	 * project.

+	 * 

+	 * @param project

+	 *            the project the Java project is requested for

+	 * 

+	 * @return the requested Java project or <code>null</code> if the Java

+	 *         project is not defined or the project is not

+	 * 

+	 *         accessible

+	 */

+	public static IJavaProject getJavaProject(IProject project) {

+		if (project.isAccessible())

+			try {

+				if (project.hasNature(JavaCore.NATURE_ID))

+					return (IJavaProject) project.getNature(JavaCore.NATURE_ID);

+			} catch (CoreException e) {

+				Trace.trace(Trace.SEVERE,

+						(new StringBuilder(

+								"Error getting Java project for project '"))

+								.append(project.getName()).append("'")

+								.toString(), e);

+			}

+		return null;

+	}

+

+	public static IFolder getJavaProjectOutputFolder(IProject project) {

+		IJavaProject javaProject = getJavaProject(project);

+		if (javaProject != null) {

+			try {

+				return ResourcesPlugin.getWorkspace().getRoot()

+						.getFolder(javaProject.getOutputLocation());

+			} catch (JavaModelException e) {

+				Trace.trace(Trace.SEVERE, (new StringBuilder(

+						"Error getting Java project output for project '"))

+						.append(project.getName()).append("'").toString(), e);

+			}

+		}

+		return null;

+	}

+

+	public static IResource[] getJavaProjectSrcFolders(IProject project) {

+		IJavaProject javaProject = getJavaProject(project);

+		if (javaProject != null) {

+			try {

+				List<IResource> sources = new ArrayList<IResource>();

+				IPackageFragmentRoot[] roots = javaProject

+						.getPackageFragmentRoots();

+				IPackageFragmentRoot root = null;

+				for (int i = 0; i < roots.length; i++) {

+					root = roots[i];

+					if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {

+						sources.add(root.getCorrespondingResource());

+					}

+				}

+				return sources.toArray(IMultiResourceProvider.EMPTY_RESOURCE);

+			} catch (JavaModelException e) {

+				Trace.trace(Trace.SEVERE, (new StringBuilder(

+						"Error getting Java project src for project '"))

+						.append(project.getName()).append("'").toString(), e);

+			}

+		}

+		return null;

+	}

+

+	public static String getPackageName(IContainer container) {

+		IJavaProject javaProject = getJavaProject(container.getProject());

+		if (javaProject != null) {

+			String containerBasePath = container.getFullPath().toString();

+			IResource[] srcs = getJavaProjectSrcFolders(container.getProject());

+			IResource src = null;

+			for (int i = 0; i < srcs.length; i++) {

+				src = srcs[i];

+				String srcBasePath = src.getFullPath().toString();

+				if (containerBasePath.startsWith(srcBasePath)) {

+					String packageName = containerBasePath.substring(

+							srcBasePath.length() + 1,

+							containerBasePath.length());

+					return packageName.replaceAll("/", ".");

+				}

+			}

+			return null;

+		}

+		return null;

+	}

+

+	public static IJarEntryResource getJavaResourceFileFromBinary(

+			IProject project, String jarNamePattern, String packageName,

+			String fileName) {

+		IJavaProject javaProject = getJavaProject(project);

+		if (javaProject != null) {

+			try {

+				IPackageFragmentRoot[] roots = javaProject

+						.getPackageFragmentRoots();

+				IPackageFragmentRoot root = null;

+				for (int i = 0; i < roots.length; i++) {

+					root = roots[i];

+					if (root.getKind() == IPackageFragmentRoot.K_BINARY) {

+						if (StringUtils.isEmpty(jarNamePattern)

+								|| root.getElementName().startsWith(

+										jarNamePattern)) {

+							Object[] nonJavaResources = null;

+							if (packageName != null) {

+								IPackageFragment fragment = root

+										.getPackageFragment(packageName);

+								if (fragment != null) {

+									nonJavaResources = fragment

+											.getNonJavaResources();

+								}

+							} else {

+								nonJavaResources = root.getNonJavaResources();

+							}

+							if (nonJavaResources != null) {

+								Object nonJavaResource = null;

+								for (int j = 0; j < nonJavaResources.length; j++) {

+									nonJavaResource = nonJavaResources[j];

+									if (nonJavaResource instanceof IJarEntryResource) {

+										IJarEntryResource r = (IJarEntryResource) nonJavaResource;

+										if (r.isFile()

+												&& fileName.equals(r.getName())) {

+											return r;

+										}

+									}

+								}

+							}

+						}

+					}

+				}

+			} catch (JavaModelException e) {

+				Trace.trace(Trace.SEVERE, (new StringBuilder(

+						"Error getting Java project src for project '"))

+						.append(project.getName()).append("'").toString(), e);

+			}

+		}

+		return null;

+	}

+

+	public static IJarEntryResource[] getJavaResourcesFileFromBinary(

+			IProject project, String jarNamePattern, String packageName,

+			String fileName) {

+		Collection<IJarEntryResource> files = new ArrayList<IJarEntryResource>();

+		IJavaProject javaProject = getJavaProject(project);

+		if (javaProject != null) {

+			try {

+				IPackageFragmentRoot[] roots = javaProject

+						.getPackageFragmentRoots();

+				IPackageFragmentRoot root = null;

+				for (int i = 0; i < roots.length; i++) {

+					root = roots[i];

+					if (root.getKind() == IPackageFragmentRoot.K_BINARY) {

+						if (StringUtils.isEmpty(jarNamePattern)

+								|| root.getElementName().contains(

+										jarNamePattern)) {

+							Object[] nonJavaResources = null;

+							if (packageName != null) {

+								IPackageFragment fragment = root

+										.getPackageFragment(packageName);

+								if (fragment != null) {

+									nonJavaResources = fragment

+											.getNonJavaResources();

+								}

+							} else {

+								nonJavaResources = root.getNonJavaResources();

+							}

+							if (nonJavaResources != null) {

+								Object nonJavaResource = null;

+								for (int j = 0; j < nonJavaResources.length; j++) {

+									nonJavaResource = nonJavaResources[j];

+									if (nonJavaResource instanceof IJarEntryResource) {

+										IJarEntryResource r = (IJarEntryResource) nonJavaResource;

+										if (r.isFile()

+												&& r.getName().contains(

+														fileName)) {

+											files.add(r);

+										}

+									}

+								}

+							}

+						}

+					}

+				}

+			} catch (JavaModelException e) {

+				Trace.trace(Trace.SEVERE, (new StringBuilder(

+						"Error getting Java project src for project '"))

+						.append(project.getName()).append("'").toString(), e);

+			}

+		}

+		return files.toArray(new IJarEntryResource[files.size()]);

+	}

+

+	/**

+	 * 

+	 * Returns the corresponding Java type for given full-qualified class name.

+	 * 

+	 * @param project

+	 *            the JDT project the class belongs to

+	 * 

+	 * @param className

+	 *            the full qualified class name of the requested Java type

+	 * 

+	 * @return the requested Java type or null if the class is not defined or

+	 *         the project is not accessible

+	 */

+

+	public static IType getJavaType(IProject project, String className) {

+		IJavaProject javaProject = JdtUtils.getJavaProject(project);

+		if (className != null) {

+			// For inner classes replace '$' by '.'

+			int pos = className.lastIndexOf('$');

+			if (pos > 0) {

+				className = className.replace('$', '.');

+			}

+

+			try {

+				IType type = null;

+				// First look for the type in the Java project

+				if (javaProject != null) {

+					// TODO CD not sure why we need

+					type = javaProject.findType(className,

+							new NullProgressMonitor());

+					if (type != null) {

+						return type;

+					}

+				}

+

+				// Then look for the type in the referenced Java projects

+				for (IProject refProject : project.getReferencedProjects()) {

+					IJavaProject refJavaProject = JdtUtils

+							.getJavaProject(refProject);

+					if (refJavaProject != null) {

+						type = refJavaProject.findType(className);

+						if (type != null) {

+							return type;

+						}

+					}

+				}

+

+				// fall back

+				return null;

+			} catch (CoreException e) {

+				Trace.trace(Trace.SEVERE, "Error getting Java type '"

+						+ className + "'", e);

+			}

+		}

+		return null;

+	}

+

+	public static IType getSuperType(IType type) throws JavaModelException {

+		if (type == null)

+			return null;

+		String name = type.getSuperclassName();

+		if (name == null

+				&& !type.getFullyQualifiedName().equals(Object.class.getName()))

+			name = Object.class.getName();

+		if (name != null) {

+			if (type.isBinary())

+				return type.getJavaProject().findType(name);

+			String resolvedName = JdtUtils.resolveClassName(name, type);

+			if (resolvedName != null)

+				return type.getJavaProject().findType(resolvedName);

+		}

+		return null;

+	}

+

+	public static String resolveClassName(String className, IType type) {

+

+		if (className == null || type == null) {

+			return className;

+		}

+

+		// replace binary $ inner class name syntax with . for source level

+		className = className.replace('$', '.');

+		String dotClassName = new StringBuilder().append('.').append(className)

+				.toString();

+		IProject project = type.getJavaProject().getProject();

+		try {

+			// Special handling for some well-know classes

+			if (className.startsWith("java.lang")

+					&& getJavaType(project, className) != null) {

+				return className;

+			}

+

+			// Check if the class is imported

+			if (!type.isBinary()) {

+				// Strip className to first segment to support

+				// ReflectionUtils.MethodCallback

+				int ix = className.lastIndexOf('.');

+				String firstClassNameSegment = className;

+

+				if (ix > 0) {

+					firstClassNameSegment = className.substring(0, ix);

+				}

+

+				// Iterate the imports

+				for (IImportDeclaration importDeclaration : type

+						.getCompilationUnit().getImports()) {

+					String importName = importDeclaration.getElementName();

+					// Wildcard imports -> check if the package + className is a

+					// valid type

+					if (importDeclaration.isOnDemand()) {

+						String newClassName = new StringBuilder(

+								importName.substring(0, importName.length() - 1))

+								.append(className).toString();

+						if (getJavaType(project, newClassName) != null) {

+							return newClassName;

+

+						}

+					}

+

+					// Concrete import matching .className at the end -> check

+					// if type exists

+					else if (importName.endsWith(dotClassName)

+							&& getJavaType(project, importName) != null) {

+						return importName;

+					}

+

+					// Check if className is multi segmented

+					// (ReflectionUtils.MethodCallback)

+					// -> check if the first segment

+					else if (!className.equals(firstClassNameSegment)) {

+						if (importName.endsWith(firstClassNameSegment)) {

+							String newClassName = new StringBuilder(

+									importName.substring(0,

+											importName.lastIndexOf('.') + 1))

+									.append(className).toString();

+

+							if (getJavaType(project, newClassName) != null) {

+								return newClassName;

+							}

+						}

+					}

+				}

+			}

+

+			// Check if the class is in the same package as the type

+			String packageName = type.getPackageFragment().getElementName();

+			String newClassName = new StringBuilder(packageName).append(

+					dotClassName).toString();

+

+			if (getJavaType(project, newClassName) != null) {

+				return newClassName;

+			}

+

+			// Check if the className is sufficient (already fully-qualified)

+			if (getJavaType(project, className) != null) {

+				return className;

+			}

+

+			// Check if the class is coming from the java.lang

+			newClassName = new StringBuilder("java.lang").append(dotClassName)

+					.toString();

+			if (getJavaType(project, newClassName) != null) {

+				return newClassName;

+			}

+

+			// Fall back to full blown resolution

+			String[][] fullInter = type.resolveType(className);

+			if (fullInter != null && fullInter.length > 0) {

+				return fullInter[0][0] + "." + fullInter[0][1];

+			}

+		} catch (JavaModelException e) {

+			Trace.trace(Trace.SEVERE, "Error resolveClassName'" + className

+					+ "'", e);

+		}

+		return className;

+

+	}

+

+	public static String[] getParameterTypesString(IMethod method) {

+		try {

+			String parameterQualifiedTypes[] = Signature

+					.getParameterTypes(method.getSignature());

+			int length = parameterQualifiedTypes != null ? parameterQualifiedTypes.length

+					: 0;

+			String parameterPackages[] = new String[length];

+			for (int i = 0; i < length; i++) {

+				parameterQualifiedTypes[i] = parameterQualifiedTypes[i]

+						.replace('/', '.');

+				parameterPackages[i] = Signature

+						.getSignatureSimpleName(parameterQualifiedTypes[i]);

+			}

+

+			return parameterPackages;

+		} catch (IllegalArgumentException _ex) {

+		} catch (JavaModelException _ex) {

+		}

+		return null;

+	}

+

+	public static String getReturnTypeString(IMethod method,

+			boolean classTypesOnly) {

+		try {

+			String qualifiedReturnType = Signature.getReturnType(method

+					.getSignature());

+			if (!classTypesOnly || qualifiedReturnType.startsWith("L")

+					|| qualifiedReturnType.startsWith("Q"))

+				return Signature.getSignatureSimpleName(qualifiedReturnType

+						.replace('/', '.'));

+		} catch (IllegalArgumentException _ex) {

+		} catch (JavaModelException _ex) {

+		}

+		return null;

+	}

+

+	public static String getPropertyNameFromMethodName(IMethod method) {

+		String methodName = method.getElementName();

+		int index = methodName.lastIndexOf('.');

+		if (index > 0)

+			methodName = methodName.substring(index + 1);

+		String replaceText = methodName.substring("set".length());

+		if (replaceText != null)

+			replaceText = Introspector.decapitalize(replaceText);

+		return replaceText;

+	}

+

+	public static IMethod findMethod(IType type, String methodNameToFind,

+			IJavaMethodRequestor requestor) throws JavaModelException {

+		if (type == null) {

+			return null;

+		}

+		IMethod method = null;

+		IMethod[] methods = type.getMethods();

+		for (int i = 0; i < methods.length; i++) {

+			method = methods[i];

+			IStatus status = requestor.matchTotally(null, methodNameToFind,

+					method);

+			if (status != null && status.isOK()) {

+				return method;

+			}

+		}

+		return findMethod(JdtUtils.getSuperType(type), methodNameToFind,

+				requestor);

+	}

+

+	public static boolean doesImplement(IResource resource, IType type,

+			IType superType) {

+		if (resource == null || type == null || superType == null)

+			return false;

+		// if(className.startsWith("java.") || className.startsWith("javax."))

+		// try

+		// {

+		// ClassLoader cls = getClassLoader(resource.getProject(), null);

+		// Class typeClass = cls.loadClass(type.getFullyQualifiedName('$'));

+		// Class interfaceClass = cls.loadClass(className);

+		// return typeClass.equals(interfaceClass) ||

+		// interfaceClass.isAssignableFrom(typeClass);

+		// }

+		// catch(Throwable _ex) { }

+		return doesImplementWithJdt(resource, type, superType);

+	}

+

+	private static boolean doesImplementWithJdt(IResource resource, IType type,

+			IType interfaceType) {

+		// IType interfaceType = getJavaType(resource.getProject(), className);

+		// if (interfaceType == null) {

+		// return false;

+		// }

+		IType subTypes[];

+		try {

+			subTypes = SuperTypeHierarchyCache.getTypeHierarchy(interfaceType)

+					.getAllSubtypes(interfaceType);

+			if (subTypes != null) {

+				for (IType subType : subTypes) {

+					if (subType.equals(type)) {

+						return true;

+					}

+				}

+			}

+		} catch (JavaModelException e) {

+			Trace.trace(Trace.SEVERE, "Error doesImplementWithJdt", e);

+		}

+		return false;

+

+	}

+

+	public static IType[] getImplementsType(IType type) {

+		try {

+			return SuperTypeHierarchyCache.getTypeHierarchy(type)

+					.getAllClasses();

+		} catch (JavaModelException e) {

+			return null;

+		}

+	}

+

+	public static boolean isImplementsClass(final IJavaElement javaElement, final String className)

+			throws JavaModelException {

+		Assert.isNotNull(javaElement);

+		if (javaElement != null && javaElement instanceof NamedMember) {

+			final NamedMember method = (NamedMember) javaElement;

+			final IType type = method.getDeclaringType();

+			if (type != null) {

+				if (type.getFullyQualifiedName().equals(

+						className)) {

+					return true;

+				}

+				return hierarchyContainsComponent(type, className);

+			}

+		}

+		return false;

+	}

+

+	public static boolean hierarchyContainsComponent(final IType type, final String className)

+			throws JavaModelException {

+		Assert.isNotNull(type);

+		final ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null);

+		if (hierarchy != null) {

+			final IType[] supertypes = hierarchy.getAllSupertypes(type);

+			for (final IType iType : supertypes) {

+				if (iType.getFullyQualifiedName().equals(

+						className)) {

+					return true;

+				}

+			}

+		}

+		return false;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/PropertiesQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/PropertiesQuerySpecificationUtil.java
new file mode 100644
index 0000000..552abd5
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/PropertiesQuerySpecificationUtil.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.util;

+

+import org.eclipse.wst.xml.search.core.properties.IPropertiesQuerySpecification;

+import org.eclipse.wst.xml.search.core.properties.PropertiesQuerySpecificationManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToProperty;

+

+public class PropertiesQuerySpecificationUtil {

+

+	public static IPropertiesQuerySpecification getQuerySpecification(

+			IXMLReferenceToProperty referenceToProperty) {

+		return PropertiesQuerySpecificationManager.getDefault()

+				.getQuerySpecification(

+						referenceToProperty.getQuerySpecificationId());

+	}

+

+	public static IPropertiesQuerySpecification[] getQuerySpecifications(

+			IXMLReferenceToProperty referenceToProperty) {

+		IPropertiesQuerySpecification querySpecification = getQuerySpecification(referenceToProperty);

+		if (querySpecification != null) {

+			IPropertiesQuerySpecification[] result = new IPropertiesQuerySpecification[1];

+			result[0] = querySpecification;

+			return result;

+		}

+		return IPropertiesQuerySpecification.EMPTY;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/ResourceQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/ResourceQuerySpecificationUtil.java
new file mode 100644
index 0000000..a1ad300
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/ResourceQuerySpecificationUtil.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.util;

+

+import org.eclipse.wst.xml.search.core.resource.IResourceQuerySpecification;

+import org.eclipse.wst.xml.search.core.resource.ResourceQuerySpecificationManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToResource;

+

+public class ResourceQuerySpecificationUtil {

+

+	public static IResourceQuerySpecification getQuerySpecification(

+			IXMLReferenceToResource referencetoResource) {

+		return ResourceQuerySpecificationManager.getDefault()

+				.getQuerySpecification(

+						referencetoResource.getQuerySpecificationId());

+	}

+

+	public static IResourceQuerySpecification[] getQuerySpecifications(

+			IXMLReferenceToResource referencetoResource) {

+		IResourceQuerySpecification querySpecification = getQuerySpecification(referencetoResource);

+		if (querySpecification != null) {

+			IResourceQuerySpecification[] result = new IResourceQuerySpecification[1];

+			result[0] = querySpecification;

+			return result;

+		}

+		return IResourceQuerySpecification.EMPTY;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/StaticQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/StaticQuerySpecificationUtil.java
new file mode 100644
index 0000000..0ed3113
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/StaticQuerySpecificationUtil.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.util;

+

+import org.eclipse.wst.xml.search.core.statics.IStaticValueQuerySpecification;

+import org.eclipse.wst.xml.search.core.statics.StaticValueQuerySpecificationManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToStatic;

+

+public class StaticQuerySpecificationUtil {

+

+	public static IStaticValueQuerySpecification getStaticQuerySpecification(

+			IXMLReferenceToStatic referenceToStatic) {

+		return StaticValueQuerySpecificationManager.getDefault()

+				.getQuerySpecification(

+						referenceToStatic.getQuerySpecificationId());

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLQuerySpecificationUtil.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLQuerySpecificationUtil.java
new file mode 100644
index 0000000..50b5deb
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLQuerySpecificationUtil.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.util;

+

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.queryspecifications.XMLQuerySpecificationManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;

+

+public class XMLQuerySpecificationUtil {

+

+	public static IXMLQuerySpecification getQuerySpecification(

+			IXMLReferencePath path) {

+		return getQuerySpecification(path.getQuerySpecificationId());

+	}

+

+	public static IXMLQuerySpecification getQuerySpecification(

+			String querySpecificationId) {

+		return XMLQuerySpecificationManager.getDefault().getQuerySpecification(

+				querySpecificationId);

+	}

+	

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLSearcherForXMLUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLSearcherForXMLUtils.java
new file mode 100644
index 0000000..d190e52
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/util/XMLSearcherForXMLUtils.java
@@ -0,0 +1,101 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.util;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.core.SimpleXMLSearchEngine;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecification;

+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;

+import org.eclipse.wst.xml.search.editor.internal.reporter.XMLSearchReporterManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo.ToType;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToXML;

+import org.w3c.dom.Node;

+

+public class XMLSearcherForXMLUtils {

+

+	public static void search(Object selectedNode, String mathingString,

+			IFile file, IXMLReferenceTo referenceTo,

+			IXMLSearchDOMNodeCollector collector, boolean startsWith) {

+		if (referenceTo.getType() != ToType.XML)

+			return;

+

+		final IXMLReferenceToXML referencePath = (IXMLReferenceToXML) referenceTo;

+		IXMLQuerySpecification querySpecification = XMLQuerySpecificationUtil

+				.getQuerySpecification(referencePath);

+		if (querySpecification != null) {

+

+			String xpathProcessorId = querySpecification.getXPathProcessorId();

+			if (xpathProcessorId == null) {

+				IXPathProcessorType processor = XPathProcessorManager

+						.getDefault().getDefaultProcessor();

+				xpathProcessorId = processor != null ? processor.getId() : null;

+			}

+

+			String xpath = null;

+			if (startsWith) {

+				xpath = referencePath.getQuery(selectedNode, mathingString,

+						querySpecification.getStartsWithStringQueryBuilder());

+			} else {

+				xpath = referencePath.getQuery(selectedNode, mathingString,

+						querySpecification.getEqualsStringQueryBuilder());

+			}

+

+			Namespaces namespaceInfos = referencePath.getNamespaces();			

+

+			if (querySpecification.isMultiResource()) {

+				SimpleXMLSearchEngine.getDefault().search(

+						querySpecification.getResources(selectedNode, file),

+						querySpecification.getRequestor(),

+						querySpecification.getVisitor(), xpath,

+						xpathProcessorId, namespaceInfos, collector,

+						selectedNode, XMLSearchReporterManager.getDefault(),

+						null);

+			} else {

+				SimpleXMLSearchEngine.getDefault().search(

+						querySpecification.getResource(selectedNode, file),

+						querySpecification.getRequestor(),

+						querySpecification.getVisitor(), xpath,

+						xpathProcessorId, namespaceInfos, collector,

+						selectedNode, XMLSearchReporterManager.getDefault(),

+						null);

+			}

+

+			// Storage

+			if (querySpecification.isMultiStorage()) {

+				SimpleXMLSearchEngine.getDefault().search(

+						querySpecification.getStorages(selectedNode, file),

+						querySpecification.getRequestor(),

+						querySpecification.getVisitor(), xpath,

+						xpathProcessorId, namespaceInfos, collector,

+						selectedNode, XMLSearchReporterManager.getDefault(),

+						null);

+

+			} else {

+				if (querySpecification.isSimpleStorage()) {

+					SimpleXMLSearchEngine.getDefault().search(

+							querySpecification.getStorage(selectedNode, file),

+							querySpecification.getRequestor(),

+							querySpecification.getVisitor(), xpath,

+							xpathProcessorId, namespaceInfos, collector,

+							selectedNode,

+							XMLSearchReporterManager.getDefault(), null);

+				}

+			}

+

+		}

+

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractTagValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractTagValidator.java
new file mode 100644
index 0000000..142fdfe
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractTagValidator.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;

+import org.eclipse.wst.validation.internal.provisional.core.IReporter;

+import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;

+

+public abstract class AbstractTagValidator extends AbstractValidator {

+

+	@Override

+	protected void doValidate(

+			IStructuredDocumentRegion structuredDocumentRegion,

+			IReporter reporter, IFile file, IStructuredModel model) {

+		if (isStartTag(structuredDocumentRegion)) {

+			doValidateStartTag(structuredDocumentRegion, reporter, file, model);

+		} else if (isXMLContent(structuredDocumentRegion)) {

+			doValidateXMLContent(structuredDocumentRegion, reporter, file,

+					model);

+		}

+	}

+

+	protected abstract void doValidateXMLContent(

+			IStructuredDocumentRegion structuredDocumentRegion,

+			IReporter reporter, IFile file, IStructuredModel model);

+

+	protected abstract void doValidateStartTag(

+			IStructuredDocumentRegion structuredDocumentRegion,

+			IReporter reporter, IFile file, IStructuredModel model);

+

+	/**

+	 * Determines whether the IStructuredDocumentRegion is a XML "start tag"

+	 * since they need to be checked for proper XML attribute region sequences

+	 * 

+	 * @param structuredDocumentRegion

+	 * 

+	 */

+	private boolean isStartTag(

+			IStructuredDocumentRegion structuredDocumentRegion) {

+		if ((structuredDocumentRegion == null)

+				|| structuredDocumentRegion.isDeleted()) {

+			return false;

+		}

+		return structuredDocumentRegion.getFirstRegion().getType() == DOMRegionContext.XML_TAG_OPEN;

+	}

+

+	/**

+	 * Determines if the IStructuredDocumentRegion is XML Content

+	 * 

+	 * @param structuredDocumentRegion

+	 * 

+	 */

+	private boolean isXMLContent(

+			IStructuredDocumentRegion structuredDocumentRegion) {

+		if ((structuredDocumentRegion == null)

+				|| structuredDocumentRegion.isDeleted()) {

+			return false;

+		}

+		return structuredDocumentRegion.getFirstRegion().getType() == DOMRegionContext.XML_CONTENT;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidationResult.java
new file mode 100644
index 0000000..714bc3f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidationResult.java
@@ -0,0 +1,53 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+public abstract class AbstractValidationResult implements IValidationResult {

+

+	private final String value;

+	private final int startIndex;

+	private final int endIndex;

+	protected int nbElements = 0;

+

+	public AbstractValidationResult(String value, int startIndex, int endIndex) {

+		this.value = value;

+		this.startIndex = startIndex;

+		this.endIndex = endIndex;

+	}

+	

+	public AbstractValidationResult() {

+		this(null, -1, -1);

+	}

+

+	public String getValue() {

+		return value;

+	}

+

+	public int getStartIndex() {

+		return startIndex;

+	}

+

+	public int getEndIndex() {

+		return endIndex;

+	}

+

+	public boolean isMulti() {

+		return false;

+	}

+	

+	public int getNbElements() {

+		return nbElements;

+	}

+	

+	public void setNbElements(int nbElements) {

+		this.nbElements = nbElements;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidator.java
new file mode 100644
index 0000000..68568f6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/AbstractValidator.java
@@ -0,0 +1,147 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.jface.text.IRegion;

+import org.eclipse.wst.sse.core.StructuredModelManager;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;

+import org.eclipse.wst.sse.ui.internal.reconcile.validator.ISourceValidator;

+import org.eclipse.wst.sse.ui.internal.reconcile.validator.IncrementalReporter;

+import org.eclipse.wst.validation.internal.core.ValidationException;

+import org.eclipse.wst.validation.internal.provisional.core.IReporter;

+import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;

+import org.eclipse.wst.validation.internal.provisional.core.IValidator;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+

+public abstract class AbstractValidator implements IValidator, ISourceValidator {

+

+	private IDocument fDocument;

+

+	private void setDocument(IDocument doc) {

+		fDocument = doc;

+	}

+

+	protected IDocument getDocument() {

+		return fDocument;

+	}

+

+	public void connect(IDocument document) {

+		setDocument(document);

+	}

+

+	public void disconnect(IDocument document) {

+		setDocument(null);

+	}

+

+	public void cleanup(IReporter reporter) {

+

+	}

+

+	public void validate(IValidationContext helper, IReporter reporter)

+			throws ValidationException {

+		if (getDocument() == null) {

+			return;

+		}

+		if (!(reporter instanceof IncrementalReporter)) {

+			return;

+		}

+		if (!(getDocument() instanceof IStructuredDocument)) {

+			return;

+		}

+

+		// remove old messages

+		reporter.removeAllMessages(this);

+

+		IFile file = null;

+		String[] delta = helper.getURIs();

+		if (delta.length > 0) {

+			// get the file, model and document:

+			file = ValidatorUtils.getFile(delta[0]);

+		}

+

+		IStructuredDocumentRegion[] regions = ((IStructuredDocument) fDocument)

+				.getStructuredDocumentRegions();

+		validate(reporter, file, regions);

+

+	}

+

+	public void validate(IRegion dirtyRegion, IValidationContext helper,

+			IReporter reporter) {

+		if (getDocument() == null) {

+			return;

+		}

+		if (!(reporter instanceof IncrementalReporter)) {

+			return;

+		}

+		if (!(getDocument() instanceof IStructuredDocument)) {

+			return;

+		}

+

+		// remove old messages

+		reporter.removeAllMessages(this);

+

+		IFile file = null;

+		String[] delta = helper.getURIs();

+		if (delta.length > 0) {

+			// get the file, model and document:

+			file = ValidatorUtils.getFile(delta[0]);

+		}

+

+		IStructuredDocumentRegion[] regions = ((IStructuredDocument) fDocument)

+				.getStructuredDocumentRegions(dirtyRegion.getOffset(),

+						dirtyRegion.getLength());

+

+		validate(reporter, file, regions);

+	}

+

+	private void validate(IReporter reporter, IFile file,

+			IStructuredDocumentRegion[] regions) {

+		IStructuredModel model = null;

+		try {

+			model = StructuredModelManager.getModelManager()

+					.getExistingModelForRead(file);

+			if (model == null) {

+				model = StructuredModelManager.getModelManager()

+						.getModelForRead(file);

+			}

+			if (model != null) {

+

+				for (int i = 0; i < regions.length; i++) {

+					validate(regions[i], reporter, file, model);

+				}

+			}

+		} catch (Throwable e) {

+			Trace.trace(Trace.SEVERE, e.getMessage(), e);

+		} finally {

+			if (model != null)

+				model.releaseFromRead();

+		}

+	}

+

+	private void validate(IStructuredDocumentRegion structuredDocumentRegion,

+			IReporter reporter, IFile file, IStructuredModel model) {

+

+		if (structuredDocumentRegion == null) {

+			return;

+		}

+

+		doValidate(structuredDocumentRegion, reporter, file,  model);

+	}

+

+	protected abstract void doValidate(

+			IStructuredDocumentRegion structuredDocumentRegion,

+			IReporter reporter, IFile file, IStructuredModel model);

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/DefaultValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/DefaultValidationResult.java
new file mode 100644
index 0000000..c72b797
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/DefaultValidationResult.java
@@ -0,0 +1,22 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+public class DefaultValidationResult extends AbstractValidationResult {

+

+	public void addElement() {

+		nbElements++;

+	}

+

+	public boolean isMulti() {

+		return false;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IMultiValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IMultiValidationResult.java
new file mode 100644
index 0000000..c9b335b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IMultiValidationResult.java
@@ -0,0 +1,20 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+import java.util.List;

+

+public interface IMultiValidationResult extends IValidationResult {

+

+	boolean add(IValidationResult result);

+

+	List<IValidationResult> getResults();

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IValidationResult.java
new file mode 100644
index 0000000..c1e4b1b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/IValidationResult.java
@@ -0,0 +1,47 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+public interface IValidationResult {

+

+	public static final IValidationResult OK = new AbstractValidationResult() {

+		public int getNbElements() {

+			return 1;

+		}

+

+		public void setNbElements(int nbElements) {

+

+		}

+	};

+

+	public static final IValidationResult NOK = new AbstractValidationResult() {

+		public int getNbElements() {

+			return 0;

+		}

+

+		public void setNbElements(int nbElements) {

+

+		}

+	};

+

+	String getValue();

+

+	int getStartIndex();

+

+	int getEndIndex();

+

+	int getNbElements();

+

+	void setNbElements(int nbElements);

+

+	boolean isMulti();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/LocalizedMessage.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/LocalizedMessage.java
new file mode 100644
index 0000000..6d781bd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/LocalizedMessage.java
@@ -0,0 +1,64 @@
+/*******************************************************************************

+ * 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

+ * http://www.eclipse.org/legal/epl-v10.html

+ *

+ * Contributors:

+ * IBM Corporation - initial API and implementation

+ * 		Code comes from org.eclipse.wst.validation.internal.operations.LocalizedMessage

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+import java.util.Locale;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.wst.validation.internal.core.Message;

+

+/**

+ * This class is provided for validators which run only in UI and whose messages, because they

+ * come from another tool, are already localized. LocalizedMessage cannot be used by any validator

+ * which needs to run in both WebSphere and WSAD.

+ */

+public class LocalizedMessage extends Message {

+	private String _message;

+

+	public LocalizedMessage(int severity, String messageText) {

+		this(severity, messageText, null);

+	}

+

+	public LocalizedMessage(int severity, String messageText, IResource targetObject) {

+		this(severity, messageText, (Object) targetObject);

+	}

+

+	public LocalizedMessage(int severity, String messageText, Object targetObject) {

+		super(null, severity, null);

+		setLocalizedMessage(messageText);

+		setTargetObject(targetObject);

+	}

+

+	public void setLocalizedMessage(String message) {

+		_message = message;

+	}

+

+	public String getLocalizedMessage() {

+		return _message;

+	}

+

+	public String getText() {

+		return getLocalizedMessage();

+	}

+

+	public String getText(ClassLoader cl) {

+		return getLocalizedMessage();

+	}

+

+	public String getText(Locale l) {

+		return getLocalizedMessage();

+	}

+

+	public String getText(Locale l, ClassLoader cl) {

+		return getLocalizedMessage();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/MultiValidationResult.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/MultiValidationResult.java
new file mode 100644
index 0000000..e4fe265
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/MultiValidationResult.java
@@ -0,0 +1,54 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+import java.util.ArrayList;

+import java.util.List;

+

+public class MultiValidationResult extends ArrayList<IValidationResult>

+		implements IMultiValidationResult {

+

+	@Override

+	public boolean add(IValidationResult result) {

+		if (result != null) {

+			super.add(result);

+		}

+		return false;

+	}

+

+	public int getNbElements() {

+		return 0;

+	}

+

+	public void setNbElements(int nbElements) {

+

+	}

+

+	public String getValue() {

+		return null;

+	}

+

+	public int getStartIndex() {

+		return -1;

+	}

+

+	public int getEndIndex() {

+		return -1;

+	}

+

+	public boolean isMulti() {

+		return true;

+	}

+

+	public List<IValidationResult> getResults() {

+		return this;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/ValidatorUtils.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/ValidatorUtils.java
new file mode 100644
index 0000000..5d74544
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/ValidatorUtils.java
@@ -0,0 +1,132 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.core.runtime.Path;

+import org.eclipse.jface.text.BadLocationException;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.osgi.util.NLS;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;

+import org.eclipse.wst.validation.internal.provisional.core.IMessage;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.internal.Messages;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceTo;

+

+public class ValidatorUtils {

+

+	public static LocalizedMessage createMessage(IDOMAttr attr,

+			IXMLReference reference, int nbElements) {

+		if (nbElements == 1) {

+			return null;

+		}

+		String textContent = attr.getValue();

+		int start = attr.getValueRegionStartOffset();

+		return createMessage(attr, start, reference, nbElements, textContent);

+	}

+

+	public static LocalizedMessage createMessage(IDOMText text,

+			IXMLReference reference, int nbElements) {

+		if (nbElements == 1) {

+			return null;

+		}

+		String textContent = DOMUtils.getTextContent(text);

+		int start = text.getStartOffset();

+		return createMessage(text, start, reference, nbElements, textContent);

+	}

+

+	public static LocalizedMessage createMessage(IDOMNode node, int start,

+			IXMLReference reference, int nbElements, String textContent) {

+		int length = textContent.trim().length() + 2;

+		String messageText = getMessageText(reference, nbElements, textContent);

+		int severity = getSeverity(reference, nbElements);

+		return createMessage(start, length, messageText, severity, node

+				.getStructuredDocument());

+	}

+

+	public static int getSeverity(IXMLReference reference, int nbElements) {

+		if (nbElements < 1) {

+			return IMessage.HIGH_SEVERITY;

+		}

+		return IMessage.NORMAL_SEVERITY;

+	}

+

+	public static String getMessageText(IXMLReference reference,

+			int nbElements, String textContent) {

+		if (nbElements < 1) {

+			return NLS.bind(ValidatorUtils.getNotFoundedMessage(reference

+					.getTo().get(0)), textContent, nbElements);

+		} else {

+			return NLS.bind(ValidatorUtils.getNonUniqueMessage(reference

+					.getTo().get(0)), textContent, nbElements);

+		}

+	}

+

+	public static LocalizedMessage createMessage(int start, int length,

+			String messageText, int severity,

+			IStructuredDocument structuredDocument) {

+		int lineNo = getLineNumber(start, structuredDocument);

+		LocalizedMessage message = new LocalizedMessage(severity, messageText);

+		message.setOffset(start);

+		message.setLength(length);

+		message.setLineNo(lineNo);

+		return message;

+	}

+

+	private static int getLineNumber(int start, IDocument document) {

+		int lineNo = -1;

+		try {

+			lineNo = document.getLineOfOffset(start);

+		} catch (BadLocationException e) {

+			Trace.trace(Trace.SEVERE, e.getMessage(), e);

+		}

+		return lineNo;

+	}

+

+	/**

+	 * @param delta

+	 *            the IFileDelta containing the file name to get

+	 * @return the IFile

+	 */

+	public static IFile getFile(String delta) {

+		IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(

+				new Path(delta));

+		if (file != null && file.exists())

+			return file;

+		return null;

+	}

+

+	public static String getNotFoundedMessage(IXMLReferenceTo referenceTo) {

+		switch (referenceTo.getType()) {

+		case RESOURCE:

+			return Messages.Validation_FileNotFounded;

+		case JAVA:

+			return Messages.Validation_ClassNotFounded;

+		case XML:

+			return Messages.Validation_ElementNotFounded;

+		}

+		return Messages.Validation_ElementNotFounded;

+	}

+

+	public static String getNonUniqueMessage(IXMLReferenceTo referenceTo) {

+		switch (referenceTo.getType()) {

+		case XML:

+			return Messages.Validation_ElementNonUnique;

+		}

+		return Messages.Validation_ElementNonUnique;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesBatchValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesBatchValidator.java
new file mode 100644
index 0000000..7f5383c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesBatchValidator.java
@@ -0,0 +1,324 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.validation;

+

+import java.io.IOException;

+import java.util.Collection;

+import java.util.HashSet;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IWorkspaceRoot;

+import org.eclipse.core.resources.IWorkspaceRunnable;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.NullProgressMonitor;

+import org.eclipse.core.runtime.Path;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.core.runtime.jobs.ISchedulingRule;

+import org.eclipse.core.runtime.jobs.Job;

+import org.eclipse.jdt.core.JavaCore;

+import org.eclipse.wst.sse.core.StructuredModelManager;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+import org.eclipse.wst.validation.AbstractValidator;

+import org.eclipse.wst.validation.ValidationResult;

+import org.eclipse.wst.validation.ValidationState;

+import org.eclipse.wst.validation.internal.core.Message;

+import org.eclipse.wst.validation.internal.core.ValidationException;

+import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;

+import org.eclipse.wst.validation.internal.provisional.core.IMessage;

+import org.eclipse.wst.validation.internal.provisional.core.IReporter;

+import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;

+import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.EqualsStringQueryBuilder;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.eclipse.wst.xml.search.editor.internal.Trace;

+import org.eclipse.wst.xml.search.editor.internal.XMLSearchEditorPlugin;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferenceContainer;

+import org.eclipse.wst.xml.search.editor.internal.references.XMLReferencesManager;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.IXMLReferencePath;

+import org.w3c.dom.NodeList;

+

+public class XMLReferencesBatchValidator extends AbstractValidator implements

+		IValidatorJob {

+

+	// for debugging

+	static final boolean DEBUG = Boolean

+			.valueOf(

+					Platform

+							.getDebugOption("org.eclipse.wst.xml.search.editor/debug/validator")).booleanValue(); //$NON-NLS-1$

+

+	/**

+	 * List of IResources that the currently validating file depends upon

+	 */

+	private Collection<IResource> fDependsOn;

+

+	public ISchedulingRule getSchedulingRule(IValidationContext helper) {

+		if (helper instanceof IWorkbenchContext) {

+			/*

+			 * Use a single build rule when running batch validation.

+			 */

+			return ResourcesPlugin.getWorkspace().getRuleFactory().buildRule();

+		}

+		/*

+		 * For other kinds of validation, use no specific rule

+		 */

+		return null;

+	}

+

+	/**

+	 * Validate one file. It's assumed that the file has JSP content type.

+	 * 

+	 * @param file

+	 * @param reporter

+	 */

+	void validateFile(IFile file, IReporter reporter) {

+		try {

+			file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());

+		} catch (CoreException e) {

+			Trace.trace(Trace.SEVERE, "", e);

+		}

+		IStructuredModel model = null;

+		try {

+			// get DOM model on behalf of all XML references validators

+			model = StructuredModelManager.getModelManager().getModelForRead(

+					file);

+			if (!reporter.isCancelled() && model != null

+					&& model instanceof IDOMModel) {

+				reporter.removeAllMessages(this, file);

+				performValidation(file, reporter, (IDOMModel) model);

+			}

+		} catch (IOException e) {

+			Trace.trace(Trace.SEVERE, "", e);

+		} catch (CoreException e) {

+			Trace.trace(Trace.SEVERE, "", e);

+		} finally {

+			if (model != null)

+				model.releaseFromRead();

+		}

+	}

+

+	public IStatus validateInJob(final IValidationContext helper,

+			final IReporter reporter) throws ValidationException {

+		Job currentJob = Job.getJobManager().currentJob();

+		ISchedulingRule rule = null;

+		if (currentJob != null) {

+			rule = currentJob.getRule();

+		}

+		IWorkspaceRunnable validationRunnable = new IWorkspaceRunnable() {

+			public void run(IProgressMonitor monitor) throws CoreException {

+				try {

+					doValidate(helper, reporter);

+				} catch (ValidationException e) {

+					throw new CoreException(new Status(IStatus.ERROR,

+							XMLSearchEditorPlugin.PLUGIN_ID, 0,

+							XMLSearchEditorPlugin.PLUGIN_ID, e));

+				}

+			}

+		};

+		try {

+			JavaCore.run(validationRunnable, rule, new NullProgressMonitor());

+		} catch (CoreException e) {

+			if (e.getCause() instanceof ValidationException) {

+				throw (ValidationException) e.getCause();

+			}

+			throw new ValidationException(new LocalizedMessage(

+					IMessage.ERROR_AND_WARNING, e.getMessage()), e);

+		}

+		return Status.OK_STATUS;

+	}

+

+	public void cleanup(IReporter reporter) {

+		// TODO Auto-generated method stub

+

+	}

+

+	public void validate(IValidationContext helper, IReporter reporter)

+			throws ValidationException {

+		doValidate(helper, reporter);

+	}

+

+	void doValidate(IValidationContext helper, IReporter reporter)

+			throws ValidationException {

+		String[] uris = helper.getURIs();

+		if (uris.length > 0) {

+			IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();

+			IFile currentFile = null;

+			for (int i = 0; i < uris.length && !reporter.isCancelled(); i++) {

+				currentFile = wsRoot.getFile(new Path(uris[i]));

+				if (currentFile != null && currentFile.exists()) {

+					if (shouldValidate(currentFile)) {

+						Message message = new LocalizedMessage(

+								IMessage.LOW_SEVERITY, currentFile

+										.getFullPath().toString().substring(1));

+						reporter.displaySubtask(this, message);

+						validateFile(currentFile, reporter);

+					}

+					if (DEBUG)

+						System.out.println("validating: [" + uris[i] + "]"); //$NON-NLS-1$ //$NON-NLS-2$

+				}

+			}

+		} else {

+			// if uris[] length 0 -> validate() gets called for each project

+			// if (helper instanceof IWorkbenchContext) {

+			// IProject project = ((IWorkbenchContext) helper).getProject();

+			//

+			// Message message = new LocalizedMessage(IMessage.LOW_SEVERITY,

+			// NLS.bind("Gathering files in {0}", project

+			// .getFullPath()));

+			// reporter.displaySubtask(this, message);

+			//

+			// JSPFileVisitor visitor = new JSPFileVisitor(reporter);

+			// try {

+			// // collect all jsp files for the project

+			// project.accept(visitor, IResource.DEPTH_INFINITE);

+			// } catch (CoreException e) {

+			// if (DEBUG)

+			// e.printStackTrace();

+			// }

+			// IFile[] files = visitor.getFiles();

+			// for (int i = 0; i < files.length && !reporter.isCancelled(); i++)

+			// {

+			// if (shouldValidate(files[i])) {

+			//

+			// message = new LocalizedMessage(IMessage.LOW_SEVERITY,

+			// files[i].getFullPath().toString().substring(1));

+			// reporter.displaySubtask(this, message);

+			//

+			// validateFile(files[i], reporter);

+			// }

+			// if (DEBUG)

+			//						System.out.println("validating: [" + files[i] + "]"); //$NON-NLS-1$ //$NON-NLS-2$

+			// }

+			// }

+		}

+	}

+

+	/**

+	 * Determine if a given file should be validated.

+	 * 

+	 * @param file

+	 *            The file that may be validated.

+	 * @return True if the file should be validated, false otherwise.

+	 */

+	private static boolean shouldValidate(IFile file) {

+		IResource resource = file;

+		do {

+			if (resource.isDerived() || resource.isTeamPrivateMember()

+					|| !resource.isAccessible()

+					|| resource.getName().charAt(0) == '.') {

+				return false;

+			}

+			resource = resource.getParent();

+		} while ((resource.getType() & IResource.PROJECT) == 0);

+

+		return true;

+	}

+

+	void addDependsOn(IResource resource) {

+		fDependsOn.add(resource);

+	}

+

+	@Override

+	public ValidationResult validate(final IResource resource, int kind,

+			ValidationState state, IProgressMonitor monitor) {

+		if (resource.getType() != IResource.FILE)

+			return null;

+		final ValidationResult result = new ValidationResult();

+		final IReporter reporter = result.getReporter(monitor);

+		fDependsOn = new HashSet<IResource>();

+

+		IWorkspaceRunnable validationRunnable = new IWorkspaceRunnable() {

+			public void run(IProgressMonitor monitor) throws CoreException {

+				validateFile((IFile) resource, reporter);

+				result.setDependsOn((IResource[]) fDependsOn

+						.toArray(new IResource[fDependsOn.size()]));

+				fDependsOn.clear();

+			}

+		};

+		Job currentJob = Job.getJobManager().currentJob();

+		ISchedulingRule rule = null;

+		if (currentJob != null) {

+			rule = currentJob.getRule();

+		}

+		try {

+			JavaCore.run(validationRunnable, rule, new NullProgressMonitor());

+		} catch (CoreException e) {

+			Trace.trace(Trace.SEVERE, "", e);

+		}

+		return result;

+	}

+

+	private void performValidation(IFile file, IReporter reporter,

+			IDOMModel model) {

+		if (reporter.isCancelled()) {

+			// validation, was canceled, stop the validation

+			return;

+		}

+		XMLReferenceContainer container = XMLReferencesManager.getInstance()

+				.getXMLReferenceContainer(model.getContentTypeIdentifier());

+		if (container == null) {

+			// the current DOM model doesn't define XML references, stop the

+			// validation

+			return;

+		}

+		Collection<IXMLReference> allReferences = container

+				.getAllXMLReferences();

+		if (allReferences.isEmpty()) {

+			// the current DOM model doesn't define XML references, stop the

+			// validation

+			return;

+		}

+		// Loop for each XML reference to get Node by using "from" reference and

+		// validate

+		// each Node founded with "to" reference

+		IDOMDocument document = model.getDocument();

+		NamespaceInfos namespaceInfos = XPathManager.getManager()

+				.getNamespaceInfo(document);

+		for (IXMLReference reference : allReferences) {

+			IXMLReferencePath from = reference.getFrom();			

+			if (!from.hasWildCard()) {

+				String path = from.getPath();

+				String[] targetNodes = from.getTargetNodes();

+				for (String targetNode : targetNodes) {

+					String xpath = EqualsStringQueryBuilder.INSTANCE.build(

+							path, null, null)

+							+ "/" + targetNode;

+					try {

+						NodeList list = XPathManager.getManager()

+								.evaluateNodeSet(null, document, xpath,

+										namespaceInfos, null);

+						for (int i = 0; i < list.getLength(); i++) {

+							IDOMNode n = (IDOMNode) list.item(i);

+							reference.getValidator().validate(reference, n,

+									file, this, reporter, true);

+						}

+					} catch (XPathExpressionException e) {

+						Trace.trace(Trace.SEVERE, "", e);

+					}

+				}

+			} else {

+

+			}

+		}

+

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesValidator.java b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesValidator.java
new file mode 100644
index 0000000..57bd477
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.editor/src/org/eclipse/wst/xml/search/editor/validation/XMLReferencesValidator.java
@@ -0,0 +1,60 @@
+package org.eclipse.wst.xml.search.editor.validation;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;

+import org.eclipse.wst.validation.internal.provisional.core.IReporter;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.editor.references.IXMLReference;

+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;

+import org.w3c.dom.NamedNodeMap;

+import org.w3c.dom.Node;

+

+public class XMLReferencesValidator extends AbstractTagValidator {

+

+	@Override

+	protected void doValidateStartTag(

+			IStructuredDocumentRegion structuredDocumentRegion,

+			IReporter reporter, IFile file, IStructuredModel model) {

+		IDOMNode node = DOMUtils.getNodeByOffset(model,

+				structuredDocumentRegion.getStartOffset());

+		if (node == null || node.getNodeType() != Node.ELEMENT_NODE) {

+			return;

+		}

+

+		IDOMElement element = (IDOMElement) node;

+		NamedNodeMap map = element.getAttributes();

+		for (int i = 0; i < map.getLength(); i++) {

+			IDOMAttr attr = (IDOMAttr) map.item(i);

+			IXMLReference reference = XMLReferencesUtil.getXMLReference(attr,

+					file);

+			if (reference != null) {

+				reference.getValidator().validate(reference, attr, file, this,

+						reporter, false);

+			}

+		}

+	}

+

+	@Override

+	protected void doValidateXMLContent(

+			IStructuredDocumentRegion structuredDocumentRegion,

+			IReporter reporter, IFile file, IStructuredModel model) {

+

+		IDOMNode node = DOMUtils.getNodeByOffset(model,

+				structuredDocumentRegion.getStartOffset());

+		if (node == null || node.getNodeType() != Node.TEXT_NODE) {

+			return;

+		}

+		IDOMText text = (IDOMText) node;

+		IXMLReference reference = XMLReferencesUtil.getXMLReference(node, file);

+		if (reference != null) {

+			reference.getValidator().validate(reference, node, file, this,

+					reporter, false);

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/.classpath b/plugins/org.eclipse.wst.xml.search.ui/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/plugins/org.eclipse.wst.xml.search.ui/.project b/plugins/org.eclipse.wst.xml.search.ui/.project
new file mode 100644
index 0000000..e732a40
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.wst.xml.search.ui</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/plugins/org.eclipse.wst.xml.search.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.xml.search.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..12ceb96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Thu Nov 18 10:20:11 CET 2010

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

+org.eclipse.jdt.core.compiler.compliance=1.5

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.5

diff --git a/plugins/org.eclipse.wst.xml.search.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.xml.search.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..1e26bbd
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.wst.xml.core,
+ org.eclipse.core.resources,
+ org.eclipse.wst.sse.core,
+ org.eclipse.ui,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.ui.editors,
+ org.eclipse.search,
+ org.eclipse.ui.ide,
+ org.eclipse.jface.text,
+ org.eclipse.wst.sse.ui
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.wst.xml.search.ui,
+ org.eclipse.wst.xml.search.ui.util
diff --git a/plugins/org.eclipse.wst.xml.search.ui/build.properties b/plugins/org.eclipse.wst.xml.search.ui/build.properties
new file mode 100644
index 0000000..1cb217c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/build.properties
@@ -0,0 +1,7 @@
+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .,\

+               plugin.properties,\

+               plugin.xml,\

+               icons/

diff --git a/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/attribute_obj.gif b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/attribute_obj.gif
new file mode 100644
index 0000000..79d49d0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/attribute_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/element_obj.gif b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/element_obj.gif
new file mode 100644
index 0000000..3567815
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/element_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/text_obj.gif b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/text_obj.gif
new file mode 100644
index 0000000..2a2b4b6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/text_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/xmlsearch_obj.gif b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/xmlsearch_obj.gif
new file mode 100644
index 0000000..14eb1be
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/icons/obj16/xmlsearch_obj.gif
Binary files differ
diff --git a/plugins/org.eclipse.wst.xml.search.ui/plugin.properties b/plugins/org.eclipse.wst.xml.search.ui/plugin.properties
new file mode 100644
index 0000000..6a0bbd8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/plugin.properties
@@ -0,0 +1,29 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+pluginName=WST XML Search UI

+providerName=Angelo ZERR

+

+# Action sets

+XMLSearchActionSet.label= XML Search

+XMLSearchActionSet.description= Action set containing search related XML actions

+

+# Search dialog

+openXMLSearchPageAction.label=&XML..

+

+# Menus

+searchMenu.label= Se&arch

+

+# XML Search page

+XMLSearchPage.label=XML Search

+

+# Preferences

+pageNameXMLSearch=XML Search

+pagenameXPathProcessor=XPath processor
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.ui/plugin.xml b/plugins/org.eclipse.wst.xml.search.ui/plugin.xml
new file mode 100644
index 0000000..4ca9a96
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/plugin.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.4"?>

+<plugin>

+

+   <extension

+        point="org.eclipse.search.searchResultViewPages">

+		<viewPage

+			id="org.eclipse.wst.xml.search.ui.XMLSearchResultPage"

+			searchResultClass="org.eclipse.wst.xml.search.ui.internal.XMLSearchResult"

+			class="org.eclipse.wst.xml.search.ui.internal.XMLSearchResultPage">

+		</viewPage>

+   </extension>

+   

+   <extension

+         point="org.eclipse.search.searchPages">

+      <page

+            showScopeSection="true"

+            canSearchEnclosingProjects="true"

+            label="%XMLSearchPage.label"

+            icon="icons/obj16/xmlsearch_obj.gif"

+            extensions="*:1"

+            class="org.eclipse.wst.xml.search.ui.internal.dialog.XMLSearchPage"

+            sizeHint="460,160"

+            id="org.eclipse.wst.xml.search.ui.dialog.XMLSearchPage">

+      </page>

+   </extension>

+      

+   <extension

+         point="org.eclipse.ui.actionSets">

+      <actionSet

+            label="%XMLSearchActionSet.label"

+            description="%XMLSearchActionSet.description"

+            visible="true"

+            id="org.eclipse.wst.xml.search.ui.SearchActionSet">

+<!-- see http://bugs.eclipse.org/bugs/show_bug.cgi?id=15684    -->

+<!-- Note: The menu (re-) definition has to be here due to bug: -->

+<!-- =================================================================== -->

+<!-- Search Menu                                                         -->

+<!-- =================================================================== -->

+         <menu

+               label="%searchMenu.label"

+               path="navigate"

+               id="org.eclipse.search.menu">

+				<groupMarker name="internalDialogGroup"/>   <!-- not to be used by clients  -->

+				<groupMarker name="dialogGroup"/>           <!-- to be used by clients      -->

+				<separator name="fileSearchContextMenuActionsGroup"/> <!-- to be used by clients      -->

+	         	<separator name="contextMenuActionsGroup"/> <!-- to be used by clients -->

+	         	<separator name="occurencesActionsGroup"/> <!-- to be used by clients -->

+	         	<separator name="extraSearchGroup"/> <!-- to be used by clients -->

+         </menu>

+<!-- dialog group  -->

+         <action

+               label="%openXMLSearchPageAction.label"

+               icon="icons/obj16/xmlsearch_obj.gif"

+               helpContextId="org.eclipse.wst.xml.search.ui.dialog.xml_search_action_context"

+               class="org.eclipse.wst.xml.search.ui.internal.dialog.OpenXMLSearchPageAction"

+               menubarPath="org.eclipse.search.menu/dialogGroup"

+               id="org.eclipse.wst.xml.search.ui.dialog.OpenXMLSearchPage">

+         </action>   

+     </actionSet>

+  </extension>

+                           			       

+  <!--<extension

+         point="org.eclipse.ui.actionSetPartAssociations">

+      <actionSetPartAssociation

+            targetID="org.eclipse.wst.xml.search.ui.SearchActionSet">

+         <part

+               id="org.eclipse.jdt.ui.ProjectsView">

+         </part>

+         <part

+               id="org.eclipse.search.SearchResultView">

+         </part>

+      </actionSetPartAssociation>

+   </extension>-->  

+                        

+	<extension point="org.eclipse.ui.preferencePages">

+	  <page

+	        category="org.eclipse.wst.xml.ui.preferences.xml"

+	        class="org.eclipse.wst.xml.search.ui.internal.preferences.XMLSearchPreferencePage"

+	        id="org.eclipse.wst.xml.search.references"

+	        name="%pageNameXMLSearch">

+	  </page>

+		<page category="org.eclipse.wst.xml.search.references"

+			class="org.eclipse.wst.xml.search.ui.internal.preferences.XPathProcessorPreferencePage"

+			id="org.eclipse.wst.xml.search.ui.preferences.XPathProcessorPreferencePage" 

+			name="%pagenameXPathProcessor">

+		</page>	

+	</extension>

+		                            			       

+</plugin>

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/DecoratingXMLSearchLabelProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/DecoratingXMLSearchLabelProvider.java
new file mode 100644
index 0000000..28be35d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/DecoratingXMLSearchLabelProvider.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui;

+

+import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider;

+import org.eclipse.jface.viewers.ILabelProvider;

+import org.eclipse.ui.PlatformUI;

+

+/**

+ * 

+ * Extension of {@link DecoratingStyledCellLabelProvider} for DOM-SSE.

+ * 

+ */

+public class DecoratingXMLSearchLabelProvider extends

+		DecoratingStyledCellLabelProvider implements ILabelProvider {

+

+	public DecoratingXMLSearchLabelProvider(XMLLabelProvider provider) {

+		super(provider, PlatformUI.getWorkbench().getDecoratorManager()

+				.getLabelDecorator(), null);

+	}

+

+	public String getText(Object element) {

+		return getStyledText(element).getString();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/ImageResource.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/ImageResource.java
new file mode 100644
index 0000000..c4f6330
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/ImageResource.java
@@ -0,0 +1,159 @@
+/*******************************************************************************

+ * Copyright (c) 2003, 2011 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

+ *     Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search

+ *     

+ *     Code comes from org.eclipse.jst.server.ui.internal.ImageResource     

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui;

+

+import java.net.URL;

+import java.util.HashMap;

+import java.util.Map;

+

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.jface.resource.ImageRegistry;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.wst.xml.search.ui.internal.Trace;

+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;

+

+/**

+ * Utility class to handle image resources.

+ */

+public class ImageResource {

+	// the image registry

+	private static ImageRegistry imageRegistry;

+

+	// map of image descriptors since these

+	// will be lost by the image registry

+	private static Map<String, ImageDescriptor> imageDescriptors;

+

+	// base urls for images

+	private static URL ICON_BASE_URL;

+

+	private static final String URL_OBJ = "obj16/";

+

+	// General Object Images

+	public static final String IMG_ATTRIBUTE_OBJ = "attribute_obj";

+	public static final String IMG_TEXT_OBJ = "text_obj";

+	public static final String IMG_ELEMENT_OBJ = "element_obj";

+

+	static {

+		try {

+			String pathSuffix = "icons/";

+			ICON_BASE_URL = XMLSearchUIPlugin.getDefault().getBundle()

+					.getEntry(pathSuffix);

+		} catch (Exception e) {

+			Trace.trace(Trace.SEVERE, "Images error", e);

+		}

+	}

+

+	/**

+	 * Cannot construct an ImageResource. Use static methods only.

+	 */

+	private ImageResource() {

+		// do nothing

+	}

+

+	/**

+	 * Dispose of element images that were created.

+	 */

+	protected static void dispose() {

+		// do nothing

+	}

+

+	/**

+	 * Return the image with the given key.

+	 * 

+	 * @param key

+	 *            java.lang.String

+	 * @return org.eclipse.swt.graphics.Image

+	 */

+	public static Image getImage(String key) {

+		return getImage(key, null);

+	}

+

+	/**

+	 * Return the image with the given key.

+	 * 

+	 * @param key

+	 *            java.lang.String

+	 * @return org.eclipse.swt.graphics.Image

+	 */

+	public static Image getImage(String key, String keyIfImageNull) {

+		if (imageRegistry == null)

+			initializeImageRegistry();

+		Image image = imageRegistry.get(key);

+		if (image == null) {

+			if (keyIfImageNull != null) {

+				return getImage(keyIfImageNull, null);

+			}

+			imageRegistry.put(key, ImageDescriptor.getMissingImageDescriptor());

+			image = imageRegistry.get(key);

+		}

+		return image;

+	}

+

+	/**

+	 * Return the image descriptor with the given key.

+	 * 

+	 * @param key

+	 *            java.lang.String

+	 * @return org.eclipse.jface.resource.ImageDescriptor

+	 */

+	public static ImageDescriptor getImageDescriptor(String key) {

+		if (imageRegistry == null)

+			initializeImageRegistry();

+		ImageDescriptor id = imageDescriptors.get(key);

+		if (id != null)

+			return id;

+

+		return ImageDescriptor.getMissingImageDescriptor();

+	}

+

+	/**

+	 * Initialize the image resources.

+	 */

+	protected static void initializeImageRegistry() {

+		imageRegistry = new ImageRegistry();

+		imageDescriptors = new HashMap<String, ImageDescriptor>();

+

+		// load general object images

+		registerImage(IMG_ELEMENT_OBJ, URL_OBJ + IMG_ELEMENT_OBJ + ".gif");

+		registerImage(IMG_ATTRIBUTE_OBJ, URL_OBJ + IMG_ATTRIBUTE_OBJ + ".gif");

+		registerImage(IMG_TEXT_OBJ, URL_OBJ + IMG_TEXT_OBJ + ".gif");

+

+		// PlatformUI

+		// .getWorkbench()

+		// .getProgressService()

+		// .registerIconForFamily(getImageDescriptor(IMG_SERVER),

+		// GeneratorUtil.SERVER_JOB_FAMILY);

+	}

+

+	/**

+	 * Register an image with the registry.

+	 * 

+	 * @param key

+	 *            java.lang.String

+	 * @param partialURL

+	 *            java.lang.String

+	 */

+	private static void registerImage(String key, String partialURL) {

+		try {

+			ImageDescriptor id = ImageDescriptor.createFromURL(new URL(

+					ICON_BASE_URL, partialURL));

+			imageRegistry.put(key, id);

+			imageDescriptors.put(key, id);

+		} catch (Exception e) {

+			Trace.trace(Trace.SEVERE, "Error registering image " + key

+					+ " from " + partialURL, e);

+		}

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLLabelProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLLabelProvider.java
new file mode 100644
index 0000000..8670c9c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLLabelProvider.java
@@ -0,0 +1,93 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;

+import org.eclipse.jface.viewers.LabelProvider;

+import org.eclipse.jface.viewers.StyledString;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.ui.model.WorkbenchLabelProvider;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.ui.util.DOMUtils;

+import org.w3c.dom.Node;

+

+/**

+ * 

+ * {@link LabelProvider} implementation for DOM-SSE Node {@link IDOMNode}.

+ * 

+ */

+public class XMLLabelProvider extends LabelProvider implements

+		IStyledLabelProvider {

+

+	private final WorkbenchLabelProvider fLabelProvider;

+	private final Image fAttributeMatchImage;

+	private final Image fElementMatchImage;

+	private final Image fTextMatchImage;

+

+	public XMLLabelProvider() {

+		this.fLabelProvider = new WorkbenchLabelProvider();

+		this.fAttributeMatchImage = ImageResource

+				.getImage(ImageResource.IMG_ATTRIBUTE_OBJ);

+		this.fTextMatchImage = ImageResource

+				.getImage(ImageResource.IMG_TEXT_OBJ);

+		this.fElementMatchImage = ImageResource

+				.getImage(ImageResource.IMG_ELEMENT_OBJ);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)

+	 */

+	public String getText(Object object) {

+		return getStyledText(object).getString();

+	}

+

+	public StyledString getStyledText(Object element) {

+		if (element instanceof IResource) {

+			IResource resource = (IResource) element;

+			return new StyledString(resource.getName());

+		}

+		if (element instanceof IDOMNode) {

+			IDOMNode node = (IDOMNode) element;

+			return new StyledString(DOMUtils.toString(node));

+		}

+		return new StyledString(element.toString());

+	}

+

+	@Override

+	public Image getImage(Object element) {

+		if (element instanceof Node) {

+			// Element is DOM node

+			Node node = (Node) element;

+			switch (node.getNodeType()) {

+			case Node.ATTRIBUTE_NODE:

+				return fAttributeMatchImage;

+				// returns attribute icon

+			case Node.TEXT_NODE:

+				// returns text icon

+				return fTextMatchImage;

+			case Node.ELEMENT_NODE:

+				// returns element icon

+				return fElementMatchImage;

+			}

+		}

+		if (!(element instanceof IResource))

+			return null;

+

+		// Returns icon according the IResource type.

+		IResource resource = (IResource) element;

+		Image image = fLabelProvider.getImage(resource);

+		return image;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLMatch.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLMatch.java
new file mode 100644
index 0000000..680c4d9
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/XMLMatch.java
@@ -0,0 +1,26 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui;

+

+import org.eclipse.search.ui.text.Match;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+

+/**

+ * Search Match extension for DOM-SSE Node {@link IDOMNode}.

+ * 

+ */

+public class XMLMatch extends Match {

+

+	public XMLMatch(IDOMNode node) {

+		super(node, node.getStartOffset(), node.getLength());

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/IXMLSearchContentProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/IXMLSearchContentProvider.java
new file mode 100644
index 0000000..6aedd5f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/IXMLSearchContentProvider.java
@@ -0,0 +1,23 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal;

+

+/**

+ * Interface for XML search content provider.

+ * 

+ */

+public interface IXMLSearchContentProvider {

+

+	void elementsChanged(Object[] updatedElements);

+

+	void clear();

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.java
new file mode 100644
index 0000000..35ac41b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.java
@@ -0,0 +1,74 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal;

+

+import org.eclipse.osgi.util.NLS;

+

+/**

+ * Messages for XML Search UI.

+ * 

+ */

+public class Messages extends NLS {

+

+	// Search query

+	public static String XMLSearchQuery_label;

+	public static String XMLSearchQuery_status_ok_message;

+

+	// Search error

+	public static String Search_Error_search_title;

+	public static String Search_Error_search_message;

+	public static String Search_Error_search_notsuccessful_title;

+	public static String Search_Error_search_notsuccessful_message;

+

+	// Search open file

+	public static String XMLSearchPage_open_file_dialog_title;

+	public static String XMLSearchPage_open_file_failed;

+	public static String XMLSearchPage_error_marker;

+

+	public static String XMLSearchQuery_xpathPattern;

+

+	// XML Search page

+	public static String SearchPage_xpath_text;

+	public static String SearchPage_xpath_hint;

+	public static String SearchPage_xpath_errorRequired;

+	public static String SearchPage_XPathProcessor_text;

+	public static String SearchPage_xpathProcessor_errorRequired;

+	public static String SearchPage_browse;

+	public static String SearchPage_fileNamePatterns_text;

+	public static String SearchPage_fileNamePatterns_hint;

+

+	public static String XMLSearchPage_replace_searchproblems_title;

+

+	public static String XMLSearchPage_replace_searchproblems_message;

+

+	// FileTypeEditor

+	public static String FileTypeEditor_typeDelimiter;

+

+	// Preferences page

+	public static String XMLSearchPreferencePage_0;

+

+	public static String InstalledProcessorsBlock_0;

+	public static String InstalledProcessorsBlock_1;

+	public static String InstalledProcessorsBlock_2;

+	public static String InstalledProcessorsBlock_5;

+	public static String InstalledProcessorsBlock_6;

+	public static String InstalledProcessorsBlock_7;

+

+	public static String XPathProcessorPreferencePage_0;

+	public static String XPathProcessorPreferencePage_1;

+	public static String XPathProcessorPreferencePage_2;

+

+	static {

+		NLS.initializeMessages(XMLSearchUIPlugin.PLUGIN_ID

+				+ ".internal.Messages", Messages.class);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.properties b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.properties
new file mode 100644
index 0000000..80a567a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Messages.properties
@@ -0,0 +1,57 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+

+# Search query

+XMLSearchQuery_label=XML search

+XMLSearchQuery_status_ok_message=Found {0} matches.

+

+# Search error

+Search_Error_search_title=Search Error

+Search_Error_search_message=The search operation has reported problems

+Search_Error_search_notsuccessful_message=The search operation has reported problems

+Search_Error_search_notsuccessful_title=Search

+

+# Open file

+XMLSearchPage_open_file_dialog_title=Open File

+XMLSearchPage_open_file_failed=Opening the file failed.

+XMLSearchPage_error_marker=Could not create marker

+

+# The first argument will be replaced by the XPath query, the second by the count

+XMLSearchQuery_xpathPattern= ''{0}'' - {1} matches - done in {2} ms.

+

+#XML Search page

+SearchPage_xpath_text=XPath:

+SearchPage_xpath_hint=XPath

+SearchPage_xpath_errorRequired=XPath required

+SearchPage_XPathProcessor_text=XPath processor:

+SearchPage_xpathProcessor_errorRequired=XPath processor required

+SearchPage_browse= Ch&oose...

+SearchPage_fileNamePatterns_text= File name &patterns:

+SearchPage_fileNamePatterns_hint= Patterns are separated by a comma (* = any string, ? = any character)

+

+XMLSearchPage_replace_searchproblems_title=Replace

+XMLSearchPage_replace_searchproblems_message=Problems occurred while searching. The affected files will be skipped.

+

+# FileTypeEditor

+FileTypeEditor_typeDelimiter=,

+

+# Preferences page

+XMLSearchPreferencePage_0=XML search preferences.

+

+XPathProcessorPreferencePage_0=XPath Processors

+XPathProcessorPreferencePage_1=Add, remove or edit XPath processor definitions.\nBy default, the checked Processor is used for search in the XML editor (completion, hyperlink, validation...).

+XPathProcessorPreferencePage_2=Select a default XPath Processor

+InstalledProcessorsBlock_0=Installed XPath Processors:

+InstalledProcessorsBlock_1=Name

+InstalledProcessorsBlock_2=Source

+InstalledProcessorsBlock_5=Add

+InstalledProcessorsBlock_6=Edit

+InstalledProcessorsBlock_7=Remove

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Trace.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Trace.java
new file mode 100644
index 0000000..ca0ff0a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/Trace.java
@@ -0,0 +1,99 @@
+/*******************************************************************************

+ * Copyright (c) 2003, 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.search.ui.internal;

+

+import java.text.SimpleDateFormat;

+import java.util.Date;

+import java.util.HashSet;

+import java.util.Set;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+

+/**

+ * Helper class to route trace output.

+ */

+public class Trace {

+	public static final byte CONFIG = 0;

+	public static final byte INFO = 1;

+	public static final byte WARNING = 2;

+	public static final byte SEVERE = 3;

+	public static final byte FINEST = 4;

+	public static final byte FINER = 5;

+	public static final byte PERFORMANCE = 6;

+	public static final byte EXTENSION_POINT = 7;

+

+	private static final String[] levelNames = new String[] { "CONFIG ",

+			"INFO   ", "WARNING", "SEVERE ", "FINER  ", "FINEST ", "PERF   ",

+			"EXTENSION" };

+

+	private static final SimpleDateFormat sdf = new SimpleDateFormat(

+			"dd/MM/yy HH:mm.ss.SSS");

+

+	private static Set<String> logged = new HashSet<String>();

+

+	/**

+	 * Trace constructor comment.

+	 */

+	private Trace() {

+		super();

+	}

+

+	/**

+	 * Trace the given text.

+	 * 

+	 * @param level

+	 *            a trace level

+	 * @param s

+	 *            a message

+	 */

+	public static void trace(byte level, String s) {

+		trace(level, s, null);

+	}

+

+	/**

+	 * Trace the given message and exception.

+	 * 

+	 * @param level

+	 *            a trace level

+	 * @param s

+	 *            a message

+	 * @param t

+	 *            a throwable

+	 */

+	public static void trace(byte level, String s, Throwable t) {

+		if (s == null)

+			return;

+

+		if (level == SEVERE) {

+			if (!logged.contains(s)) {

+				XMLSearchUIPlugin.getDefault().getLog().log(

+						new Status(IStatus.ERROR,

+								XMLSearchUIPlugin.PLUGIN_ID, s, t));

+				logged.add(s);

+			}

+		}

+

+		if (!XMLSearchUIPlugin.getDefault().isDebugging())

+			return;

+

+		StringBuilder sb = new StringBuilder(XMLSearchUIPlugin.PLUGIN_ID);

+		sb.append(" ");

+		sb.append(levelNames[level]);

+		sb.append(" ");

+		sb.append(sdf.format(new Date()));

+		sb.append(" ");

+		sb.append(s);

+		System.out.println(sb.toString());

+		if (t != null)

+			t.printStackTrace();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchQuery.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchQuery.java
new file mode 100644
index 0000000..868167b
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchQuery.java
@@ -0,0 +1,143 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal;

+

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.OperationCanceledException;

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.osgi.util.NLS;

+import org.eclipse.search.ui.ISearchQuery;

+import org.eclipse.search.ui.ISearchResult;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.IXMLSearchDOMNodeCollector;

+import org.eclipse.wst.xml.search.core.IXMLSearchEngine;

+import org.eclipse.wst.xml.search.core.namespaces.Namespaces;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;

+import org.eclipse.wst.xml.search.ui.XMLMatch;

+

+/**

+ * {@link ISearchQuery} implementation for DOM-SSE.

+ * 

+ */

+public class XMLSearchQuery implements ISearchQuery, IXMLSearchDOMNodeCollector {

+

+	private IContainer container;

+	private IXMLSearchRequestor scope;

+	private IXMLSearchDOMDocumentVisitor visitor;

+	private String query;

+	private String xpathEvaluatorId;

+	private Namespaces namespaceInfos;

+	private ISearchResult fResult;

+	private IDOMNode selectedNode;

+	private IXMLSearchEngine engine;

+	private IXMLQuerySpecificationRegistry querySpecificationRegistry;

+	private long startTime = 0;

+	private long endTime = 0;

+	private IXMLSearchReporter reporter;

+

+	public XMLSearchQuery(IContainer container, IXMLSearchRequestor scope,

+			IXMLSearchDOMDocumentVisitor visitor, String query,

+			String xpathEvaluatorId, Namespaces namespaceInfos,

+			IDOMNode selectedNode, IXMLSearchEngine engine,

+			IXMLSearchReporter reporter) {

+		this.container = container;

+		this.scope = scope;

+		this.visitor = visitor;

+		this.query = query;

+		this.namespaceInfos = namespaceInfos;

+		this.xpathEvaluatorId = xpathEvaluatorId;

+		this.selectedNode = selectedNode;

+		this.engine = engine;

+		this.reporter = reporter;

+	}

+

+	public XMLSearchQuery(

+			IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			IXMLSearchEngine engine, IXMLSearchReporter reporter) {

+		this.engine = engine;

+		this.querySpecificationRegistry = querySpecificationRegistry;

+		this.reporter = reporter;

+	}

+

+	public boolean canRerun() {

+		return true;

+	}

+

+	public boolean canRunInBackground() {

+		return true;

+	}

+

+	public String getLabel() {

+		return Messages.XMLSearchQuery_label;

+	}

+

+	public ImageDescriptor getImageDescriptor() {

+		return null;

+	}

+

+	public String getResultLabel(int nMatches) {

+		long time = 0;

+		if (startTime > 0) {

+			if (endTime > 0) {

+				time = endTime - startTime;

+			} else {

+				time = System.currentTimeMillis() - startTime;

+			}

+		}

+		if (querySpecificationRegistry != null) {

+			String label = querySpecificationRegistry.getQueriesLabel();

+			Object[] values = { label, nMatches, time };

+			return NLS.bind(Messages.XMLSearchQuery_xpathPattern, values);

+		}

+		Object[] values = { query, nMatches, time };

+		return NLS.bind(Messages.XMLSearchQuery_xpathPattern, values);

+	}

+

+	public ISearchResult getSearchResult() {

+		if (fResult == null) {

+			XMLSearchResult result = new XMLSearchResult(this);

+			// TODO : manage SearchResultUpdater

+			// new SearchResultUpdater(result);

+			fResult = result;

+		}

+		return fResult;

+	}

+

+	public IStatus run(IProgressMonitor monitor)

+			throws OperationCanceledException {

+		startTime = System.currentTimeMillis();

+		XMLSearchResult xmlResult = (XMLSearchResult) getSearchResult();

+		xmlResult.removeAll();

+		if (querySpecificationRegistry != null) {

+			return engine.search(querySpecificationRegistry, this, reporter,

+					monitor);

+		}

+		try {

+			return engine.search(container, scope, visitor, query,

+					xpathEvaluatorId, namespaceInfos, this, selectedNode,

+					reporter, monitor);

+		} finally {

+			endTime = System.currentTimeMillis();

+		}

+	}

+

+	public boolean add(IDOMNode node) {

+		XMLSearchResult xmlResult = (XMLSearchResult) getSearchResult();

+		xmlResult.addMatch(new XMLMatch(node));

+		return true;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResult.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResult.java
new file mode 100644
index 0000000..1d08c61
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResult.java
@@ -0,0 +1,150 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.IAdaptable;

+import org.eclipse.jface.resource.ImageDescriptor;

+import org.eclipse.search.ui.ISearchQuery;

+import org.eclipse.search.ui.text.AbstractTextSearchResult;

+import org.eclipse.search.ui.text.IEditorMatchAdapter;

+import org.eclipse.search.ui.text.IFileMatchAdapter;

+import org.eclipse.search.ui.text.Match;

+import org.eclipse.ui.IEditorPart;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+

+/**

+ * {@link AbstractTextSearchResult} implementation for DOM-SSE.

+ * 

+ */

+public class XMLSearchResult extends AbstractTextSearchResult implements

+		IEditorMatchAdapter, IFileMatchAdapter {

+

+	protected static final Match[] NO_MATCHES = new Match[0];

+

+	private XMLSearchQuery fQuery;

+

+	public XMLSearchResult(XMLSearchQuery query) {

+		fQuery = query;

+	}

+

+	@Override

+	public IEditorMatchAdapter getEditorMatchAdapter() {

+		return this;

+	}

+

+	@Override

+	public IFileMatchAdapter getFileMatchAdapter() {

+		return this;

+	}

+

+	public ImageDescriptor getImageDescriptor() {

+		return fQuery.getImageDescriptor();

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.search.ui.ISearchResult#getLabel()

+	 */

+	public String getLabel() {

+		return fQuery.getResultLabel(getMatchCount());

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.search.ui.ISearchResult#getTooltip()

+	 */

+	public String getTooltip() {

+		return getLabel();

+	}

+

+	public ISearchQuery getQuery() {

+		return fQuery;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.search.ui.text.IEditorMatchAdapter#computeContainedMatches

+	 * (org.eclipse.search.ui.text.AbstractTextSearchResult,

+	 * org.eclipse.ui.IEditorPart)

+	 */

+	public Match[] computeContainedMatches(AbstractTextSearchResult result,

+			IEditorPart editor) {

+		// IStructuredModel editor.getAdapter(IStructuredModel.class);

+		return computeContainedMatches(editor.getEditorInput());

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.search.ui.text.IEditorMatchAdapter#computeContainedMatches

+	 * (org.eclipse.search.ui.text.AbstractTextSearchResult,

+	 * org.eclipse.ui.IEditorPart)

+	 */

+	public Match[] computeContainedMatches(AbstractTextSearchResult result,

+			IFile file) {

+		return computeContainedMatches(file);

+	}

+

+	private Match[] computeContainedMatches(IAdaptable adaptable) {

+		// IJavaElement javaElement= (IJavaElement)

+		// adaptable.getAdapter(IJavaElement.class);

+		// Set matches= new HashSet();

+		// if (javaElement != null) {

+		// collectMatches(matches, javaElement);

+		// }

+		// IFile file= (IFile) adaptable.getAdapter(IFile.class);

+		// if (file != null) {

+		// collectMatches(matches, file);

+		// }

+		// if (!matches.isEmpty()) {

+		// return (Match[]) matches.toArray(new Match[matches.size()]);

+		// }

+		// adaptable.getAdapter(IStructuredDocument.class)

+		return NO_MATCHES;

+	}

+

+	public boolean isShownInEditor(Match match, IEditorPart editor) {

+		Object element = match.getElement();

+		if (element instanceof IDOMNode) {

+			// DOMNode matched

+			IDOMNode node = (IDOMNode) element;

+			IStructuredModel editorModel = (IStructuredModel) editor

+					.getAdapter(IStructuredModel.class);

+			if (editorModel != null) {

+				// Returns true if found node belong to the current XML editor

+				// which

+				// has launched the search and false otherwise.

+				return editorModel.equals(node.getModel());

+			}

+		}

+		return false;

+	}

+

+	public IFile getFile(Object element) {

+		if (element instanceof IFile)

+			return (IFile) element;

+		if (element instanceof IDOMNode) {

+			// Returns owner file of the node

+			IDOMNode node = (IDOMNode) element;

+			return DOMUtils.getFile(node);

+		}

+		return null;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResultPage.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResultPage.java
new file mode 100644
index 0000000..47ff2e8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchResultPage.java
@@ -0,0 +1,145 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal;

+

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jface.viewers.ILabelProvider;

+import org.eclipse.jface.viewers.IStructuredSelection;

+import org.eclipse.jface.viewers.OpenEvent;

+import org.eclipse.jface.viewers.StructuredViewer;

+import org.eclipse.jface.viewers.TableViewer;

+import org.eclipse.jface.viewers.TreeViewer;

+import org.eclipse.jface.viewers.Viewer;

+import org.eclipse.jface.viewers.ViewerComparator;

+import org.eclipse.search.ui.text.AbstractTextSearchViewPage;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.ui.DecoratingXMLSearchLabelProvider;

+import org.eclipse.wst.xml.search.ui.XMLLabelProvider;

+import org.eclipse.wst.xml.search.ui.util.EditorOpener;

+

+/**

+ * {@link AbstractTextSearchViewPage} implementation for DOM-SSE.

+ */

+public class XMLSearchResultPage extends AbstractTextSearchViewPage {

+

+	private static final int DEFAULT_ELEMENT_LIMIT = 1000;

+

+	private IXMLSearchContentProvider fContentProvider;

+

+	private EditorOpener fEditorOpener = new EditorOpener();

+

+	public XMLSearchResultPage() {

+		super.setElementLimit(new Integer(DEFAULT_ELEMENT_LIMIT));

+	}

+

+	public static class DecoratorIgnoringViewerSorter extends ViewerComparator {

+		private final ILabelProvider fLabelProvider;

+

+		public DecoratorIgnoringViewerSorter(ILabelProvider labelProvider) {

+			fLabelProvider = labelProvider;

+		}

+

+		public int category(Object element) {

+			if (element instanceof IDOMNode || element instanceof IResource)

+				return 1;

+			return 2;

+		}

+

+		public int compare(Viewer viewer, Object e1, Object e2) {

+			int cat1 = category(e1);

+			int cat2 = category(e2);

+

+			if (cat1 != cat2) {

+				return cat1 - cat2;

+			}

+			String name1 = fLabelProvider.getText(e1);

+			String name2 = fLabelProvider.getText(e2);

+			if (name1 == null)

+				name1 = "";//$NON-NLS-1$

+			if (name2 == null)

+				name2 = "";//$NON-NLS-1$

+			return getComparator().compare(name1, name2);

+		}

+	}

+

+	@Override

+	protected void configureTableViewer(TableViewer viewer) {

+		viewer.setUseHashlookup(true);

+		XMLLabelProvider innerLabelProvider = new XMLLabelProvider();

+		viewer.setLabelProvider(new DecoratingXMLSearchLabelProvider(

+				innerLabelProvider));

+		viewer.setContentProvider(new XMLSearchTableContentProvider(this));

+		viewer.setComparator(new DecoratorIgnoringViewerSorter(

+				innerLabelProvider));

+		fContentProvider = (XMLSearchTableContentProvider) viewer

+				.getContentProvider();

+	}

+

+	@Override

+	protected void configureTreeViewer(TreeViewer viewer) {

+		viewer.setUseHashlookup(true);

+		XMLLabelProvider innerLabelProvider = new XMLLabelProvider();

+		viewer.setLabelProvider(new DecoratingXMLSearchLabelProvider(

+				innerLabelProvider));

+		viewer.setContentProvider(new XMLSearchTreeContentProvider(this, viewer));

+		viewer.setComparator(new DecoratorIgnoringViewerSorter(

+				innerLabelProvider));

+		fContentProvider = (IXMLSearchContentProvider) viewer

+				.getContentProvider();

+		addDragAdapters(viewer);

+	}

+

+	@Override

+	protected void elementsChanged(Object[] objects) {

+		if (fContentProvider != null)

+			fContentProvider.elementsChanged(objects);

+	}

+

+	@Override

+	protected void clear() {

+		if (fContentProvider != null)

+			fContentProvider.clear();

+	}

+

+	private void addDragAdapters(StructuredViewer viewer) {

+		// Transfer[] transfers = new Transfer[] {

+		// ResourceTransfer.getInstance() };

+		// int ops = DND.DROP_COPY | DND.DROP_LINK;

+		// viewer.addDragSupport(ops, transfers, new

+		// NavigatorDragAdapter(viewer));

+	}

+

+	public StructuredViewer getViewer() {

+		return super.getViewer();

+	}

+

+	@Override

+	protected void handleOpen(OpenEvent event) {

+		Object firstElement = ((IStructuredSelection) event.getSelection())

+				.getFirstElement();

+		if (firstElement instanceof IDOMNode) {

+			if (getDisplayedMatchCount(firstElement) == 0) {

+				// Search result item clicked is DOM node, open the XML editor

+				// and select the node as soon as the XML editor is opened.

+				IDOMNode node = (IDOMNode) firstElement;

+				EditorOpener.openDOMNode(getSite().getPage(), node,

+						fEditorOpener, getSite().getShell());

+				return;

+			}

+		}

+		super.handleOpen(event);

+	}

+

+	@Override

+	public int getDisplayedMatchCount(Object element) {

+		return 0;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTableContentProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTableContentProvider.java
new file mode 100644
index 0000000..279ac6c
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTableContentProvider.java
@@ -0,0 +1,86 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2008 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

+ *     Angelo Zerr <angelo.zerr@gmail.com> - adapt it for XML Search.

+ *     

+ *     Code comes from org.eclipse.search.internal.ui.text.FileTableContentProvider

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal;

+

+import org.eclipse.jface.viewers.IStructuredContentProvider;

+import org.eclipse.jface.viewers.TableViewer;

+import org.eclipse.jface.viewers.Viewer;

+import org.eclipse.search.ui.text.AbstractTextSearchResult;

+

+public class XMLSearchTableContentProvider implements

+		IStructuredContentProvider, IXMLSearchContentProvider {

+

+	private final Object[] EMPTY_ARR = new Object[0];

+

+	private XMLSearchResultPage fPage;

+	private AbstractTextSearchResult fResult;

+

+	public XMLSearchTableContentProvider(XMLSearchResultPage page) {

+		fPage = page;

+	}

+

+	public void dispose() {

+		// nothing to do

+	}

+

+	public Object[] getElements(Object inputElement) {

+		if (inputElement instanceof XMLSearchResult) {

+			int elementLimit = getElementLimit();

+			Object[] elements = ((XMLSearchResult) inputElement).getElements();

+			if (elementLimit != -1 && elements.length > elementLimit) {

+				Object[] shownElements = new Object[elementLimit];

+				System.arraycopy(elements, 0, shownElements, 0, elementLimit);

+				return shownElements;

+			}

+			return elements;

+		}

+		return EMPTY_ARR;

+	}

+

+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

+		if (newInput instanceof XMLSearchResult) {

+			fResult = (XMLSearchResult) newInput;

+		}

+	}

+

+	public void elementsChanged(Object[] updatedElements) {

+		TableViewer viewer = getViewer();

+		int elementLimit = getElementLimit();

+		boolean tableLimited = elementLimit != -1;

+		for (int i = 0; i < updatedElements.length; i++) {

+			if (fResult.getMatchCount(updatedElements[i]) > 0) {

+				if (viewer.testFindItem(updatedElements[i]) != null)

+					viewer.update(updatedElements[i], null);

+				else {

+					if (!tableLimited

+							|| viewer.getTable().getItemCount() < elementLimit)

+						viewer.add(updatedElements[i]);

+				}

+			} else

+				viewer.remove(updatedElements[i]);

+		}

+	}

+

+	private int getElementLimit() {

+		return fPage.getElementLimit().intValue();

+	}

+

+	private TableViewer getViewer() {

+		return (TableViewer) fPage.getViewer();

+	}

+

+	public void clear() {

+		getViewer().refresh();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTreeContentProvider.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTreeContentProvider.java
new file mode 100644
index 0000000..765dbac
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchTreeContentProvider.java
@@ -0,0 +1,241 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2008 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

+ *     Juerg Billeter, juergbi@ethz.ch - 47136 Search view should show match objects

+ *     Ulrich Etter, etteru@ethz.ch - 47136 Search view should show match objects

+ *     Roman Fuchs, fuchsro@ethz.ch - 47136 Search view should show match objects

+ *     Angelo Zerr <angelo.zerr@gmail.com> - adapt it for XML Search.

+ *     

+ *     Code comes from org.eclipse.search.internal.ui.text.FileTreeContentProvider

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal;

+

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.Map;

+import java.util.Set;

+

+import org.eclipse.core.resources.IProject;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.jface.viewers.AbstractTreeViewer;

+import org.eclipse.jface.viewers.ITreeContentProvider;

+import org.eclipse.jface.viewers.Viewer;

+import org.eclipse.search.ui.text.AbstractTextSearchResult;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+

+public class XMLSearchTreeContentProvider implements ITreeContentProvider,

+		IXMLSearchContentProvider {

+

+	private final Object[] EMPTY_ARR = new Object[0];

+

+	private AbstractTextSearchResult fResult;

+	private XMLSearchResultPage fPage;

+	private AbstractTreeViewer fTreeViewer;

+	private Map fChildrenMap;

+

+	public XMLSearchTreeContentProvider(XMLSearchResultPage page,

+			AbstractTreeViewer viewer) {

+		fPage = page;

+		fTreeViewer = viewer;

+	}

+

+	public Object[] getElements(Object inputElement) {

+		Object[] children = getChildren(inputElement);

+		int elementLimit = getElementLimit();

+		if (elementLimit != -1 && elementLimit < children.length) {

+			Object[] limitedChildren = new Object[elementLimit];

+			System.arraycopy(children, 0, limitedChildren, 0, elementLimit);

+			return limitedChildren;

+		}

+		return children;

+	}

+

+	private int getElementLimit() {

+		return fPage.getElementLimit().intValue();

+	}

+

+	public void dispose() {

+		// nothing to do

+	}

+

+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

+		if (newInput instanceof XMLSearchResult) {

+			initialize((XMLSearchResult) newInput);

+		}

+	}

+

+	private synchronized void initialize(AbstractTextSearchResult result) {

+		fResult = result;

+		fChildrenMap = new HashMap();

+		// boolean showLineMatches= !((SIDocSearchQuery)

+		// fResult.getQuery()).isFileNameSearch();

+

+		if (result != null) {

+			Object[] elements = result.getElements();

+			for (int i = 0; i < elements.length; i++) {

+				// if (showLineMatches) {

+				// Match[] matches= result.getMatches(elements[i]);

+				// for (int j= 0; j < matches.length; j++) {

+				// insert(((XMLMatch) matches[j]).getLineElement(), false);

+				// }

+				// } else {

+				insert(elements[i], false);

+				// }

+			}

+		}

+	}

+

+	private void insert(Object child, boolean refreshViewer) {

+		Object parent = getParent(child);

+		while (parent != null) {

+			if (insertChild(parent, child)) {

+				if (refreshViewer)

+					fTreeViewer.add(parent, child);

+			} else {

+				if (refreshViewer)

+					fTreeViewer.refresh(parent);

+				return;

+			}

+			child = parent;

+			parent = getParent(child);

+		}

+		if (insertChild(fResult, child)) {

+			if (refreshViewer)

+				fTreeViewer.add(fResult, child);

+		}

+	}

+

+	/**

+	 * Adds the child to the parent.

+	 * 

+	 * @param parent

+	 *            the parent

+	 * @param child

+	 *            the child

+	 * @return <code>true</code> if this set did not already contain the

+	 *         specified element

+	 */

+	private boolean insertChild(Object parent, Object child) {

+		Set children = (Set) fChildrenMap.get(parent);

+		if (children == null) {

+			children = new HashSet();

+			fChildrenMap.put(parent, children);

+		}

+		return children.add(child);

+	}

+

+	private boolean hasChild(Object parent, Object child) {

+		Set children = (Set) fChildrenMap.get(parent);

+		return children != null && children.contains(child);

+	}

+

+	private void remove(Object element, boolean refreshViewer) {

+		// precondition here: fResult.getMatchCount(child) <= 0

+

+		if (hasChildren(element)) {

+			if (refreshViewer)

+				fTreeViewer.refresh(element);

+		} else {

+			if (!hasMatches(element)) {

+				fChildrenMap.remove(element);

+				Object parent = getParent(element);

+				if (parent != null) {

+					removeFromSiblings(element, parent);

+					remove(parent, refreshViewer);

+				} else {

+					removeFromSiblings(element, fResult);

+					if (refreshViewer)

+						fTreeViewer.refresh();

+				}

+			} else {

+				if (refreshViewer) {

+					fTreeViewer.refresh(element);

+				}

+			}

+		}

+	}

+

+	private boolean hasMatches(Object element) {

+		// if (element instanceof LineElement) {

+		// LineElement lineElement= (LineElement) element;

+		// return lineElement.getNumberOfMatches(fResult) > 0;

+		// }

+		return fResult.getMatchCount(element) > 0;

+	}

+

+	private void removeFromSiblings(Object element, Object parent) {

+		Set siblings = (Set) fChildrenMap.get(parent);

+		if (siblings != null) {

+			siblings.remove(element);

+		}

+	}

+

+	public Object[] getChildren(Object parentElement) {

+		Set children = (Set) fChildrenMap.get(parentElement);

+		if (children == null)

+			return EMPTY_ARR;

+		return children.toArray();

+	}

+

+	public boolean hasChildren(Object element) {

+		return getChildren(element).length > 0;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.search.internal.ui.text.IFileSearchContentProvider#

+	 * elementsChanged(java.lang.Object[])

+	 */

+	public synchronized void elementsChanged(Object[] updatedElements) {

+		for (int i = 0; i < updatedElements.length; i++) {

+			// if (!(updatedElements[i] instanceof LineElement)) {

+			// change events to elements are reported in file search

+			if (fResult.getMatchCount(updatedElements[i]) > 0)

+				insert(updatedElements[i], true);

+			else

+				remove(updatedElements[i], true);

+			// } else {

+			// // change events to line elements are reported in text search

+			// LineElement lineElement= (LineElement) updatedElements[i];

+			// int nMatches= lineElement.getNumberOfMatches(fResult);

+			// if (nMatches > 0) {

+			// if (hasChild(lineElement.getParent(), lineElement)) {

+			// fTreeViewer.update(new Object[] { lineElement,

+			// lineElement.getParent() }, null);

+			// } else {

+			// insert(lineElement, true);

+			// }

+			// } else {

+			// remove(lineElement, true);

+			// }

+			// }

+		}

+	}

+

+	public void clear() {

+		initialize(fResult);

+		fTreeViewer.refresh();

+	}

+

+	public Object getParent(Object element) {

+		if (element instanceof IProject)

+			return null;

+		if (element instanceof IResource) {

+			IResource resource = (IResource) element;

+			return resource.getParent();

+		}

+		if (element instanceof IDOMNode) {

+			return DOMUtils.getFile((IDOMNode) element);

+		}

+		return null;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchUIPlugin.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchUIPlugin.java
new file mode 100644
index 0000000..87058a8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/XMLSearchUIPlugin.java
@@ -0,0 +1,107 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.jface.dialogs.IDialogSettings;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.IWorkbenchPage;

+import org.eclipse.ui.IWorkbenchWindow;

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class XMLSearchUIPlugin extends AbstractUIPlugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.ui";

+

+	// The shared instance

+	private static XMLSearchUIPlugin plugin;

+

+	/**

+	 * The constructor

+	 */

+	public XMLSearchUIPlugin() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void stop(BundleContext context) throws Exception {

+		plugin = null;

+		super.stop(context);

+	}

+

+	/**

+	 * Returns the shared instance

+	 * 

+	 * @return the shared instance

+	 */

+	public static XMLSearchUIPlugin getDefault() {

+		return plugin;

+	}

+

+	public static IStatus createStatus(int severity, String message) {

+		return new Status(severity, XMLSearchUIPlugin.PLUGIN_ID, message);

+	}

+

+	public static IStatus createStatus(int severity, String message, Throwable e) {

+		return new Status(severity, XMLSearchUIPlugin.PLUGIN_ID, message, e);

+	}

+

+	public static IWorkbenchWindow getActiveWorkbenchWindow() {

+		return getDefault().getWorkbench().getActiveWorkbenchWindow();

+	}

+

+	public static Shell getActiveWorkbenchShell() {

+		IWorkbenchWindow window = getActiveWorkbenchWindow();

+		if (window != null) {

+			return window.getShell();

+		}

+		return null;

+	}

+

+	/**

+	 * @return Returns the active workbench window's currrent page.

+	 */

+	public static IWorkbenchPage getActivePage() {

+		return getActiveWorkbenchWindow().getActivePage();

+	}

+

+	public IDialogSettings getDialogSettingsSection(String name) {

+		IDialogSettings dialogSettings = getDialogSettings();

+		IDialogSettings section = dialogSettings.getSection(name);

+		if (section == null) {

+			section = dialogSettings.addNewSection(name);

+		}

+		return section;

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/IXMLHelpContextIds.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/IXMLHelpContextIds.java
new file mode 100644
index 0000000..485708d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/IXMLHelpContextIds.java
@@ -0,0 +1,25 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal.dialog;

+

+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;

+

+/**

+ * Constants for XML Search Help.

+ * 

+ */

+public interface IXMLHelpContextIds {

+

+	public static final String PREFIX = XMLSearchUIPlugin.PLUGIN_ID + '.';

+

+	public static final String XML_SEARCH_PAGE = PREFIX

+			+ "xml_search_page_context"; //$NON-NLS-1$

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/OpenXMLSearchPageAction.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/OpenXMLSearchPageAction.java
new file mode 100644
index 0000000..22984a7
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/OpenXMLSearchPageAction.java
@@ -0,0 +1,66 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2011 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

+ *     Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search.   

+ *     Code comes from org.eclipse.jdt.internal.ui.search.OpenJavaSearchPageAction

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal.dialog;

+

+import org.eclipse.jface.action.IAction;

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.search.ui.NewSearchUI;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.IWorkbenchWindow;

+import org.eclipse.ui.IWorkbenchWindowActionDelegate;

+import org.eclipse.wst.xml.search.ui.internal.Trace;

+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;

+

+/**

+ * Opens the XML Search Dialog and brings the XML search page to front

+ */

+public class OpenXMLSearchPageAction implements IWorkbenchWindowActionDelegate {

+

+	private static final String XML_SEARCH_PAGE_ID = "org.eclipse.wst.xml.search.ui.dialog.XMLSearchPage"; //$NON-NLS-1$

+

+	private IWorkbenchWindow fWindow;

+

+	public OpenXMLSearchPageAction() {

+	}

+

+	public void init(IWorkbenchWindow window) {

+		fWindow = window;

+	}

+

+	public void run(IAction action) {

+		if (fWindow == null || fWindow.getActivePage() == null) {

+			beep();

+			logErrorMessage("Could not open the search dialog - for some reason the window handle was null"); //$NON-NLS-1$

+			return;

+		}

+		NewSearchUI.openSearchDialog(fWindow, XML_SEARCH_PAGE_ID);

+	}

+

+	public void selectionChanged(IAction action, ISelection selection) {

+		// do nothing since the action isn't selection dependent.

+	}

+

+	public void dispose() {

+		fWindow = null;

+	}

+

+	public static void logErrorMessage(String message) {

+		Trace.trace(Trace.SEVERE, message);

+	}

+

+	protected void beep() {

+		Shell shell = XMLSearchUIPlugin.getActiveWorkbenchShell();

+		if (shell != null && shell.getDisplay() != null)

+			shell.getDisplay().beep();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/XMLSearchPage.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/XMLSearchPage.java
new file mode 100644
index 0000000..41e5b29
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/dialog/XMLSearchPage.java
@@ -0,0 +1,756 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal.dialog;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.List;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.ResourcesPlugin;

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.jface.dialogs.Dialog;

+import org.eclipse.jface.dialogs.DialogPage;

+import org.eclipse.jface.dialogs.ErrorDialog;

+import org.eclipse.jface.dialogs.IDialogSettings;

+import org.eclipse.jface.resource.JFaceColors;

+import org.eclipse.jface.text.ITextSelection;

+import org.eclipse.jface.viewers.ComboViewer;

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.jface.viewers.IStructuredContentProvider;

+import org.eclipse.jface.viewers.IStructuredSelection;

+import org.eclipse.jface.viewers.LabelProvider;

+import org.eclipse.jface.viewers.StructuredSelection;

+import org.eclipse.jface.viewers.Viewer;

+import org.eclipse.search.ui.ISearchPage;

+import org.eclipse.search.ui.ISearchPageContainer;

+import org.eclipse.search.ui.ISearchQuery;

+import org.eclipse.search.ui.NewSearchUI;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.custom.CLabel;

+import org.eclipse.swt.events.ModifyEvent;

+import org.eclipse.swt.events.ModifyListener;

+import org.eclipse.swt.events.SelectionAdapter;

+import org.eclipse.swt.events.SelectionEvent;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.widgets.Button;

+import org.eclipse.swt.widgets.Combo;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Label;

+import org.eclipse.ui.IEditorPart;

+import org.eclipse.ui.IFileEditorInput;

+import org.eclipse.ui.IWorkingSet;

+import org.eclipse.ui.IWorkingSetManager;

+import org.eclipse.ui.PlatformUI;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.XMLSearchEngine2;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AbstractXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.AllFilesXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.requestor.IXMLSearchRequestor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.IXMLSearchDOMDocumentVisitor;

+import org.eclipse.wst.xml.search.core.queryspecifications.visitor.XPathNodeSetSearchVisitor;

+import org.eclipse.wst.xml.search.core.util.StringUtils;

+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.eclipse.wst.xml.search.core.xpath.DefaultXPathProcessor;

+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;

+import org.eclipse.wst.xml.search.ui.internal.Messages;

+import org.eclipse.wst.xml.search.ui.internal.XMLSearchQuery;

+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;

+import org.eclipse.wst.xml.search.ui.internal.util.FileTypeEditor;

+import org.eclipse.wst.xml.search.ui.internal.util.SWTUtil;

+import org.eclipse.wst.xml.search.ui.util.DOMUtils;

+import org.eclipse.wst.xml.search.ui.util.SearchUtil;

+

+/**

+ * {@link ISearchPage} implementation for DOM-SSE.

+ * 

+ */

+public class XMLSearchPage extends DialogPage implements ISearchPage {

+

+	private static final String DEFAULT_XML_EXT = "*.xml";

+	private static final int HISTORY_SIZE = 12;

+

+	private ISearchPageContainer container;

+	private boolean fFirstTime = true;

+	private Combo xpathCombo;

+	private CLabel fStatusLabel;

+	private Combo fExtensions;

+	private ComboViewer xpathProcessorViewer;

+	private FileTypeEditor fFileTypeEditor;

+

+	private NamespaceInfos namespaceInfos = null;

+

+	// Dialog store id constants

+	private static final String PAGE_NAME = "XMLSearchPage"; //$NON-NLS-1$

+	private static final String STORE_HISTORY = "HISTORY"; //$NON-NLS-1$

+	private static final String STORE_HISTORY_SIZE = "HISTORY_SIZE"; //$NON-NLS-1$

+

+	private List<SearchPatternData> fPreviousSearchPatterns = new ArrayList<SearchPatternData>(

+			20);

+

+	private static class SearchPatternData {

+

+		private static final String XPATH_SETTINGS_ID = "xpath";

+		private static final String XPATH_EVALUATOR_SETTINGS_ID = "xpathProcessor";

+		private static final String FILE_NAME_PATTERNS_SETTINGS_ID = "fileNamePatterns";

+		private static final String SCOPE_SETTINGS_ID = "scope";

+		private static final String WORKING_SETS_SETTINGS_ID = "workingSets";

+

+		public final String xpath;

+		public final String xpathProcessorId;

+		public final String[] fileNamePatterns;

+		public final int scope;

+		public final IWorkingSet[] workingSets;

+

+		public SearchPatternData(String xpath, String xpathProcessorId,

+				String[] fileNamePatterns, int scope, IWorkingSet[] workingSets) {

+			Assert.isNotNull(fileNamePatterns);

+			this.xpath = xpath;

+			this.xpathProcessorId = xpathProcessorId;

+			this.fileNamePatterns = fileNamePatterns;

+			this.scope = scope;

+			this.workingSets = workingSets; // can be null

+		}

+

+		public void store(IDialogSettings settings) {

+			settings.put(XPATH_SETTINGS_ID, xpath); //$NON-NLS-1$

+			settings.put(XPATH_EVALUATOR_SETTINGS_ID, xpathProcessorId); //$NON-NLS-1$

+			settings.put(FILE_NAME_PATTERNS_SETTINGS_ID, fileNamePatterns); //$NON-NLS-1$

+			settings.put(SCOPE_SETTINGS_ID, scope); //$NON-NLS-1$

+			if (workingSets != null) {

+				String[] wsIds = new String[workingSets.length];

+				for (int i = 0; i < workingSets.length; i++) {

+					wsIds[i] = workingSets[i].getLabel();

+				}

+				settings.put(WORKING_SETS_SETTINGS_ID, wsIds); //$NON-NLS-1$

+			} else {

+				settings.put(WORKING_SETS_SETTINGS_ID, new String[0]); //$NON-NLS-1$

+			}

+

+		}

+

+		public static SearchPatternData create(IDialogSettings settings) {

+			String xpath = settings.get(XPATH_SETTINGS_ID); //$NON-NLS-1$

+			String xpathProcessorId = settings.get(XPATH_EVALUATOR_SETTINGS_ID); //$NON-NLS-1$

+			String[] wsIds = settings.getArray(WORKING_SETS_SETTINGS_ID); //$NON-NLS-1$

+			IWorkingSet[] workingSets = null;

+			if (wsIds != null && wsIds.length > 0) {

+				IWorkingSetManager workingSetManager = PlatformUI

+						.getWorkbench().getWorkingSetManager();

+				workingSets = new IWorkingSet[wsIds.length];

+				for (int i = 0; workingSets != null && i < wsIds.length; i++) {

+					workingSets[i] = workingSetManager.getWorkingSet(wsIds[i]);

+					if (workingSets[i] == null) {

+						workingSets = null;

+					}

+				}

+			}

+			String[] fileNamePatterns = settings

+					.getArray(FILE_NAME_PATTERNS_SETTINGS_ID); //$NON-NLS-1$

+			if (fileNamePatterns == null) {

+				fileNamePatterns = StringUtils.EMPTY_ARRAY;

+			}

+			try {

+				int scope = settings.getInt(SCOPE_SETTINGS_ID); //$NON-NLS-1$

+

+				return new SearchPatternData(xpath, xpathProcessorId,

+						fileNamePatterns, scope, workingSets);

+			} catch (NumberFormatException e) {

+				return null;

+			}

+		}

+

+	}

+

+	private static class XPathProcessorLabelProvider extends LabelProvider {

+		/*

+		 * @see

+		 * org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)

+		 */

+		public Image getImage(Object element) {

+			return null;

+		}

+

+		/*

+		 * @see

+		 * org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)

+		 */

+		public String getText(Object element) {

+			return ((IXPathProcessorType) element).getName();

+		}

+

+	}

+

+	private static class XPathProcessorContentProvider implements

+			IStructuredContentProvider {

+

+		/*

+		 * @see org.eclipse.jface.viewers.IContentProvider#dispose()

+		 */

+		public void dispose() {

+		}

+

+		/*

+		 * @see

+		 * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse

+		 * .jface.viewers.Viewer, java.lang.Object, java.lang.Object)

+		 */

+		public void inputChanged(Viewer v, Object oldInput, Object newInput) {

+		}

+

+		/*

+		 * @see

+		 * org.eclipse.jface.viewers.IStructuredContentProvider#getElements(

+		 * java.lang.Object)

+		 */

+		public Object[] getElements(Object inputElement) {

+			return XPathProcessorManager.getDefault().getProcessors();

+		}

+	}

+

+	public XMLSearchPage() {

+

+	}

+

+	// ---- Action Handling ------------------------------------------------

+

+	public boolean performAction() {

+		try {

+			NewSearchUI.runQueryInBackground(newQuery());

+		} catch (CoreException e) {

+			ErrorDialog.openError(getShell(),

+					Messages.XMLSearchPage_replace_searchproblems_title,

+					Messages.XMLSearchPage_replace_searchproblems_message,

+					e.getStatus());

+			return false;

+		}

+		return true;

+	}

+

+	private ISearchQuery newQuery() throws CoreException {

+		SearchPatternData data = getPatternData();

+		String xpath = data.xpath;

+		IXMLSearchDOMDocumentVisitor visitor = XPathNodeSetSearchVisitor.INSTANCE;

+

+		final Collection<String> extensions = new ArrayList<String>();

+		final boolean acceptAllFiles = getExtensions(extensions);

+		IXMLSearchRequestor requestor = null;

+		if (acceptAllFiles) {

+			requestor = AllFilesXMLSearchRequestor.INSTANCE;

+		} else {

+			requestor = new AbstractXMLSearchRequestor() {

+				protected boolean accept(IFile file, IResource rootResource) {

+					boolean accept = false;

+					for (String extension : extensions) {

+						accept = extension.equals(file.getFileExtension());

+						if (accept)

+							return true;

+					}

+					return false;

+				};

+			};

+		}

+

+		return new XMLSearchQuery(ResourcesPlugin.getWorkspace().getRoot(),

+				requestor, visitor, xpath, getXPathProcessorId(),

+				null, null, new XMLSearchEngine2(), null);

+	}

+

+	public void createControl(Composite parent) {

+		initializeDialogUnits(parent);

+		readConfiguration();

+

+		Composite result = new Composite(parent, SWT.NONE);

+

+		GridLayout layout = new GridLayout(2, false);

+		layout.horizontalSpacing = 10;

+		result.setLayout(layout);

+

+		addXPathControls(result);

+		addXPathProcessorControls(result);

+

+		Label separator = new Label(result, SWT.NONE);

+		separator.setVisible(false);

+		GridData data = new GridData(GridData.FILL, GridData.FILL, false,

+				false, 2, 1);

+		data.heightHint = convertHeightInCharsToPixels(1) / 3;

+		separator.setLayoutData(data);

+

+		addFileNameControls(result);

+

+		setControl(result);

+

+		Dialog.applyDialogFont(result);

+		PlatformUI.getWorkbench().getHelpSystem()

+				.setHelp(result, IXMLHelpContextIds.XML_SEARCH_PAGE);

+

+	}

+

+	/*

+	 * Implements method from IDialogPage

+	 */

+	public void setVisible(boolean visible) {

+		if (visible && xpathCombo != null) {

+			if (fFirstTime) {

+				fFirstTime = false;

+				// Set item and text here to prevent page from resizing

+				xpathCombo.setItems(getPreviousSearchPatterns());

+				xpathProcessorViewer.setInput(XPathProcessorManager

+						.getDefault().getProcessors());

+				fExtensions.setItems(getPreviousExtensions());

+				if (!initializeXPathControl()) {

+					xpathCombo.select(0);

+					fExtensions.setText(DEFAULT_XML_EXT); //$NON-NLS-1$

+					handleWidgetSelected();

+				}

+			}

+			xpathCombo.setFocus();

+			if (xpathProcessorViewer.getSelection().isEmpty()) {

+				selectXPathProcessor(DefaultXPathProcessor.ID);

+			}

+		}

+		updateOKStatus();

+		super.setVisible(visible);

+	}

+

+	private void addXPathControls(Composite group) {

+		// grid layout with 2 columns

+

+		// Info text

+		Label label = new Label(group, SWT.LEAD);

+		label.setText(Messages.SearchPage_xpath_text);

+		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2,

+				1));

+		label.setFont(group.getFont());

+

+		// XPath combo

+		xpathCombo = new Combo(group, SWT.SINGLE | SWT.BORDER);

+		// Not done here to prevent page from resizing

+		xpathCombo.addSelectionListener(new SelectionAdapter() {

+			public void widgetSelected(SelectionEvent e) {

+				handleWidgetSelected();

+				updateOKStatus();

+			}

+		});

+		// add some listeners for XPath syntax checking

+		xpathCombo.addModifyListener(new ModifyListener() {

+			public void modifyText(ModifyEvent e) {

+				updateOKStatus();

+			}

+		});

+		xpathCombo.setFont(group.getFont());

+		GridData data = new GridData(GridData.FILL, GridData.FILL, true, false,

+				1, 1);

+		data.widthHint = convertWidthInCharsToPixels(50);

+		xpathCombo.setLayoutData(data);

+

+		// Text line which explains the special characters

+		fStatusLabel = new CLabel(group, SWT.LEAD);

+		fStatusLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,

+				false, 1, 1));

+		fStatusLabel.setFont(group.getFont());

+		fStatusLabel.setAlignment(SWT.LEFT);

+		fStatusLabel.setText(Messages.SearchPage_xpath_hint);

+	}

+

+	private void addXPathProcessorControls(Composite group) {

+		// Info text

+		Label label = new Label(group, SWT.LEAD);

+		label.setText(Messages.SearchPage_XPathProcessor_text);

+		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2,

+				1));

+		label.setFont(group.getFont());

+

+		// XPathProcessor combo

+		xpathProcessorViewer = new ComboViewer(group, SWT.SINGLE | SWT.BORDER

+				| SWT.READ_ONLY);

+		xpathProcessorViewer

+				.setLabelProvider(new XPathProcessorLabelProvider());

+		xpathProcessorViewer

+				.setContentProvider(new XPathProcessorContentProvider());

+		// Not done here to prevent page from resizing

+		xpathProcessorViewer.getCombo().addSelectionListener(

+				new SelectionAdapter() {

+					public void widgetSelected(SelectionEvent e) {

+						// handleWidgetSelected();

+						updateOKStatus();

+					}

+				});

+

+		xpathProcessorViewer.getCombo().setFont(group.getFont());

+		GridData data = new GridData(GridData.FILL, GridData.FILL, true, false,

+				1, 1);

+		data.widthHint = convertWidthInCharsToPixels(50);

+		xpathProcessorViewer.getCombo().setLayoutData(data);

+	}

+

+	private String getExtensionFromEditor() {

+		IEditorPart ep = getEditorPart();

+		if (ep != null) {

+			Object elem = ep.getEditorInput();

+			if (elem instanceof IFileEditorInput) {

+				String extension = ((IFileEditorInput) elem).getFile()

+						.getFileExtension();

+				if (extension == null)

+					return ((IFileEditorInput) elem).getFile().getName();

+				return "*." + extension; //$NON-NLS-1$

+			}

+		}

+		return null;

+	}

+

+	private IEditorPart getEditorPart() {

+		return XMLSearchUIPlugin.getActivePage().getActiveEditor();

+	}

+

+	private void addFileNameControls(Composite group) {

+		// grid layout with 2 columns

+

+		// Line with label, combo and button

+		Label label = new Label(group, SWT.LEAD);

+		label.setText(Messages.SearchPage_fileNamePatterns_text);

+		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2,

+				1));

+		label.setFont(group.getFont());

+

+		fExtensions = new Combo(group, SWT.SINGLE | SWT.BORDER);

+		fExtensions.addModifyListener(new ModifyListener() {

+			public void modifyText(ModifyEvent e) {

+				updateOKStatus();

+			}

+		});

+		GridData data = new GridData(GridData.FILL, GridData.FILL, true, false,

+				1, 1);

+		data.widthHint = convertWidthInCharsToPixels(50);

+		fExtensions.setLayoutData(data);

+		fExtensions.setFont(group.getFont());

+

+		Button button = new Button(group, SWT.PUSH);

+		button.setText(Messages.SearchPage_browse);

+		GridData gridData = new GridData(SWT.BEGINNING, SWT.CENTER, false,

+				false, 1, 1);

+		gridData.widthHint = SWTUtil.getButtonWidthHint(button);

+		button.setLayoutData(gridData);

+		button.setFont(group.getFont());

+

+		fFileTypeEditor = new FileTypeEditor(fExtensions, button);

+

+	}

+

+	protected void handleWidgetSelected() {

+		int selectionIndex = xpathCombo.getSelectionIndex();

+		if (selectionIndex < 0

+				|| selectionIndex >= fPreviousSearchPatterns.size())

+			return;

+

+		SearchPatternData patternData = (SearchPatternData) fPreviousSearchPatterns

+				.get(selectionIndex);

+		if (!xpathCombo.getText().equals(patternData.xpath))

+			return;

+		xpathCombo.setText(patternData.xpath);

+		fFileTypeEditor.setFileTypes(patternData.fileNamePatterns);

+		selectXPathProcessor(patternData.xpathProcessorId);

+		if (patternData.workingSets != null)

+			getContainer().setSelectedWorkingSets(patternData.workingSets);

+		else

+			getContainer().setSelectedScope(patternData.scope);

+

+	}

+

+	private void selectXPathProcessor(String xpathProcessorId) {

+		IXPathProcessorType provider = XPathProcessorManager.getDefault()

+				.getProcessor(xpathProcessorId);

+		if (provider == null) {

+			provider = XPathProcessorManager.getDefault().getProcessor(

+					DefaultXPathProcessor.ID);

+		}

+		if (provider != null) {

+			xpathProcessorViewer

+					.setSelection(new StructuredSelection(provider));

+		}

+	}

+

+	protected void updateOKStatus() {

+		boolean valid = validateXPath();

+		if (valid) {

+			valid = validateXPathProcessor();

+		}

+		// boolean hasFilePattern= fExtensions.getText().length() > 0;

+		getContainer().setPerformActionEnabled(valid);

+	}

+

+	private boolean validateXPathProcessor() {

+		if (xpathProcessorViewer.getSelection().isEmpty()) {

+			statusMessage(true,

+					Messages.SearchPage_xpathProcessor_errorRequired); //$NON-NLS-1$

+			return false;

+		}

+		return true;

+	}

+

+	private boolean validateXPath() {

+		String xpath = xpathCombo.getText();

+		if (xpath == null || xpath.length() < 1) {

+			statusMessage(true, Messages.SearchPage_xpath_errorRequired); //$NON-NLS-1$

+			return false;

+		}

+		IStatus status = XPathManager.getManager().validateXPath(

+				getXPathProcessorId(), xpath);

+		if (!status.isOK() && status.getException() != null) {

+			String error = getErrorMessage(status.getException());

+			statusMessage(true, error != null ? error : ""); // only take first

+			// // line

+			return false;

+		}

+		statusMessage(false, Messages.SearchPage_xpath_hint);

+		return true;

+	}

+

+	private String getErrorMessage(Throwable e) {

+		if (e == null) {

+			return null;

+		}

+		String locMessage = e.getLocalizedMessage();

+		if (locMessage == null || locMessage.length() < 1) {

+			locMessage = e.getMessage();

+		}

+		if (locMessage == null || locMessage.length() < 1) {

+			return getErrorMessage(e.getCause());

+		} else {

+			int i = 0;

+			while (i < locMessage.length()

+					&& "\n\r".indexOf(locMessage.charAt(i)) == -1) { //$NON-NLS-1$

+				i++;

+			}

+			return locMessage.substring(0, i);

+		}

+	}

+

+	public void setContainer(ISearchPageContainer container) {

+		this.container = container;

+	}

+

+	private ISearchPageContainer getContainer() {

+		return container;

+	}

+

+	private boolean getExtensions(Collection<String> extensions) {

+		String fileType = null;

+		String[] fileTypes = fFileTypeEditor.getFileTypes();

+		for (int i = 0; i < fileTypes.length; i++) {

+			fileType = fileTypes[i];

+			if (fileType.equals("*") || fileType.equals("*.*")) {

+				return true;

+			}

+			if (fileType.startsWith("*.")) {

+				extensions.add(fileType.substring(2, fileType.length()));

+			} else {

+				extensions.add(fileType);

+			}

+		}

+		return false;

+	}

+

+	private boolean initializeXPathControl() {

+		ISelection selection = getSelection();

+		if (selection instanceof ITextSelection && !selection.isEmpty()) {

+			ITextSelection textSelection = ((ITextSelection) selection);

+			String text = textSelection.getText();

+			if (text != null && !text.isEmpty()) {

+				ITextEditor textEditor = SearchUtil

+						.getTextEditor(getEditorPart());

+				if (textEditor != null) {

+					IDOMNode selectedNode = DOMUtils

+							.getSelectedNode((ITextEditor) textEditor);

+					if (selectedNode != null) {

+						namespaceInfos = XPathManager.getManager()

+								.getNamespaceInfo(selectedNode);

+						// Compute XPath

+						String xpath = XPathManager

+								.getManager()

+								.computeBasicXPath(selectedNode, namespaceInfos);

+						if (xpath != null) {

+							xpathCombo.setText(xpath);

+						}

+					}

+				}

+				//

+

+				// if (fIsRegExSearch)

+				// fPattern.setText(FindReplaceDocumentAdapter.escapeForRegExPattern(text));

+				// else

+				// fPattern.setText(insertEscapeChars(text));

+				//

+				if (getPreviousExtensions().length > 0) {

+					fExtensions.setText(getPreviousExtensions()[0]);

+				} else {

+					String extension = getExtensionFromEditor();

+					if (extension != null)

+						fExtensions.setText(extension);

+					else

+						fExtensions.setText(DEFAULT_XML_EXT); //$NON-NLS-1$

+				}

+				return true;

+			}

+		}

+		return false;

+	}

+

+	private ISelection getSelection() {

+		return container.getSelection();

+	}

+

+	/**

+	 * Return search pattern data and update previous searches. An existing

+	 * entry will be updated.

+	 * 

+	 * @return the search pattern data

+	 */

+	private SearchPatternData getPatternData() {

+		SearchPatternData match = findInPrevious(xpathCombo.getText());

+		if (match != null) {

+			fPreviousSearchPatterns.remove(match);

+		}

+		match = new SearchPatternData(getXPath(), getXPathProcessorId(),

+				fFileTypeEditor.getFileTypes(), getContainer()

+						.getSelectedScope(), getContainer()

+						.getSelectedWorkingSets());

+		fPreviousSearchPatterns.add(0, match);

+		return match;

+	}

+

+	private String getXPath() {

+		return xpathCombo.getText();

+	}

+

+	private String getXPathProcessorId() {

+		ISelection selection = xpathProcessorViewer.getSelection();

+		if (selection.isEmpty()) {

+			return DefaultXPathProcessor.ID;

+		}

+		return ((IXPathProcessorType) ((IStructuredSelection) selection)

+				.getFirstElement()).getId();

+	}

+

+	private SearchPatternData findInPrevious(String pattern) {

+		for (SearchPatternData element : fPreviousSearchPatterns) {

+			if (pattern.equals(element.xpath)) {

+				return element;

+			}

+		}

+		return null;

+	}

+

+	private String[] getPreviousExtensions() {

+		List<String> extensions = new ArrayList<String>(

+				fPreviousSearchPatterns.size());

+		int size = fPreviousSearchPatterns.size();

+		for (int i = 0; i < size; i++) {

+			SearchPatternData data = (SearchPatternData) fPreviousSearchPatterns

+					.get(i);

+			String text = FileTypeEditor.typesToString(data.fileNamePatterns);

+			if (!extensions.contains(text))

+				extensions.add(text);

+		}

+		return (String[]) extensions.toArray(new String[extensions.size()]);

+	}

+

+	private String[] getPreviousSearchPatterns() {

+		int size = fPreviousSearchPatterns.size();

+		String[] patterns = new String[size];

+		for (int i = 0; i < size; i++)

+			patterns[i] = ((SearchPatternData) fPreviousSearchPatterns.get(i)).xpath;

+		return patterns;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.jface.dialogs.DialogPage#dispose()

+	 */

+	public void dispose() {

+		writeConfiguration();

+		super.dispose();

+	}

+

+	/**

+	 * Returns the page settings for this Text search page.

+	 * 

+	 * @return the page settings to be used

+	 */

+	private IDialogSettings getDialogSettings() {

+		return XMLSearchUIPlugin.getDefault().getDialogSettingsSection(

+				PAGE_NAME);

+	}

+

+	/**

+	 * Initializes itself from the stored page settings.

+	 */

+	private void readConfiguration() {

+		IDialogSettings s = getDialogSettings();

+		// fIsCaseSensitive= s.getBoolean(STORE_CASE_SENSITIVE);

+		// fIsRegExSearch= s.getBoolean(STORE_IS_REG_EX_SEARCH);

+		// fSearchDerived= s.getBoolean(STORE_SEARCH_DERIVED);

+

+		try {

+			int historySize = s.getInt(STORE_HISTORY_SIZE);

+			for (int i = 0; i < historySize; i++) {

+				IDialogSettings histSettings = s.getSection(STORE_HISTORY + i);

+				if (histSettings != null) {

+					SearchPatternData data = SearchPatternData

+							.create(histSettings);

+					if (data != null) {

+						fPreviousSearchPatterns.add(data);

+					}

+				}

+			}

+		} catch (NumberFormatException e) {

+			// ignore

+		}

+	}

+

+	/**

+	 * Stores it current configuration in the dialog store.

+	 */

+	private void writeConfiguration() {

+		IDialogSettings s = getDialogSettings();

+		// s.put(STORE_CASE_SENSITIVE, fIsCaseSensitive);

+		// s.put(STORE_IS_REG_EX_SEARCH, fIsRegExSearch);

+		// s.put(STORE_SEARCH_DERIVED, fSearchDerived);

+

+		int historySize = Math

+				.min(fPreviousSearchPatterns.size(), HISTORY_SIZE);

+		s.put(STORE_HISTORY_SIZE, historySize);

+		for (int i = 0; i < historySize; i++) {

+			IDialogSettings histSettings = s.addNewSection(STORE_HISTORY + i);

+			SearchPatternData data = ((SearchPatternData) fPreviousSearchPatterns

+					.get(i));

+			data.store(histSettings);

+		}

+	}

+

+	private void statusMessage(boolean error, String message) {

+		fStatusLabel.setText(message);

+		if (error)

+			fStatusLabel.setForeground(JFaceColors.getErrorText(fStatusLabel

+					.getDisplay()));

+		else

+			fStatusLabel.setForeground(null);

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/AbstractTableBlock.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/AbstractTableBlock.java
new file mode 100644
index 0000000..cf16439
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/AbstractTableBlock.java
@@ -0,0 +1,84 @@
+/*******************************************************************************

+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk

+ * 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:

+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal.preferences;

+

+import org.eclipse.jface.dialogs.IDialogSettings;

+import org.eclipse.swt.widgets.Table;

+

+/**

+ * An <code>AbstractLaunchConfigurationTab</code> specialised for blocks that

+ * contain a table. This abstract class conveniently saves and restores the

+ * table's column settings.

+ * 

+ * @author Doug Satchwell

+ * @since 1.0

+ */

+public abstract class AbstractTableBlock {

+	private int fSortColumn;

+

+	protected abstract Table getTable();

+

+	protected abstract IDialogSettings getDialogSettings();

+

+	protected abstract String getQualifier();

+

+	protected void setSortColumn(int column) {

+		fSortColumn = column;

+	}

+

+	/**

+	 * Persist table settings into the give dialog store, prefixed with the

+	 * given key.

+	 */

+	public void saveColumnSettings() {

+		int columnCount = getTable().getColumnCount();

+		for (int i = 0; i < columnCount; i++) {

+			getDialogSettings()

+					.put(

+							getQualifier() + ".columnWidth" + i, getTable().getColumn(i).getWidth()); //$NON-NLS-1$

+		}

+		getDialogSettings().put(getQualifier() + ".sortColumn", fSortColumn); //$NON-NLS-1$

+	}

+

+	/**

+	 * Restore table settings from the given dialog store using the given key.

+	 */

+	public void restoreColumnSettings() {

+		getTable().layout(true);

+		restoreColumnWidths(getDialogSettings(), getQualifier());

+		int col = 0;

+		try {

+			col = getDialogSettings().getInt(getQualifier() + ".sortColumn"); //$NON-NLS-1$

+		} catch (NumberFormatException e) {

+			col = 1;

+		}

+		setSortColumn(col);

+	}

+

+	private void restoreColumnWidths(IDialogSettings settings, String qualifier) {

+		int columnCount = getTable().getColumnCount();

+		for (int i = 0; i < columnCount; i++) {

+			int width = -1;

+			try {

+				width = settings.getInt(qualifier + ".columnWidth" + i); //$NON-NLS-1$

+			} catch (NumberFormatException e) {

+			}

+

+			if (width > 0)

+				getTable().getColumn(i).setWidth(width);

+		}

+	}

+

+	public void dispose() {

+		if (getTable() != null && !getTable().isDisposed())

+			saveColumnSettings();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/InstalledProcessorsBlock.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/InstalledProcessorsBlock.java
new file mode 100644
index 0000000..ceaa113
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/InstalledProcessorsBlock.java
@@ -0,0 +1,544 @@
+/*******************************************************************************

+ * Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk

+ * 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:

+ *     Doug Satchwell (Chase Technology Ltd) - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal.preferences;

+

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import org.eclipse.core.runtime.ListenerList;

+import org.eclipse.jface.dialogs.IDialogSettings;

+import org.eclipse.jface.layout.GridDataFactory;

+import org.eclipse.jface.viewers.CheckStateChangedEvent;

+import org.eclipse.jface.viewers.CheckboxTableViewer;

+import org.eclipse.jface.viewers.DoubleClickEvent;

+import org.eclipse.jface.viewers.ICheckStateListener;

+import org.eclipse.jface.viewers.IDoubleClickListener;

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.jface.viewers.ISelectionChangedListener;

+import org.eclipse.jface.viewers.ISelectionProvider;

+import org.eclipse.jface.viewers.IStructuredContentProvider;

+import org.eclipse.jface.viewers.IStructuredSelection;

+import org.eclipse.jface.viewers.ITableLabelProvider;

+import org.eclipse.jface.viewers.LabelProvider;

+import org.eclipse.jface.viewers.SelectionChangedEvent;

+import org.eclipse.jface.viewers.StructuredSelection;

+import org.eclipse.jface.viewers.Viewer;

+import org.eclipse.jface.viewers.ViewerSorter;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.events.KeyAdapter;

+import org.eclipse.swt.events.KeyEvent;

+import org.eclipse.swt.events.SelectionAdapter;

+import org.eclipse.swt.events.SelectionEvent;

+import org.eclipse.swt.graphics.Font;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.widgets.Button;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Event;

+import org.eclipse.swt.widgets.Label;

+import org.eclipse.swt.widgets.Listener;

+import org.eclipse.swt.widgets.Table;

+import org.eclipse.swt.widgets.TableColumn;

+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;

+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;

+import org.eclipse.wst.xml.search.ui.internal.Messages;

+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;

+

+public class InstalledProcessorsBlock extends AbstractTableBlock implements

+		ISelectionProvider {

+	private Composite fControl;

+	private final List<IXPathProcessorType> processors = new ArrayList<IXPathProcessorType>();

+	private CheckboxTableViewer tableViewer;

+	private Button fAddButton;

+	private Button fRemoveButton;

+	private Button fEditButton;

+	private final ListenerList fSelectionListeners = new ListenerList();

+	private ISelection fPrevSelection = new StructuredSelection();

+

+	public void addSelectionChangedListener(ISelectionChangedListener listener) {

+		fSelectionListeners.add(listener);

+	}

+

+	public void removeSelectionChangedListener(

+			ISelectionChangedListener listener) {

+		fSelectionListeners.remove(listener);

+	}

+

+	public ISelection getSelection() {

+		return new StructuredSelection(tableViewer.getCheckedElements());

+	}

+

+	public void setSelection(ISelection selection) {

+		if (selection instanceof IStructuredSelection) {

+			if (!selection.equals(fPrevSelection)) {

+				fPrevSelection = selection;

+				Object jre = ((IStructuredSelection) selection)

+						.getFirstElement();

+				if (jre == null) {

+					tableViewer.setCheckedElements(new Object[0]);

+				} else {

+					tableViewer.setCheckedElements(new Object[] { jre });

+					tableViewer.reveal(jre);

+				}

+				fireSelectionChanged();

+			}

+		}

+	}

+

+	public void createControl(Composite ancestor) {

+

+		Composite parent = new Composite(ancestor, SWT.NULL);

+		GridLayout layout = new GridLayout();

+		layout.numColumns = 2;

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		parent.setLayout(layout);

+		Font font = ancestor.getFont();

+		parent.setFont(font);

+		fControl = parent;

+

+		GridData data;

+

+		Label tableLabel = new Label(parent, SWT.NONE);

+		tableLabel.setText(Messages.InstalledProcessorsBlock_0);

+		data = new GridData();

+		data.horizontalSpan = 2;

+		tableLabel.setLayoutData(data);

+		tableLabel.setFont(font);

+

+		Table fTable = new Table(parent, SWT.CHECK | SWT.BORDER

+				| SWT.FULL_SELECTION | SWT.V_SCROLL);

+

+		data = new GridData(GridData.FILL_BOTH);

+		data.widthHint = 450;

+		fTable.setLayoutData(data);

+		fTable.setFont(font);

+

+		fTable.setHeaderVisible(true);

+		fTable.setLinesVisible(true);

+

+		TableColumn column1 = new TableColumn(fTable, SWT.NONE);

+		column1.setWidth(180);

+		column1.setResizable(true);

+		column1.setText(Messages.InstalledProcessorsBlock_1);

+		column1.addSelectionListener(new SelectionAdapter() {

+			@Override

+			public void widgetSelected(SelectionEvent e) {

+				sortByName();

+			}

+		});

+

+		TableColumn column2 = new TableColumn(fTable, SWT.NONE);

+		column2.setWidth(180);

+		column2.setResizable(true);

+		column2.setText(Messages.InstalledProcessorsBlock_2);

+		column2.addSelectionListener(new SelectionAdapter() {

+			@Override

+			public void widgetSelected(SelectionEvent e) {

+				sortBySource();

+			}

+		});

+

+		// TableColumn column4 = new TableColumn(fTable, SWT.NONE);

+		// column4.setWidth(180);

+		// column4.setResizable(true);

+		// column4.setText(Messages.InstalledProcessorsBlock_4);

+		// column4.addSelectionListener(new SelectionAdapter()

+		// {

+		// @Override

+		// public void widgetSelected(SelectionEvent e)

+		// {

+		// sortByVersion();

+		// }

+		// });

+

+		tableViewer = new CheckboxTableViewer(fTable);

+		tableViewer.setLabelProvider(new VMLabelProvider());

+		tableViewer.setContentProvider(new ProcessorsContentProvider());

+

+		tableViewer

+				.addSelectionChangedListener(new ISelectionChangedListener() {

+					public void selectionChanged(SelectionChangedEvent evt) {

+						enableButtons();

+					}

+				});

+

+		tableViewer.addCheckStateListener(new ICheckStateListener() {

+			public void checkStateChanged(CheckStateChangedEvent event) {

+				if (event.getChecked()) {

+					setCheckedInstall((IXPathProcessorType) event.getElement());

+				} else {

+					setCheckedInstall(null);

+				}

+			}

+		});

+

+		tableViewer.addDoubleClickListener(new IDoubleClickListener() {

+			public void doubleClick(DoubleClickEvent e) {

+				if (!tableViewer.getSelection().isEmpty()) {

+					editProcessor();

+				}

+			}

+		});

+		fTable.addKeyListener(new KeyAdapter() {

+			@Override

+			public void keyPressed(KeyEvent event) {

+				if (event.character == SWT.DEL && event.stateMask == 0) {

+					removeProcessors();

+				}

+			}

+		});

+

+		Composite buttons = new Composite(parent, SWT.NULL);

+		buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));

+		layout = new GridLayout();

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		buttons.setLayout(layout);

+		buttons.setFont(font);

+

+		fAddButton = createPushButton(buttons,

+				Messages.InstalledProcessorsBlock_5);

+		fAddButton.addListener(SWT.Selection, new Listener() {

+			public void handleEvent(Event evt) {

+				addProcessor();

+			}

+		});

+		fAddButton.setEnabled(false);

+

+		fEditButton = createPushButton(buttons,

+				Messages.InstalledProcessorsBlock_6);

+		fEditButton.addListener(SWT.Selection, new Listener() {

+			public void handleEvent(Event evt) {

+				editProcessor();

+			}

+		});

+

+		fRemoveButton = createPushButton(buttons,

+				Messages.InstalledProcessorsBlock_7);

+		fRemoveButton.addListener(SWT.Selection, new Listener() {

+			public void handleEvent(Event evt) {

+				removeProcessors();

+			}

+		});

+

+		// copied from ListDialogField.CreateSeparator()

+		Label separator = new Label(buttons, SWT.NONE);

+		separator.setVisible(false);

+		GridData gd = new GridData();

+		gd.horizontalAlignment = GridData.FILL;

+		gd.verticalAlignment = GridData.BEGINNING;

+		gd.heightHint = 4;

+		separator.setLayoutData(gd);

+

+		fillWithWorkspaceProcessors();

+		enableButtons();

+

+		restoreColumnSettings();

+	}

+

+	protected void fillWithWorkspaceProcessors() {

+		setProcessors(XPathProcessorManager.getDefault().getProcessors());

+	}

+

+	private void fireSelectionChanged() {

+		SelectionChangedEvent event = new SelectionChangedEvent(this,

+				getSelection());

+		Object[] listeners = fSelectionListeners.getListeners();

+		for (Object element : listeners) {

+			ISelectionChangedListener listener = (ISelectionChangedListener) element;

+			listener.selectionChanged(event);

+		}

+	}

+

+	/**

+	 * Sorts by type, and name within type.

+	 */

+//	private void sortByType() {

+//		tableViewer.setSorter(new ViewerSorter() {

+//			@Override

+//			public int compare(Viewer viewer, Object e1, Object e2) {

+//				IXPathProcessorType left = (IXPathProcessorType) e1;

+//				IXPathProcessorType right = (IXPathProcessorType) e2;

+//				return left

+//						.getProcessorType()

+//						.getLabel()

+//						.compareToIgnoreCase(

+//								right.getProcessorType().getLabel());

+//			}

+//

+//			@Override

+//			public boolean isSorterProperty(Object element, String property) {

+//				return true;

+//			}

+//		});

+//	}

+

+	private void sortBySource() {

+		tableViewer.setSorter(new ViewerSorter() {

+			@Override

+			public int compare(Viewer viewer, Object e1, Object e2) {

+				IXPathProcessorType left = (IXPathProcessorType) e1;

+				IXPathProcessorType right = (IXPathProcessorType) e2;

+				return left.getSource().compareToIgnoreCase(

+						right.getSource());

+			}

+

+			@Override

+			public boolean isSorterProperty(Object element, String property) {

+				return true;

+			}

+		});

+	}

+

+	/**

+	 * Sorts by name.

+	 */

+	private void sortByName() {

+		tableViewer.setSorter(new ViewerSorter() {

+			@Override

+			public int compare(Viewer viewer, Object e1, Object e2) {

+				if ((e1 instanceof IXPathProcessorType)

+						&& (e2 instanceof IXPathProcessorType)) {

+					IXPathProcessorType left = (IXPathProcessorType) e1;

+					IXPathProcessorType right = (IXPathProcessorType) e2;

+					return left.getName().compareToIgnoreCase(right.getName());

+				}

+				return super.compare(viewer, e1, e2);

+			}

+

+			@Override

+			public boolean isSorterProperty(Object element, String property) {

+				return true;

+			}

+		});

+	}

+

+	private void enableButtons() {

+		IStructuredSelection selection = (IStructuredSelection) tableViewer

+				.getSelection();

+		int selectionCount = selection.size();

+		fEditButton.setEnabled(selectionCount == 1

+				&& !((IXPathProcessorType) selection.getFirstElement())

+						.isContributed());

+		if (selectionCount > 0

+				&& selectionCount < tableViewer.getTable().getItemCount()) {

+			Iterator<?> iterator = selection.iterator();

+			while (iterator.hasNext()) {

+				IXPathProcessorType install = (IXPathProcessorType) iterator

+						.next();

+				if (install.isContributed()) {

+					fRemoveButton.setEnabled(false);

+					return;

+				}

+			}

+			fRemoveButton.setEnabled(true);

+		} else {

+			fRemoveButton.setEnabled(false);

+		}

+	}

+

+	protected Button createPushButton(Composite parent, String label) {

+		Button button = new Button(parent, SWT.PUSH);

+		button.setText(label);

+		button.setLayoutData(GridDataFactory.fillDefaults().create());

+		return button;

+	}

+

+	public Control getControl() {

+		return fControl;

+	}

+

+	protected void setProcessors(IXPathProcessorType[] vms) {

+		processors.clear();

+		for (IXPathProcessorType element : vms) {

+			processors.add(element);

+		}

+		tableViewer.setInput(processors);

+		// tableViewer.refresh();

+	}

+

+	public IXPathProcessorType[] getProcessors() {

+		return processors.toArray(new IXPathProcessorType[processors.size()]);

+	}

+

+	private void addProcessor() {

+		// AddProcessorDialog dialog = new AddProcessorDialog(this, getShell(),

+		// JAXPRuntime.getProcessorTypesExclJREDefault(), null);

+		// dialog.setTitle(Messages.AddProcessorDialog_Add_Title);

+		// if (dialog.open() != Window.OK)

+		// {

+		// return;

+		// }

+	}

+

+	public void processorAdded(IXPathProcessorType install) {

+		processors.add(install);

+		tableViewer.add(install);

+		tableViewer.setSelection(new StructuredSelection(install), true);

+	}

+

+	public boolean isDuplicateName(String name) {

+		for (int i = 0; i < processors.size(); i++) {

+			IXPathProcessorType install = processors.get(i);

+			if (install.getName().equals(name)) {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	private void editProcessor() {

+		IStructuredSelection selection = (IStructuredSelection) tableViewer

+				.getSelection();

+		IXPathProcessorType install = (IXPathProcessorType) selection

+				.getFirstElement();

+		if (install == null) {

+			return;

+		}

+		// if (!install.isContributed())

+		// {

+		// // ProcessorDetailsDialog dialog = new

+		// ProcessorDetailsDialog(getShell(), install);

+		// // dialog.open();

+		// // }

+		// // else

+		// // {

+		// AddProcessorDialog dialog = new AddProcessorDialog(this, getShell(),

+		// JAXPRuntime.getProcessorTypesExclJREDefault(), install);

+		// dialog.setTitle(Messages.AddProcessorDialog_Edit_Title);

+		// if (dialog.open() != Window.OK)

+		// {

+		// return;

+		// }

+		// // fillWithWorkspaceProcessors();

+		// tableViewer.refresh();

+		// }

+	}

+

+	private void removeProcessors() {

+		IStructuredSelection selection = (IStructuredSelection) tableViewer

+				.getSelection();

+		IXPathProcessorType[] vms = new IXPathProcessorType[selection.size()];

+		Iterator<?> iter = selection.iterator();

+		int i = 0;

+		while (iter.hasNext()) {

+			vms[i] = (IXPathProcessorType) iter.next();

+			i++;

+		}

+		removeProcessors(vms);

+	}

+

+	public void removeProcessors(IXPathProcessorType[] theInstalls) {

+		IStructuredSelection prev = (IStructuredSelection) getSelection();

+		for (IXPathProcessorType element : theInstalls) {

+			processors.remove(element);

+		}

+		tableViewer.refresh();

+		IStructuredSelection curr = (IStructuredSelection) getSelection();

+		if (!curr.equals(prev)) {

+			IXPathProcessorType[] installs = getProcessors();

+			if (curr.size() == 0 && installs.length == 1) {

+				// pick a default install automatically

+				setSelection(new StructuredSelection(installs[0]));

+			} else {

+				fireSelectionChanged();

+			}

+		}

+	}

+

+	public void setCheckedInstall(IXPathProcessorType install) {

+		if (install == null) {

+			setSelection(new StructuredSelection());

+		} else {

+			setSelection(new StructuredSelection(install));

+		}

+	}

+

+	public IXPathProcessorType getCheckedInstall() {

+		Object[] objects = tableViewer.getCheckedElements();

+		if (objects.length == 0) {

+			return null;

+		}

+		return (IXPathProcessorType) objects[0];

+	}

+

+	@Override

+	protected void setSortColumn(int column) {

+		switch (column) {

+		case 1:

+			sortByName();

+			break;

+		// case 2:

+		// sortByType();

+		// break;

+		}

+		super.setSortColumn(column);

+	}

+

+	@Override

+	protected Table getTable() {

+		return tableViewer.getTable();

+	}

+

+	@Override

+	protected IDialogSettings getDialogSettings() {

+		return XMLSearchUIPlugin.getDefault().getDialogSettings();

+	}

+

+	private class ProcessorsContentProvider implements

+			IStructuredContentProvider {

+		public Object[] getElements(Object input) {

+			return processors.toArray();

+		}

+

+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

+		}

+

+		public void dispose() {

+		}

+	}

+

+	private static class VMLabelProvider extends LabelProvider implements

+			ITableLabelProvider {

+		public String getColumnText(Object element, int columnIndex) {

+			if (element instanceof IXPathProcessorType) {

+				IXPathProcessorType install = (IXPathProcessorType) element;

+				switch (columnIndex) {

+				case 0:

+					return install.getName();

+				 case 1:

+					 return install.getSource();

+					// case 2:

+					// if (install.getDebugger() != null)

+					// {

+					// return install.getDebugger().getName();

+					// }

+					// return Messages.InstalledProcessorsBlock_8;

+				}

+			}

+			return element.toString();

+		}

+

+		public Image getColumnImage(Object element, int columnIndex) {

+			return null;

+		}

+

+	}

+

+	@Override

+	protected String getQualifier() {

+		return "";

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XMLSearchPreferencePage.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XMLSearchPreferencePage.java
new file mode 100644
index 0000000..e07245a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XMLSearchPreferencePage.java
@@ -0,0 +1,44 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search.

+ * Code comes from org.eclipse.wst.xml.xpath.ui.internal.preferences.XPathPrefencePage but there is not Header license.

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal.preferences;

+

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Text;

+import org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractPreferencePage;

+import org.eclipse.wst.xml.search.ui.internal.Messages;

+

+@SuppressWarnings("restriction")

+public class XMLSearchPreferencePage extends AbstractPreferencePage {

+

+	/**

+	 * (non-Javadoc)

+	 * 

+	 * @see org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractPreferencePage#createContents(org.eclipse.swt.widgets.Composite)

+	 * @deprecated

+	 */

+	protected Control createContents(Composite parent) {

+		Composite composite = createScrolledComposite(parent);

+

+		String description = Messages.XMLSearchPreferencePage_0;

+		Text text = new Text(composite, SWT.READ_ONLY);

+		// some themes on GTK have different background colors for Text and

+		// Labels

+		text.setBackground(composite.getBackground());

+		text.setText(description);

+

+		setSize(composite);

+		return composite;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XPathProcessorPreferencePage.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XPathProcessorPreferencePage.java
new file mode 100644
index 0000000..edfb2ee
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/preferences/XPathProcessorPreferencePage.java
@@ -0,0 +1,123 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.internal.preferences;

+

+import org.eclipse.jface.preference.PreferencePage;

+import org.eclipse.jface.viewers.ISelectionChangedListener;

+import org.eclipse.jface.viewers.SelectionChangedEvent;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.ui.IWorkbench;

+import org.eclipse.ui.IWorkbenchPreferencePage;

+import org.eclipse.wst.xml.search.core.xpath.IXPathProcessorType;

+import org.eclipse.wst.xml.search.core.xpath.XPathProcessorManager;

+import org.eclipse.wst.xml.search.ui.internal.Messages;

+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;

+

+public class XPathProcessorPreferencePage extends PreferencePage implements

+		IWorkbenchPreferencePage {

+

+	private InstalledProcessorsBlock processorsBlock;

+

+	public XPathProcessorPreferencePage() {

+		super();

+		// only used when page is shown programatically

+		setTitle(Messages.XPathProcessorPreferencePage_0);

+		setDescription(Messages.XPathProcessorPreferencePage_1);

+	}

+

+	public void init(IWorkbench workbench) {

+		setPreferenceStore(XMLSearchUIPlugin.getDefault().getPreferenceStore());

+	}

+

+	@Override

+	protected Control createContents(Composite ancestor) {

+		initializeDialogUnits(ancestor);

+

+		noDefaultAndApplyButton();

+

+		GridLayout layout = new GridLayout();

+		layout.numColumns = 1;

+		layout.marginHeight = 0;

+		layout.marginWidth = 0;

+		ancestor.setLayout(layout);

+

+		processorsBlock = new InstalledProcessorsBlock();

+		processorsBlock.createControl(ancestor);

+		Control control = processorsBlock.getControl();

+		GridData data = new GridData(GridData.FILL_BOTH);

+		data.horizontalSpan = 1;

+		control.setLayoutData(data);

+

+		// TODO PlatformUI.getWorkbench().getHelpSystem().setHelp...

+

+		initDefaultInstall();

+		processorsBlock

+				.addSelectionChangedListener(new ISelectionChangedListener() {

+					public void selectionChanged(SelectionChangedEvent event) {

+						IXPathProcessorType processor = getCurrentDefaultProcessor();

+						if (processor == null) {

+							setValid(false);

+							setErrorMessage(Messages.XPathProcessorPreferencePage_2);

+						} else {

+							setValid(true);

+							setErrorMessage(null);

+						}

+					}

+				});

+		applyDialogFont(ancestor);

+		return ancestor;

+	}

+

+	@Override

+	public boolean performOk() {

+		IXPathProcessorType processorType = getCurrentDefaultProcessor();

+		if (processorType == null) {

+			setErrorMessage("Please select a XPath processor");

+			return false;

+		}

+		processorsBlock.saveColumnSettings();

+		XPathProcessorManager.getDefault().setDefaultProcessor(processorType);

+		return true;

+	}

+

+	private void initDefaultInstall() {

+		IXPathProcessorType processorType = XPathProcessorManager.getDefault()

+				.getDefaultProcessor();

+		verifyDefaultVM(processorType);

+

+		// IXPathEvaluatorType realDefault = JAXPRuntime.getDefaultProcessor();

+		// if (realDefault != null) {

+		// IXPathEvaluatorType[] installs = processorsBlock.getProcessors();

+		// for (IXPathEvaluatorType fakeInstall : installs) {

+		// if (fakeInstall.getId().equals(realDefault.getId())) {

+		// verifyDefaultVM(fakeInstall);

+		// break;

+		// }

+		// }

+		// }

+	}

+

+	private void verifyDefaultVM(IXPathProcessorType install) {

+		if (install != null) {

+			processorsBlock.setCheckedInstall(install);

+		} else {

+			processorsBlock.setCheckedInstall(null);

+		}

+	}

+

+	private IXPathProcessorType getCurrentDefaultProcessor() {

+		return processorsBlock.getCheckedInstall();

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/FileTypeEditor.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/FileTypeEditor.java
new file mode 100644
index 0000000..ea8acf4
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/FileTypeEditor.java
@@ -0,0 +1,124 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2008 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.search.ui.internal.util;

+

+import java.util.Arrays;

+import java.util.Comparator;

+import java.util.HashSet;

+import java.util.Set;

+import java.util.StringTokenizer;

+

+import org.eclipse.jface.window.Window;

+import org.eclipse.swt.events.DisposeEvent;

+import org.eclipse.swt.events.DisposeListener;

+import org.eclipse.swt.events.SelectionAdapter;

+import org.eclipse.swt.events.SelectionEvent;

+import org.eclipse.swt.widgets.Button;

+import org.eclipse.swt.widgets.Combo;

+import org.eclipse.swt.widgets.Widget;

+import org.eclipse.ui.dialogs.TypeFilteringDialog;

+import org.eclipse.wst.xml.search.ui.internal.Messages;

+

+public class FileTypeEditor extends SelectionAdapter implements DisposeListener {

+

+	private Combo fTextField;

+	private Button fBrowseButton;

+

+	private final static String TYPE_DELIMITER= Messages.FileTypeEditor_typeDelimiter;

+	public final static String FILE_PATTERN_NEGATOR= "!"; //$NON-NLS-1$

+

+	private static final Comparator FILE_TYPES_COMPARATOR= new Comparator() {

+		public int compare(Object o1, Object o2) {

+			return compare((String) o1, (String) o2);

+		}

+		public int compare(String fp1, String fp2) {

+			boolean isNegative1= fp1.startsWith(FILE_PATTERN_NEGATOR);

+			boolean isNegative2= fp2.startsWith(FILE_PATTERN_NEGATOR);

+			if (isNegative1 != isNegative2) {

+				return isNegative1 ? 1 : -1;

+			}

+			return fp1.compareTo(fp2);

+		}

+	};

+

+	public FileTypeEditor(Combo textField, Button browseButton) {

+		fTextField= textField;

+		fBrowseButton= browseButton;

+

+		fTextField.addDisposeListener(this);

+		fBrowseButton.addDisposeListener(this);

+		fBrowseButton.addSelectionListener(this);

+	}

+

+	public void widgetDisposed(DisposeEvent event) {

+		Widget widget= event.widget;

+		if (widget == fTextField)

+			fTextField= null;

+		else if (widget	== fBrowseButton)

+			fBrowseButton= null;

+	}

+

+	public void widgetSelected(SelectionEvent event) {

+		if (event.widget == fBrowseButton)

+			handleBrowseButton();

+	}

+

+	public String[] getFileTypes() {

+		Set<String> result= new HashSet<String>();

+		StringTokenizer tokenizer= new StringTokenizer(fTextField.getText(), TYPE_DELIMITER);

+

+		while (tokenizer.hasMoreTokens()) {

+			String currentExtension= tokenizer.nextToken().trim();

+			result.add(currentExtension);

+		}

+		return (String[]) result.toArray(new String[result.size()]);

+	}

+

+	public void setFileTypes(String[] types) {

+		fTextField.setText(typesToString(types));

+	}

+

+	protected void handleBrowseButton() {

+		TypeFilteringDialog dialog= new TypeFilteringDialog(fTextField.getShell(), Arrays.asList(getFileTypes()));

+		if (dialog.open() == Window.OK) {

+			Object[] result= dialog.getResult();

+			Set<String> patterns= new HashSet<String>();

+			boolean starIncluded= false;

+			for (int i= 0; i < result.length; i++) {

+				String curr= result[i].toString();

+				if (curr.equals("*")) { //$NON-NLS-1$

+					starIncluded= true;

+				} else {

+					patterns.add("*." + curr); //$NON-NLS-1$

+				}

+			}

+			if (patterns.isEmpty() && starIncluded) { // remove star when other file extensions active

+				patterns.add("*"); //$NON-NLS-1$

+			}

+			String[] filePatterns= (String[]) patterns.toArray(new String[patterns.size()]);

+			Arrays.sort(filePatterns);

+			setFileTypes(filePatterns);

+		}

+	}

+

+	public static String typesToString(String[] types) {

+		Arrays.sort(types, FILE_TYPES_COMPARATOR);

+		StringBuffer result= new StringBuffer();

+		for (int i= 0; i < types.length; i++) {

+			if (i > 0) {

+				result.append(TYPE_DELIMITER);

+				result.append(" "); //$NON-NLS-1$

+			}

+			result.append(types[i]);

+		}

+		return result.toString();

+	}

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/PixelConverter.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/PixelConverter.java
new file mode 100644
index 0000000..8a1eb4d
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/PixelConverter.java
@@ -0,0 +1,114 @@
+/*******************************************************************************

+ * Copyright (c) 2008 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.search.ui.internal.util;

+

+import org.eclipse.swt.graphics.Font;

+import org.eclipse.swt.graphics.FontMetrics;

+import org.eclipse.swt.graphics.GC;

+import org.eclipse.swt.widgets.Control;

+

+import org.eclipse.jface.dialogs.Dialog;

+

+/**

+ * PixelConverter performs various conversions from device-independent units

+ * (such as DLUs or characters) to pixels. It can be associated with a control or

+ * a font. In the case of a control, the font used by the control at the time

+ * the PixelConverter is created is used for the pixel calculations. In the case

+ * of a specific font, the supplied font is used for the calculations.

+ * 

+ * The control and/or font must not be disposed at the time the PixelConverter

+ * is created.

+ * 

+ * @since 3.5

+ */

+public class PixelConverter {

+

+	private final FontMetrics fontMetrics;

+

+	/**

+	 * Create a PixelConverter which will convert device-independent units to

+	 * pixels using the font of the specified control.

+	 * 

+	 * @param control

+	 *            the control whose font should be used for pixel conversions.

+	 *            Note that the font used by the control at the time this

+	 *            constructor is called is the font that will be used for all

+	 *            calculations. If the font of the specified control is changed

+	 *            after this PixelConverter is created, then the conversions

+	 *            from this instance will not produce the desired effect.

+	 */

+	public PixelConverter(Control control) {

+		this(control.getFont());

+	}

+

+	/**

+	 * Create a PixelConverter which will convert device-independent units to

+	 * pixels using the specified font.

+	 * 

+	 * @param font

+	 *            the font that should be used for pixel conversions.

+	 */

+	public PixelConverter(Font font) {

+		GC gc = new GC(font.getDevice());

+		gc.setFont(font);

+		fontMetrics = gc.getFontMetrics();

+		gc.dispose();

+	}

+

+	/**

+	 * Returns the number of pixels corresponding to the height of the given

+	 * number of characters.

+	 * 

+	 * @param chars

+	 *            the number of characters

+	 * @return the number of pixels

+	 */

+	public int convertHeightInCharsToPixels(int chars) {

+		return Dialog.convertHeightInCharsToPixels(fontMetrics, chars);

+	}

+

+	/**

+	 * Returns the number of pixels corresponding to the given number of

+	 * horizontal dialog units.

+	 * 

+	 * @param dlus

+	 *            the number of horizontal dialog units

+	 * @return the number of pixels

+	 */

+	public int convertHorizontalDLUsToPixels(int dlus) {

+		return Dialog.convertHorizontalDLUsToPixels(fontMetrics, dlus);

+	}

+

+	/**

+	 * Returns the number of pixels corresponding to the given number of

+	 * vertical dialog units.

+	 * 

+	 * @param dlus

+	 *            the number of vertical dialog units

+	 * @return the number of pixels

+	 */

+	public int convertVerticalDLUsToPixels(int dlus) {

+		return Dialog.convertVerticalDLUsToPixels(fontMetrics, dlus);

+	}

+

+	/**

+	 * Returns the number of pixels corresponding to the width of the given

+	 * number of characters.

+	 * 

+	 * @param chars

+	 *            the number of characters

+	 * @return the number of pixels

+	 */

+	public int convertWidthInCharsToPixels(int chars) {

+		return Dialog.convertWidthInCharsToPixels(fontMetrics, chars);

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/SWTUtil.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/SWTUtil.java
new file mode 100644
index 0000000..e6690e8
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/internal/util/SWTUtil.java
@@ -0,0 +1,113 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2009 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.search.ui.internal.util;

+

+import org.eclipse.core.runtime.Assert;

+import org.eclipse.jface.dialogs.IDialogConstants;

+import org.eclipse.jface.resource.JFaceResources;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.dnd.DragSource;

+import org.eclipse.swt.dnd.DropTarget;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.widgets.Button;

+import org.eclipse.swt.widgets.Caret;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Display;

+import org.eclipse.swt.widgets.Menu;

+import org.eclipse.swt.widgets.ScrollBar;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.swt.widgets.Table;

+import org.eclipse.swt.widgets.Widget;

+

+

+/**

+ * Utility class to simplify access to some SWT resources.

+ */

+public class SWTUtil {

+

+	/**

+	 * Returns the standard display to be used. The method first checks, if

+	 * the thread calling this method has an associated disaply. If so, this

+	 * display is returned. Otherwise the method returns the default display.

+	 * @return Returns the standard display to be used.

+	 */

+	public static Display getStandardDisplay() {

+		Display display;

+		display= Display.getCurrent();

+		if (display == null)

+			display= Display.getDefault();

+		return display;

+	}

+

+	/**

+	 * Returns the shell for the given widget. If the widget doesn't represent

+	 * a SWT object that manage a shell, <code>null</code> is returned.

+	 *

+	 * @param widget The widget to get the shell for

+	 * @return the shell for the given widget

+	 */

+	public static Shell getShell(Widget widget) {

+		if (widget instanceof Control)

+			return ((Control)widget).getShell();

+		if (widget instanceof Caret)

+			return ((Caret)widget).getParent().getShell();

+		if (widget instanceof DragSource)

+			return ((DragSource)widget).getControl().getShell();

+		if (widget instanceof DropTarget)

+			return ((DropTarget)widget).getControl().getShell();

+		if (widget instanceof Menu)

+			return ((Menu)widget).getParent().getShell();

+		if (widget instanceof ScrollBar)

+			return ((ScrollBar)widget).getParent().getShell();

+

+		return null;

+	}

+

+

+	/**

+	 * Returns a width hint for a button control.

+	 * @param button The button to calculate the width for

+	 * @return The width of the button

+	 */

+	public static int getButtonWidthHint(Button button) {

+		button.setFont(JFaceResources.getDialogFont());

+		PixelConverter converter= new PixelConverter(button);

+		int widthHint= converter.convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);

+		return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);

+	}

+

+	/**

+	 * Sets width and height hint for the button control.

+	 * <b>Note:</b> This is a NOP if the button's layout data is not

+	 * an instance of <code>GridData</code>.

+	 *

+	 * @param button	the button for which to set the dimension hint

+	 */

+	public static void setButtonDimensionHint(Button button) {

+		Assert.isNotNull(button);

+		Object gd= button.getLayoutData();

+		if (gd instanceof GridData) {

+			((GridData)gd).widthHint= getButtonWidthHint(button);

+			((GridData)gd).horizontalAlignment = GridData.FILL;

+		}

+	}

+

+	public static int getTableHeightHint(Table table, int rows) {

+		if (table.getFont().equals(JFaceResources.getDefaultFont()))

+			table.setFont(JFaceResources.getDialogFont());

+		int result= table.getItemHeight() * rows + table.getHeaderHeight();

+		if (table.getLinesVisible())

+			result+= table.getGridLineWidth() * (rows - 1);

+		return result;

+	}

+

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/DOMUtils.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/DOMUtils.java
new file mode 100644
index 0000000..3df7084
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/DOMUtils.java
@@ -0,0 +1,205 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.util;

+

+import static org.eclipse.wst.xml.search.core.util.DOMUtils.getAttrByOffset;

+import static org.eclipse.wst.xml.search.core.util.DOMUtils.getNodeByOffset;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.jface.text.ITextSelection;

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.jface.viewers.IStructuredSelection;

+import org.eclipse.ui.IEditorInput;

+import org.eclipse.ui.IFileEditorInput;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.sse.core.StructuredModelManager;

+import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;

+import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;

+import org.eclipse.wst.xml.search.ui.internal.Trace;

+import org.w3c.dom.Node;

+

+/**

+ * Utility class for DOM-SSE node.

+ * 

+ */

+public class DOMUtils {

+

+	/**

+	 * Returns the selected Node from the given text editor.

+	 * 

+	 * @param textEditor

+	 * @return

+	 */

+	public static IDOMNode getSelectedNode(ITextEditor textEditor) {

+		ISelection selection = textEditor.getSelectionProvider().getSelection();

+		if (selection.isEmpty()) {

+			// No selection is the text editor, return null.

+			return null;

+		}

+

+		ITextSelection textSelection = (ITextSelection) textEditor

+				.getSelectionProvider().getSelection();

+		if (selection instanceof IStructuredSelection) {

+			// Selection is done

+			IStructuredSelection structuredSelection = (IStructuredSelection) selection;

+			Object selectedElement = structuredSelection.getFirstElement();

+			if (selectedElement instanceof IDOMNode) {

+				// The first selected element is DOM-SSE Node.

+				// Returns the DOM attribute if can and DOM node otherwise.

+				IDOMNode selectedNode = (IDOMNode) selectedElement;

+				return getSelectedAttrIfCan(textSelection, selectedNode);

+			}

+		}

+

+		// Selected Node is not opened in WTP XML Editor

+		IEditorInput editorInput = textEditor.getEditorInput();

+		if (!(editorInput instanceof IFileEditorInput)) {

+			return null;

+		}

+

+		// Open the DOM SEE to get the IDocument

+		IFile file = ((IFileEditorInput) textEditor.getEditorInput()).getFile();

+		// Load SSE Document to get selected Node

+		IStructuredModel model = null;

+		try {

+			model = StructuredModelManager.getModelManager()

+					.getExistingModelForRead(file);

+			if (model == null) {

+				model = StructuredModelManager.getModelManager()

+						.getModelForRead(file);

+			}

+			if (model == null) {

+				return null;

+			}

+			IDOMNode selectedNode = getNodeByOffset(model,

+					textSelection.getOffset());

+			return getSelectedAttrIfCan(textSelection, selectedNode);

+

+		} catch (Throwable e) {

+			Trace.trace(Trace.WARNING, e.getMessage(), e);

+		} finally {

+			if (model != null) {

+				model.releaseFromRead();

+			}

+		}

+		return null;

+	}

+

+	/**

+	 * Returns the selected attribute of the given text selection if can and the

+	 * selected node otherwise.

+	 * 

+	 * @param textSelection

+	 * @param selectedNode

+	 * @return

+	 */

+	private static IDOMNode getSelectedAttrIfCan(ITextSelection textSelection,

+			IDOMNode selectedNode) {

+		IDOMAttr attr = getAttrByOffset(selectedNode, textSelection.getOffset());

+		if (attr != null) {

+			return attr;

+		}

+		return selectedNode;

+	}

+

+	public static String toString(IDOMNode node) {

+		switch (node.getNodeType()) {

+		case Node.ATTRIBUTE_NODE:

+			return DOMUtils.toString((IDOMAttr) node);

+		case Node.TEXT_NODE:

+			return DOMUtils.toString((IDOMText) node);

+		case Node.ELEMENT_NODE:

+			return DOMUtils.toString((IDOMElement) node);

+		}

+		return node.toString();

+	}

+

+	public static String toString(IDOMAttr attr) {

+		StringBuilder buffer = new StringBuilder();

+		buffer.append('@');

+		buffer.append(attr.getNodeName());

+		buffer.append('(');

+		buffer.append(attr.getValue());

+		buffer.append(") ");

+		toRegionString(attr, buffer);

+

+		IDOMElement element = (IDOMElement) attr.getOwnerElement();

+		if (element != null) {

+			buffer.append(" - Owner element: ");

+			toString(element, buffer);

+		}

+		return buffer.toString();

+	}

+

+	public static String toString(IDOMText text) {

+		StringBuilder buffer = new StringBuilder();

+		buffer.append(text.getNodeName());

+		buffer.append('(');

+		buffer.append(text.getData());

+		buffer.append(") ");

+		toRegionString(text, buffer);

+		// IStructuredDocumentRegion flatNode =

+		// text.getStructuredDocumentRegion();

+		// if (flatNode != null) {

+		// buffer.append('@');

+		// buffer.append(flatNode.toString());

+		// }

+		Node parentNode = text.getParentNode();

+		if (parentNode != null && parentNode.getNodeType() == Node.ELEMENT_NODE) {

+			buffer.append(" - Owner element: ");

+			toString((IDOMElement) parentNode, buffer);

+		}

+		return buffer.toString();

+	}

+

+	public static void toString(IDOMElement element, StringBuilder buffer) {

+		String tagName = element.getTagName();

+		if (element.hasStartTag())

+			buffer.append(tagName);

+		if (element.isEmptyTag())

+			buffer.append('/');

+		if (element.hasEndTag()) {

+			buffer.append('/');

+			buffer.append(tagName);

+		}

+		if (buffer.length() == 0)

+			buffer.append(tagName);

+

+		toRegionString(element, buffer);

+

+	}

+

+	public static String toString(IDOMElement element) {

+		StringBuilder buffer = new StringBuilder();

+		toString(element, buffer);

+		return buffer.toString();

+	}

+

+	private static void toRegionString(IDOMNode element, StringBuilder buffer) {

+		IStructuredDocumentRegion startStructuredDocumentRegion = element

+				.getStartStructuredDocumentRegion();

+		if (startStructuredDocumentRegion != null) {

+			buffer.append('@');

+			buffer.append(startStructuredDocumentRegion.toString());

+		}

+		IStructuredDocumentRegion endStructuredDocumentRegion = element

+				.getEndStructuredDocumentRegion();

+		if (endStructuredDocumentRegion != null) {

+			buffer.append('@');

+			buffer.append(endStructuredDocumentRegion.toString());

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/EditorOpener.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/EditorOpener.java
new file mode 100644
index 0000000..401689a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/EditorOpener.java
@@ -0,0 +1,176 @@
+/*******************************************************************************

+ * Copyright (c) 2000, 2008 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

+ *     Angelo Zerr <angelo.zerr@gmail.com> - adapt for XML Search

+ *     

+ *     Code comes from org.eclipse.search.internal.ui.text.EditorOpener

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.util;

+

+import java.util.HashMap;

+

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IMarker;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.jface.dialogs.ErrorDialog;

+import org.eclipse.search.ui.NewSearchUI;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.IEditorDescriptor;

+import org.eclipse.ui.IEditorInput;

+import org.eclipse.ui.IEditorPart;

+import org.eclipse.ui.IEditorReference;

+import org.eclipse.ui.IEditorRegistry;

+import org.eclipse.ui.IReusableEditor;

+import org.eclipse.ui.IWorkbenchPage;

+import org.eclipse.ui.PartInitException;

+import org.eclipse.ui.ide.IDE;

+import org.eclipse.ui.part.FileEditorInput;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

+import org.eclipse.wst.xml.search.core.util.DOMUtils;

+import org.eclipse.wst.xml.search.ui.internal.Messages;

+import org.eclipse.wst.xml.search.ui.internal.XMLSearchUIPlugin;

+

+public class EditorOpener {

+

+	private IEditorReference fReusedEditor;

+

+	public static void openDOMNode(IWorkbenchPage wbPage, IDOMNode node,

+			EditorOpener editorOpener, Shell shell) {

+		try {

+			// Search result item clicked is DOM node, open the XML editor

+			// and select the node as soon as the XML editor is opened.

+			IFile file = DOMUtils.getFile(node);

+			editorOpener.openAndSelect(wbPage, file, node.getStartOffset(),

+					node.getLength(), false);

+		} catch (PartInitException e) {

+			ErrorDialog.openError(shell,

+					Messages.XMLSearchPage_open_file_dialog_title,

+					Messages.XMLSearchPage_open_file_failed, e.getStatus());

+		}

+	}

+

+	public IEditorPart open(IWorkbenchPage wbPage, IFile file, boolean activate)

+			throws PartInitException {

+		if (NewSearchUI.reuseEditor())

+			return showWithReuse(file, wbPage, getEditorID(file), activate);

+		return showWithoutReuse(file, wbPage, getEditorID(file), activate);

+	}

+

+	public IEditorPart openAndSelect(IWorkbenchPage wbPage, IFile file,

+			int offset, int length, boolean activate) throws PartInitException {

+		String editorId = null;

+		IEditorDescriptor desc = IDE.getEditorDescriptor(file);

+		if (desc == null || !desc.isInternal()) {

+			editorId = "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$

+		} else {

+			editorId = desc.getId();

+		}

+

+		IEditorPart editor;

+		if (NewSearchUI.reuseEditor()) {

+			editor = showWithReuse(file, wbPage, editorId, activate);

+		} else {

+			editor = showWithoutReuse(file, wbPage, editorId, activate);

+		}

+

+		if (editor instanceof ITextEditor) {

+			ITextEditor textEditor = (ITextEditor) editor;

+			textEditor.selectAndReveal(offset, length);

+		} else if (editor != null) {

+			showWithMarker(editor, file, offset, length);

+		}

+		return editor;

+	}

+

+	private IEditorPart showWithoutReuse(IFile file, IWorkbenchPage wbPage,

+			String editorID, boolean activate) throws PartInitException {

+		return IDE.openEditor(wbPage, file, editorID, activate);

+	}

+

+	private String getEditorID(IFile file) throws PartInitException {

+		IEditorDescriptor desc = IDE.getEditorDescriptor(file);

+		if (desc == null)

+			return XMLSearchUIPlugin.getDefault().getWorkbench()

+					.getEditorRegistry()

+					.findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID)

+					.getId();

+		return desc.getId();

+	}

+

+	private IEditorPart showWithReuse(IFile file, IWorkbenchPage page,

+			String editorId, boolean activate) throws PartInitException {

+		IEditorInput input = new FileEditorInput(file);

+		IEditorPart editor = page.findEditor(input);

+		if (editor != null) {

+			page.bringToTop(editor);

+			if (activate) {

+				page.activate(editor);

+			}

+			return editor;

+		}

+		IEditorReference reusedEditorRef = fReusedEditor;

+		if (reusedEditorRef != null) {

+			boolean isOpen = reusedEditorRef.getEditor(false) != null;

+			boolean canBeReused = isOpen && !reusedEditorRef.isDirty()

+					&& !reusedEditorRef.isPinned();

+			if (canBeReused) {

+				boolean showsSameInputType = reusedEditorRef.getId().equals(

+						editorId);

+				if (!showsSameInputType) {

+					page.closeEditors(

+							new IEditorReference[] { reusedEditorRef }, false);

+					fReusedEditor = null;

+				} else {

+					editor = reusedEditorRef.getEditor(true);

+					if (editor instanceof IReusableEditor) {

+						((IReusableEditor) editor).setInput(input);

+						page.bringToTop(editor);

+						if (activate) {

+							page.activate(editor);

+						}

+						return editor;

+					}

+				}

+			}

+		}

+		editor = page.openEditor(input, editorId, activate);

+		if (editor instanceof IReusableEditor) {

+			IEditorReference reference = (IEditorReference) page

+					.getReference(editor);

+			fReusedEditor = reference;

+		} else {

+			fReusedEditor = null;

+		}

+		return editor;

+	}

+

+	private void showWithMarker(IEditorPart editor, IFile file, int offset,

+			int length) throws PartInitException {

+		IMarker marker = null;

+		try {

+			marker = file.createMarker(NewSearchUI.SEARCH_MARKER);

+			HashMap attributes = new HashMap(4);

+			attributes.put(IMarker.CHAR_START, new Integer(offset));

+			attributes.put(IMarker.CHAR_END, new Integer(offset + length));

+			marker.setAttributes(attributes);

+			IDE.gotoMarker(editor, marker);

+		} catch (CoreException e) {

+			throw new PartInitException(Messages.XMLSearchPage_error_marker, e);

+		} finally {

+			if (marker != null)

+				try {

+					marker.delete();

+				} catch (CoreException e) {

+					// ignore

+				}

+		}

+	}

+

+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/SearchUtil.java b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/SearchUtil.java
new file mode 100644
index 0000000..8044b27
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.ui/src/org/eclipse/wst/xml/search/ui/util/SearchUtil.java
@@ -0,0 +1,163 @@
+/*******************************************************************************

+ * Copyright (c) 2010 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.ui.util;

+

+import org.eclipse.core.commands.ExecutionEvent;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.jface.dialogs.ErrorDialog;

+import org.eclipse.jface.operation.IRunnableContext;

+import org.eclipse.search.ui.ISearchQuery;

+import org.eclipse.search.ui.NewSearchUI;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.IEditorInput;

+import org.eclipse.ui.IEditorPart;

+import org.eclipse.ui.IFileEditorInput;

+import org.eclipse.ui.PlatformUI;

+import org.eclipse.ui.handlers.HandlerUtil;

+import org.eclipse.ui.progress.IProgressService;

+import org.eclipse.ui.texteditor.ITextEditor;

+import org.eclipse.wst.xml.search.core.XMLSearchEngine2;

+import org.eclipse.wst.xml.search.core.queryspecifications.IXMLQuerySpecificationRegistry;

+import org.eclipse.wst.xml.search.core.reporter.IXMLSearchReporter;

+import org.eclipse.wst.xml.search.ui.internal.Messages;

+import org.eclipse.wst.xml.search.ui.internal.XMLSearchQuery;

+

+/**

+ * Utility class for Search UI.

+ * 

+ */

+public class SearchUtil {

+

+	/**

+	 * This helper method with Object as parameter is needed to prevent the

+	 * loading of the Search plug-in: the VM verifies the method call and hence

+	 * loads the types used in the method signature, eventually triggering the

+	 * loading of a plug-in (in this case ISearchQuery results in Search plug-in

+	 * being loaded).

+	 * 

+	 * @param query

+	 *            the search query

+	 */

+	public static void runQueryInBackground(Object query) {

+		NewSearchUI.runQueryInBackground((ISearchQuery) query);

+	}

+

+	/**

+	 * This helper method with Object as parameter is needed to prevent the

+	 * loading of the Search plug-in: the VM verifies the method call and hence

+	 * loads the types used in the method signature, eventually triggering the

+	 * loading of a plug-in (in this case ISearchQuery results in Search plug-in

+	 * being loaded).

+	 * 

+	 * @param context

+	 *            the runnable context

+	 * @param query

+	 *            the search query

+	 * @return status

+	 */

+	public static IStatus runQueryInForeground(IRunnableContext context,

+			Object query) {

+		return NewSearchUI.runQueryInForeground(context, (ISearchQuery) query);

+	}

+

+	/**

+	 * Returns the {@link ITextEditor} from the given event.

+	 * 

+	 * @param event

+	 * @return

+	 */

+	public static ITextEditor getTextEditor(ExecutionEvent event) {

+		IEditorPart editor = HandlerUtil.getActiveEditor(event);

+		return getTextEditor(editor);

+	}

+

+	/**

+	 * Returns the {@link ITextEditor} from the given editor part.

+	 * 

+	 * @param editor

+	 * @return

+	 */

+	public static ITextEditor getTextEditor(IEditorPart editor) {

+		if (editor instanceof ITextEditor)

+			return (ITextEditor) editor;

+		else {

+			Object o = editor.getAdapter(ITextEditor.class);

+			if (o != null)

+				return (ITextEditor) o;

+		}

+		return null;

+	}

+

+	/**

+	 * Returns the {@link IFile} from the given editor part.

+	 * 

+	 * @param editor

+	 * @return

+	 */

+	public static IFile getFile(IEditorPart editor) {

+		IEditorInput editorInput = editor.getEditorInput();

+		if (!(editorInput instanceof IFileEditorInput)) {

+			return null;

+		}

+		return ((IFileEditorInput) editorInput).getFile();

+	}

+

+	/**

+	 * Perform the XMl Search.

+	 * 

+	 * @param shell

+	 *            the parent shell.

+	 * @param querySpecificationRegistry

+	 *            registry of the XML query specification to execute.

+	 * @param reporter

+	 *            XML search reporter.

+	 * @throws InterruptedException

+	 * @throws CoreException

+	 */

+	public static void performNewSearch(Shell shell,

+			IXMLQuerySpecificationRegistry querySpecificationRegistry,

+			IXMLSearchReporter reporter) throws InterruptedException,

+			CoreException {

+

+		XMLSearchQuery query = new XMLSearchQuery(querySpecificationRegistry,

+				XMLSearchEngine2.getDefault(), reporter);

+		if (query.canRunInBackground()) {

+			/*

+			 * This indirection with Object as parameter is needed to prevent

+			 * the loading of the Search plug-in: the VM verifies the method

+			 * call and hence loads the types used in the method signature,

+			 * eventually triggering the loading of a plug-in (in this case

+			 * ISearchQuery results in Search plug-in being loaded).

+			 */

+			SearchUtil.runQueryInBackground(query);

+		} else {

+			IProgressService progressService = PlatformUI.getWorkbench()

+					.getProgressService();

+			/*

+			 * This indirection with Object as parameter is needed to prevent

+			 * the loading of the Search plug-in: the VM verifies the method

+			 * call and hence loads the types used in the method signature,

+			 * eventually triggering the loading of a plug-in (in this case it

+			 * would be ISearchQuery).

+			 */

+			IStatus status = SearchUtil.runQueryInForeground(progressService,

+					query);

+			if (status.matches(IStatus.ERROR | IStatus.INFO | IStatus.WARNING)) {

+				ErrorDialog.openError(shell,

+						Messages.Search_Error_search_title,

+						Messages.Search_Error_search_message, status);

+			}

+		}

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/.classpath b/plugins/org.eclipse.wst.xml.search.xpath.processors/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/.project b/plugins/org.eclipse.wst.xml.search.xpath.processors/.project
new file mode 100644
index 0000000..1060a4f
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.wst.xml.search.xpath.processors</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.wst.xml.search.xpath.processors/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..d9eb17a
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Thu Dec 09 14:46:07 CET 2010

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

+org.eclipse.jdt.core.compiler.compliance=1.5

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.5

diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.xml.search.xpath.processors/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..c2668c0
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.xpath.processors;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.wst.xml.search.xpath.processors.Activator
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.wst.xml.xpath2.processor;bundle-version="1.1.1",
+ org.apache.xerces;bundle-version="2.9.0",
+ org.eclipse.wst.xml.xpath.core;bundle-version="1.1.0",
+ org.eclipse.wst.xml.core
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ClassPath: .
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/build.properties b/plugins/org.eclipse.wst.xml.search.xpath.processors/build.properties
new file mode 100644
index 0000000..73a5119
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/build.properties
@@ -0,0 +1,6 @@
+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .,\

+               plugin.properties,\

+               plugin.xml

diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.properties b/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.properties
new file mode 100644
index 0000000..f88a609
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.properties
@@ -0,0 +1,14 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+pluginName=XML Search - XPath processors

+providerName=Angelo ZERR

+

+wstXPath2ProcessorName=WST XPath 2.0 processor
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.xml b/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.xml
new file mode 100644
index 0000000..4f21624
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/plugin.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<?eclipse version="3.4"?>

+<plugin>

+		

+	<extension

+	      point="org.eclipse.wst.xml.search.core.xpathProcessors">

+	    <processor

+	          class="org.eclipse.wst.xml.search.xpath.processors.WSTXPath2Processor"

+	          id="WSTXPath2Evaluator"

+	          name="%wstXPath2ProcessorName">

+	    </processor>

+	</extension>	

+	

+</plugin>

diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/Activator.java b/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/Activator.java
new file mode 100644
index 0000000..9197cb3
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/Activator.java
@@ -0,0 +1,66 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.xpath.processors;

+

+import org.eclipse.core.runtime.Plugin;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class Activator extends Plugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.xpath.processors";

+

+	// The shared instance

+	private static Activator plugin;

+

+	/**

+	 * The constructor

+	 */

+	public Activator() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * 

+	 * @see

+	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext

+	 * )

+	 */

+	public void stop(BundleContext context) throws Exception {

+		plugin = null;

+		super.stop(context);

+	}

+

+	/**

+	 * Returns the shared instance

+	 * 

+	 * @return the shared instance

+	 */

+	public static Activator getDefault() {

+		return plugin;

+	}

+

+}

diff --git a/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/WSTXPath2Processor.java b/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/WSTXPath2Processor.java
new file mode 100644
index 0000000..46e65f6
--- /dev/null
+++ b/plugins/org.eclipse.wst.xml.search.xpath.processors/src/org/eclipse/wst/xml/search/xpath/processors/WSTXPath2Processor.java
@@ -0,0 +1,111 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.xpath.processors;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;

+import org.eclipse.wst.xml.search.core.xpath.AbstractXPathProcessor;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.eclipse.wst.xml.xpath.core.util.NodeListImpl;

+import org.eclipse.wst.xml.xpath2.processor.DefaultDynamicContext;

+import org.eclipse.wst.xml.xpath2.processor.DefaultEvaluator;

+import org.eclipse.wst.xml.xpath2.processor.DynamicContext;

+import org.eclipse.wst.xml.xpath2.processor.Evaluator;

+import org.eclipse.wst.xml.xpath2.processor.JFlexCupParser;

+import org.eclipse.wst.xml.xpath2.processor.ResultSequence;

+import org.eclipse.wst.xml.xpath2.processor.StaticChecker;

+import org.eclipse.wst.xml.xpath2.processor.StaticNameResolver;

+import org.eclipse.wst.xml.xpath2.processor.XPathParser;

+import org.eclipse.wst.xml.xpath2.processor.XPathParserException;

+import org.eclipse.wst.xml.xpath2.processor.function.FnFunctionLibrary;

+import org.eclipse.wst.xml.xpath2.processor.function.XSCtrLibrary;

+import org.w3c.dom.Document;

+import org.w3c.dom.NodeList;

+

+public class WSTXPath2Processor extends AbstractXPathProcessor {

+

+	public NodeList evaluateNodeSet(Object source, String xpath,

+			NamespaceInfos namespaces, String... criteria)

+			throws XPathExpressionException {

+		ResultSequence rs = evaluate(source, xpath, namespaces, criteria);

+		return new NodeListImpl(rs);

+	}

+

+	public String evaluateString(Object source, String xpath,

+			NamespaceInfos namespaces, String... criteria)

+			throws XPathExpressionException {

+		ResultSequence rs = evaluate(source, xpath, namespaces, criteria);

+		return rs.string();

+	}

+

+	private ResultSequence evaluate(Object source, String xp,

+			NamespaceInfos namespaces, String... criteria)

+			throws XPathExpressionException {

+

+		Document doc = (Document) source;

+		DynamicContext dc = new DefaultDynamicContext(null, doc);

+

+		if (namespaces != null) {

+			String prefix = null;

+			// Add the defined namespaces

+			for (NamespaceInfo namespaceinfo : namespaces) {

+				prefix = namespaces.getPrefix(namespaceinfo);

+				if (prefix != null && prefix.length() > 0) {

+					// when prefix is empty and NamespaceInfo#locationHint is

+					// not empty, the processor failed?

+					dc.add_namespace(prefix, namespaceinfo.uri);

+				}

+			}

+		}

+

+		dc.add_function_library(new FnFunctionLibrary());

+		dc.add_function_library(new XSCtrLibrary());

+

+		XPathParser xpp = new JFlexCupParser();

+

+		try {

+			// Parses the XPath expression.

+			org.eclipse.wst.xml.xpath2.processor.ast.XPath xpath = xpp

+					.parse(xp);

+

+			StaticChecker namecheck = new StaticNameResolver(dc);

+			namecheck.check(xpath);

+

+			// Static Checking the Xpath expression Â’Hello World!Â’

+			// namecheck.check(xp);

+			/**

+			 * Evaluate the XPath 2.0 expression

+			 */

+

+			// Initializing the evaluator with DynamicContext and the name

+			// of the XML document XPexample.xml as parameters.

+			Evaluator eval = new DefaultEvaluator(dc, doc);

+

+			return eval.evaluate(xpath);

+		} catch (Exception ex) {

+			throw new XPathExpressionException(ex);

+		}

+	}

+

+	public IStatus validateXPath(String xp) {

+		XPathParser xpp = new JFlexCupParser();

+		try {

+			xpp.parse(xp);

+		} catch (XPathParserException e) {

+			return createStatusForXPathNotValid(xp, Activator.PLUGIN_ID, e);

+		}

+		return Status.OK_STATUS;

+	}

+

+}

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/.classpath b/tests/org.eclipse.wst.xml.search.core.tests/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/.project b/tests/org.eclipse.wst.xml.search.core.tests/.project
new file mode 100644
index 0000000..7ff7a54
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.wst.xml.search.core.tests</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/.settings/org.eclipse.jdt.core.prefs b/tests/org.eclipse.wst.xml.search.core.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ec53b95
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Tue Nov 23 14:56:34 CET 2010

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

+org.eclipse.jdt.core.compiler.compliance=1.5

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.5

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.wst.xml.search.core.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..09c8e6a
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.core.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.core.tests.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.junit,
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0",
+ org.eclipse.core.resources,
+ org.eclipse.wst.xml.core
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/build.properties b/tests/org.eclipse.wst.xml.search.core.tests/build.properties
new file mode 100644
index 0000000..f463499
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/build.properties
@@ -0,0 +1,14 @@
+###############################################################################

+# Copyright (c) 2011 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/plugin.properties b/tests/org.eclipse.wst.xml.search.core.tests/plugin.properties
new file mode 100644
index 0000000..198470e
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+pluginName=WST XML Search Core Test

+providerName=Angelo ZERR
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/DOMUtils.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/DOMUtils.java
new file mode 100644
index 0000000..0c73a4e
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/DOMUtils.java
@@ -0,0 +1,33 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core;

+

+import java.io.IOException;

+import java.io.InputStream;

+

+import javax.xml.parsers.DocumentBuilder;

+import javax.xml.parsers.DocumentBuilderFactory;

+import javax.xml.parsers.ParserConfigurationException;

+

+import org.w3c.dom.Document;

+import org.xml.sax.SAXException;

+

+public class DOMUtils {

+

+	public static Document load(InputStream stream) throws SAXException,

+			IOException, ParserConfigurationException {

+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

+		factory.setNamespaceAware(true);

+		DocumentBuilder builder = factory.newDocumentBuilder();

+		return builder.parse(stream);

+	}

+

+}

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/tests/Activator.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/tests/Activator.java
new file mode 100644
index 0000000..2e216da
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/tests/Activator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.tests;

+

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class Activator extends AbstractUIPlugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.core.tests";

+

+	// The shared instance

+	private static Activator plugin;

+	

+	/**

+	 * The constructor

+	 */

+	public Activator() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)

+	 */

+	public void stop(BundleContext context) throws Exception {

+		plugin = null;

+		super.stop(context);

+	}

+

+	/**

+	 * Returns the shared instance

+	 *

+	 * @return the shared instance

+	 */

+	public static Activator getDefault() {

+		return plugin;

+	}

+

+}

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/util/StringUtilsTestCase.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/util/StringUtilsTestCase.java
new file mode 100644
index 0000000..8d14553
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/util/StringUtilsTestCase.java
@@ -0,0 +1,47 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.util;

+

+import junit.framework.TestCase;

+

+public class StringUtilsTestCase extends TestCase {

+

+	public void testSpaceNormalize() {

+		String s1 = "\r\n         org.eclipse.wst.xml.search.core.util.StringUtils\r\n";

+		String s2 = StringUtils.normalizeSpace(s1);

+		assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils", s2);

+	}

+

+	public void testSpaceNormalizeFirst() {

+		String s1 = "\r\n         org.eclipse.wst.xml.search.core.util.StringUtils";

+		String s2 = StringUtils.normalizeSpace(s1);

+		assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils", s2);

+	}

+

+	public void testSpaceNormalizeLast() {

+		String s1 = "org.eclipse.wst.xml.search.core.util.StringUtils\r\n";

+		String s2 = StringUtils.normalizeSpace(s1);

+		assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils", s2);

+	}

+	

+	public void testSpaceNormalizeTab() {

+		String s1 = "org.eclipse.wst.xml.search.core.util.StringUtils\r\n\t";

+		String s2 = StringUtils.normalizeSpace(s1);

+		assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils", s2);

+	}

+

+	public void testTrimNormalizeBody() {

+		String s1 = "org.eclipse.wst.xml.search.core.util.StringUtils\r\naaa";

+		String s2 = StringUtils.normalizeSpace(s1);

+		assertEquals("org.eclipse.wst.xml.search.core.util.StringUtils\r\naaa",

+				s2);

+	}

+}

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcherTestCase.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcherTestCase.java
new file mode 100644
index 0000000..2cd980d
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/XPathMatcherTestCase.java
@@ -0,0 +1,139 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath.matcher;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import junit.framework.TestCase;

+

+import org.eclipse.wst.xml.search.core.DOMUtils;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.NodeList;

+

+public class XPathMatcherTestCase extends TestCase {

+

+	public void testOneAttrCondition() throws Exception {

+		Document document = DOMUtils.load(XPathMatcherTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+		XPathMatcher matcher = new XPathMatcher(

+				"/pipelines/pipeline/transformer[@type='pipeline']");

+		boolean match = matcher.match(transformer);

+		assertTrue(match);

+

+	}

+

+	public void testOneAttrNoMatchedCondition() throws Exception {

+

+		Document document = DOMUtils.load(XPathMatcherTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		XPathMatcher matcher = new XPathMatcher(

+				"/pipelines/pipeline/transformer[@type='xslt']");

+		boolean match = matcher.match(transformer);

+		assertFalse(match);

+

+	}

+

+	public void testTwoAttrCondition() throws Exception {

+

+		Document document = DOMUtils.load(XPathMatcherTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		XPathMatcher matcher = new XPathMatcher(

+				"/pipelines/pipeline/transformer[@type='pipeline'][@src='p1']");

+		boolean match = matcher.match(transformer);

+		assertTrue(match);

+

+	}

+

+	public void testOneAttrAndAnyPathCondition() throws Exception {

+

+		Document document = DOMUtils.load(XPathMatcherTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		XPathMatcher matcher = new XPathMatcher(

+				"/pipelines//transformer[@type='pipeline']");

+		boolean match = matcher.match(transformer);

+		assertTrue(match);

+

+	}

+

+	public void testOneAttrAndAnyPathConditionNotMatched() throws Exception {

+

+		Document document = DOMUtils.load(XPathMatcherTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		XPathMatcher matcher = new XPathMatcher(

+				"/AAAAAAAAAAAAAAAA//transformer[@type='pipeline']");

+		boolean match = matcher.match(transformer);

+		assertFalse(match);

+

+	}

+

+	public void testOneAttrAndFullAnyPathCondition() throws Exception {

+

+		Document document = DOMUtils.load(XPathMatcherTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		XPathMatcher matcher = new XPathMatcher(

+				"//transformer[@type='pipeline']");

+		boolean match = matcher.match(transformer);

+		assertTrue(match);

+

+	}

+

+	public void testWildCardValue() throws Exception {

+

+		Document document = DOMUtils.load(XPathMatcherTestCase.class

+				.getResourceAsStream("struts.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "/struts/package/action[@name='hello']", null);

+		Element action = (Element) list.item(0);

+

+		XPathMatcher matcher = new XPathMatcher(

+				"/struts/package/action[@name='$0']");

+

+		List<String> wildCardValues = new ArrayList<String>();

+		boolean match = matcher.match(action, wildCardValues);

+		assertTrue(match);

+		assertEquals(1, wildCardValues.size());

+		assertEquals("hello", wildCardValues.get(0));

+	}

+	

+}

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/docflow-config.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/docflow-config.xml
new file mode 100644
index 0000000..1c0ab6a
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/docflow-config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<docflows-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+	xsi:noNamespaceSchemaLocation="../../../../sidoc-core/design/persistence/collection/meta/docflow.xsd">

+	<docflows>

+		<docflow uri="d2">

+			<state state-type="s1">

+			</state>

+		</docflow>

+		

+		<docflow uri="d1">

+			<state state-type="s1">

+			</state>

+

+			<transitions>

+				<on-version-type uri="version-reference">

+					<transition from-state="s1" >

+					</transition>

+				</on-version-type>

+

+			</transitions>

+

+		</docflow>

+	</docflows>

+</docflows-config>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/XPathMatcherNSTestCase.java b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/XPathMatcherNSTestCase.java
new file mode 100644
index 0000000..66df4c1
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/XPathMatcherNSTestCase.java
@@ -0,0 +1,63 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.core.xpath.matcher.ns;

+

+import junit.framework.TestCase;

+

+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;

+import org.eclipse.wst.xml.search.core.DOMUtils;

+import org.eclipse.wst.xml.search.core.xpath.NamespaceInfos;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.eclipse.wst.xml.search.core.xpath.matcher.XPathMatcher;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.NodeList;

+

+public class XPathMatcherNSTestCase extends TestCase {

+

+	public void testWeb25() throws Exception {

+		Document document = DOMUtils.load(XPathMatcherNSTestCase.class

+				.getResourceAsStream("web2.5.xml"));

+		document.getNamespaceURI();

+		

+		NamespaceInfos infos = new NamespaceInfos();

+		infos.add(new NamespaceInfo("http://java.sun.com/xml/ns/javaee", "ns", "")); 

+		

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "/ns:web-app/ns:servlet", infos);

+		Element servlet = (Element) list.item(0);

+		assertNotNull(servlet);

+		

+		XPathMatcher matcher = new XPathMatcher(

+				"/ns:web-app/ns:servlet");

+		boolean match = matcher.match(servlet);

+		assertTrue(match);

+	}

+	

+	public void testWeb25NS() throws Exception {

+		Document document = DOMUtils.load(XPathMatcherNSTestCase.class

+				.getResourceAsStream("web2.5_ns.xml"));

+		document.getNamespaceURI();

+		

+		NamespaceInfos infos = new NamespaceInfos();

+		infos.add(new NamespaceInfo("http://java.sun.com/xml/ns/javaee", "ns", "")); 

+		

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "/ns:web-app/ns:servlet", infos);

+		Element servlet = (Element) list.item(0);

+		assertNotNull(servlet);

+		

+		XPathMatcher matcher = new XPathMatcher(

+				"/ns:web-app/ns:servlet");

+		boolean match = matcher.match(servlet);

+		assertTrue(match);

+	}

+}

diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5.xml
new file mode 100644
index 0000000..ab23b6d
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app
+  xmlns="http://java.sun.com/xml/ns/javaee"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+  metadata-complete="true"
+  version="2.5" 
+>
+  <servlet>
+    <servlet-name>default</servlet-name>
+    <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>default</servlet-name>
+    <url-pattern>/</url-pattern>
+  </servlet-mapping>
+
+</web-app>
+
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5_ns.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5_ns.xml
new file mode 100644
index 0000000..018cdaf
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/ns/web2.5_ns.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<javaee:web-app
+  xmlns:javaee="http://java.sun.com/xml/ns/javaee"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+  metadata-complete="true"
+  version="2.5" 
+>
+  <javaee:servlet>
+    <javaee:servlet-name>default</javaee:servlet-name>
+    <javaee:servlet-class>org.eclipse.jetty.servlet.DefaultServlet</javaee:servlet-class>
+  </javaee:servlet>
+
+  <javaee:servlet-mapping>
+    <javaee:servlet-name>default</javaee:servlet-name>
+    <javaee:url-pattern>/</javaee:url-pattern>
+  </javaee:servlet-mapping>
+
+</javaee:web-app>
+
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/pipelines.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/pipelines.xml
new file mode 100644
index 0000000..7287ab2
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/pipelines.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<pipelines>

+

+	<pipeline uri="p1">

+		<transformer type="xslt" src="file1.xsl" />

+	</pipeline>

+

+	<pipeline uri="p2">

+		<transformer type="xslt" src="file2.xsl" />

+		<transformer type="pipeline" src="p1" />

+	</pipeline>

+	

+	<pipeline uri="p3">

+	</pipeline>

+	

+</pipelines>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/struts.xml b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/struts.xml
new file mode 100644
index 0000000..2a1f623
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.core.tests/src/org/eclipse/wst/xml/search/core/xpath/matcher/struts.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE struts PUBLIC
+    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
+    "http://struts.apache.org/dtds/struts-2.1.7.dtd">
+
+<struts>
+
+	<constant name="struts.devMode" value="true" />
+
+	<package name="basicstruts2" extends="struts-default">
+
+		<result-types>
+			<result-type name="UUU"
+				class="org.apache.struts.helloworld.action.HelloWorldAction"></result-type>
+		</result-types>
+
+		<!--
+			If no class attribute is specified the framework will assume success
+			and render the result index.jsp
+		-->
+		<!--
+			If no name value for the result node is specified the success value
+			is the default
+		-->
+		<action name="index">
+			<result>/index.jsp</result>
+		</action>
+
+		<action name="III">
+			<interceptor-ref name="actionMappingParams"></interceptor-ref>
+		</action>
+
+		<!--
+			If the URL is hello.action the call the execute method of class
+			HelloWorldAction. If the result returned by the execute method is
+			success render the HelloWorld.jsp
+		-->
+		<action name="hello"
+			class="org.apache.struts.helloworld.action.HelloWorldAction" method="execute">
+			<result name="success" type="xslt" >/HelloWorld.jsp</result>
+		</action>
+
+	</package>
+
+</struts>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/.classpath b/tests/org.eclipse.wst.xml.search.editor.tests/.classpath
new file mode 100644
index 0000000..2d1a430
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>

+	<classpathentry kind="src" path="src"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/.project b/tests/org.eclipse.wst.xml.search.editor.tests/.project
new file mode 100644
index 0000000..b57d73c
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.wst.xml.search.editor.tests</name>

+	<comment></comment>

+	<projects>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.ManifestBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+		<buildCommand>

+			<name>org.eclipse.pde.SchemaBuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.pde.PluginNature</nature>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/.settings/org.eclipse.jdt.core.prefs b/tests/org.eclipse.wst.xml.search.editor.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..ec53b95
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Tue Nov 23 14:56:34 CET 2010

+eclipse.preferences.version=1

+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

+org.eclipse.jdt.core.compiler.compliance=1.5

+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

+org.eclipse.jdt.core.compiler.source=1.5

diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.wst.xml.search.editor.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..14bc09a
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Bundle-SymbolicName: org.eclipse.wst.xml.search.core.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.wst.xml.search.editor.tests.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.junit,
+ org.eclipse.core.resources,
+ org.eclipse.wst.xml.search.editor;bundle-version="1.0.0",
+ org.eclipse.wst.xml.search.core;bundle-version="1.0.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/build.properties b/tests/org.eclipse.wst.xml.search.editor.tests/build.properties
new file mode 100644
index 0000000..f463499
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/build.properties
@@ -0,0 +1,14 @@
+###############################################################################

+# Copyright (c) 2011 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+source.. = src/

+output.. = bin/

+bin.includes = META-INF/,\

+               .

diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/plugin.properties b/tests/org.eclipse.wst.xml.search.editor.tests/plugin.properties
new file mode 100644
index 0000000..198470e
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/plugin.properties
@@ -0,0 +1,12 @@
+###############################################################################

+# Copyright (c) 2010 Angelo Zerr 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:

+#     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 

+###############################################################################

+pluginName=WST XML Search Core Test

+providerName=Angelo ZERR
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/DOMUtils.java b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/DOMUtils.java
new file mode 100644
index 0000000..b714513
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/DOMUtils.java
@@ -0,0 +1,32 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor;

+

+import java.io.IOException;

+import java.io.InputStream;

+

+import javax.xml.parsers.DocumentBuilder;

+import javax.xml.parsers.DocumentBuilderFactory;

+import javax.xml.parsers.ParserConfigurationException;

+

+import org.w3c.dom.Document;

+import org.xml.sax.SAXException;

+

+public class DOMUtils {

+

+	public static Document load(InputStream stream) throws SAXException,

+			IOException, ParserConfigurationException {

+		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

+		DocumentBuilder builder = factory.newDocumentBuilder();

+		return builder.parse(stream);

+	}

+

+}

diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/XMLReferenceUtilTestCase.java b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/XMLReferenceUtilTestCase.java
new file mode 100644
index 0000000..369dccd
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/XMLReferenceUtilTestCase.java
@@ -0,0 +1,282 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.references;

+

+import java.util.List;

+

+import javax.xml.xpath.XPathExpressionException;

+

+import junit.framework.TestCase;

+

+import org.eclipse.wst.xml.search.core.queryspecifications.querybuilder.EqualsStringQueryBuilder;

+import org.eclipse.wst.xml.search.core.xpath.XPathManager;

+import org.eclipse.wst.xml.search.editor.DOMUtils;

+import org.w3c.dom.Attr;

+import org.w3c.dom.Document;

+import org.w3c.dom.Element;

+import org.w3c.dom.NodeList;

+

+public class XMLReferenceUtilTestCase extends TestCase {

+

+	private static String[] PIPELINES_CONTENT_TYPE = { "pipelinesContentType" };

+

+	public void testNodeNull() throws Exception {

+		IXMLReference reference = XMLReferencesUtil.getXMLReference(null,

+				(String) null);

+		assertNull(reference);

+	}

+

+	public void testOneAttrCondition() throws Exception {

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(

+				"/pipelines/pipeline/transformer[@type='pipeline']", "@src",

+				null, null, PIPELINES_CONTENT_TYPE, null, null).getFrom();

+		boolean match = referencePath.match(transformer);

+		assertTrue(match);

+

+	}

+

+	public void testOneAttrNoMatchedCondition() throws Exception {

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(

+				"/pipelines/pipeline/transformer[@type='xslt']", "@src", null,

+				null, PIPELINES_CONTENT_TYPE, null, null).getFrom();

+

+		boolean match = referencePath.match(transformer);

+		assertFalse(match);

+

+	}

+

+	public void testTwoAttrCondition() throws Exception {

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(

+				"/pipelines/pipeline/transformer[@type='pipeline'][@src='p1']",

+				"@src", null, null, PIPELINES_CONTENT_TYPE, null, null)

+				.getFrom();

+

+		boolean match = referencePath.match(transformer);

+		assertTrue(match);

+

+	}

+

+	public void testXMLReferenceInRegisrty() throws Exception {

+

+		IXMLReference reference = XMLReferencesUtil.createXMLReference(

+				"/pipelines/pipeline/transformer[@type='pipeline'][@src='p1']",

+				"@src", null, null, PIPELINES_CONTENT_TYPE, null, null);

+

+		XMLReferencesUtil.registerXMLReference(reference);

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		IXMLReference referenceFromRegisrty = XMLReferencesUtil

+				.getXMLReference(transformer.getAttributeNode("src"),

+						PIPELINES_CONTENT_TYPE[0]);

+		assertNotNull(referenceFromRegisrty);

+

+	}

+

+	public void testXMLReferenceInversed() throws Exception {

+

+		IXMLReference reference = XMLReferencesUtil.createXMLReference(

+				"/pipelines/pipeline/transformer[@type='pipeline']", "@src",

+				null, null, PIPELINES_CONTENT_TYPE, null, null);

+		IXMLReferencePath to = reference.createToXML("", null,

+				"/pipelines/pipeline", "@uri", null, null, null, null, null);

+		reference.addTo(to);

+

+		XMLReferencesUtil.registerXMLReference(reference);

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//pipeline[@uri='p1']", null);

+		Element pipelineP1 = (Element) list.item(0);

+

+		Attr uriAttr = pipelineP1.getAttributeNode("uri");

+

+		List<IXMLReference> referenceInversed = XMLReferencesUtil

+				.getXMLReferenceInversed(uriAttr, PIPELINES_CONTENT_TYPE[0]);

+

+		assertNotNull(referenceInversed);

+		assertEquals(1, referenceInversed.size());

+

+		IXMLReference reference2 = referenceInversed.get(0);

+		IXMLReferencePath fromPath = reference2.getFrom();

+		String xpath = fromPath.getQuery(uriAttr, null,

+				EqualsStringQueryBuilder.INSTANCE);

+

+		assertEquals(

+				"/pipelines/pipeline/transformer[@type='pipeline'][@src=\"p1\"]/@src",

+				xpath);

+		// assertEquals("/pipelines/pipeline",

+		// referenceInversed.get(0).getPath());

+

+	}

+

+	public void testOneAttrAndAnyPathCondition() throws Exception {

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(

+				"/pipelines//transformer[@type='pipeline']", "@src", null,

+				null, PIPELINES_CONTENT_TYPE, null, null).getFrom();

+		boolean match = referencePath.match(transformer);

+		assertTrue(match);

+

+	}

+

+	public void testOneAttrAndAnyPathConditionNotMatched() throws Exception {

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(

+				"/AAAAAAAAAAAAAAAA//transformer[@type='pipeline']", "@src",

+				null, null, PIPELINES_CONTENT_TYPE, null, null).getFrom();

+		boolean match = referencePath.match(transformer);

+		assertFalse(match);

+

+	}

+

+	public void testOneAttrAndFullAnyPathCondition() throws Exception {

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("pipelines.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "//transformer[@type='pipeline']", null);

+		Element transformer = (Element) list.item(0);

+

+		IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(

+				"//transformer[@type='pipeline']", "@src", null, null,

+				PIPELINES_CONTENT_TYPE, null, null).getFrom();

+		boolean match = referencePath.match(transformer);

+		assertTrue(match);

+

+	}

+

+	public void testWildCardValue() throws Exception {

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("struts.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "/struts/package/action[@name='hello']", null);

+		Element action = (Element) list.item(0);

+

+		IXMLReferencePath referencePath = XMLReferencesUtil.createXMLReference(

+				"/struts/package/action[@name='$0']", "@method", null, null,

+				PIPELINES_CONTENT_TYPE, null, null).getFrom();

+

+		boolean match = referencePath.match(action);

+		assertTrue(match);

+		List<String> wildCardValues = referencePath.getWildcardValues(action);

+		assertEquals(1, wildCardValues.size());

+		assertEquals("hello", wildCardValues.get(0));

+	}

+

+	public void testExtractJavaMethodForStruts2() throws Exception {

+

+		IXMLReference reference = XMLReferencesUtil.createXMLReference(

+				"/struts/package/action", "@method", null, null,

+				PIPELINES_CONTENT_TYPE, null, null);

+		IXMLReferenceToJavaMethod toJavaMethod = reference.createToJavaMethod(

+				"", null, null, "/pipelines/pipeline", "@class", null);

+		reference.addTo(toJavaMethod);

+

+		XMLReferencesUtil.registerXMLReference(reference);

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("struts.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "/struts/package/action[@name='hello']", null);

+		Element action = (Element) list.item(0);

+

+		XPathExpressionException ex = null;

+		String className = null;

+		try {

+			className = toJavaMethod.extractClassName(action, null, null, null);

+		} catch (XPathExpressionException e) {

+			ex = e;

+			e.printStackTrace();

+		}

+		assertNull(ex);

+		assertEquals("org.apache.struts.helloworld.action.HelloWorldAction",

+				className);

+	}

+

+	public void testExtractJavaMethodForJetty() throws Exception {

+

+		IXMLReference reference = XMLReferencesUtil.createXMLReference(

+				"/struts/package/action", "@method", null, null,

+				PIPELINES_CONTENT_TYPE, null, null);

+		IXMLReferenceToJavaMethod toJavaMethod = reference.createToJavaMethod(

+				"", null, null, "/pipelines/pipeline", "@class", null);

+		reference.addTo(toJavaMethod);

+

+		XMLReferencesUtil.registerXMLReference(reference);

+

+		Document document = DOMUtils.load(XMLReferenceUtilTestCase.class

+				.getResourceAsStream("struts.xml"));

+

+		NodeList list = XPathManager.getManager().evaluateNodeSet(null,

+				document, "/struts/package/action[@name='hello']", null);

+		Element action = (Element) list.item(0);

+

+		XPathExpressionException ex = null;

+		String className = null;

+		try {

+			className = toJavaMethod.extractClassName(action, null, null, null);

+		} catch (XPathExpressionException e) {

+			ex = e;

+			e.printStackTrace();

+		}

+		assertNull(ex);

+		assertEquals("org.apache.struts.helloworld.action.HelloWorldAction",

+				className);

+	}

+}

diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/docflow-config.xml b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/docflow-config.xml
new file mode 100644
index 0000000..1c0ab6a
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/docflow-config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<docflows-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+	xsi:noNamespaceSchemaLocation="../../../../sidoc-core/design/persistence/collection/meta/docflow.xsd">

+	<docflows>

+		<docflow uri="d2">

+			<state state-type="s1">

+			</state>

+		</docflow>

+		

+		<docflow uri="d1">

+			<state state-type="s1">

+			</state>

+

+			<transitions>

+				<on-version-type uri="version-reference">

+					<transition from-state="s1" >

+					</transition>

+				</on-version-type>

+

+			</transitions>

+

+		</docflow>

+	</docflows>

+</docflows-config>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/pipelines.xml b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/pipelines.xml
new file mode 100644
index 0000000..7287ab2
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/pipelines.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<pipelines>

+

+	<pipeline uri="p1">

+		<transformer type="xslt" src="file1.xsl" />

+	</pipeline>

+

+	<pipeline uri="p2">

+		<transformer type="xslt" src="file2.xsl" />

+		<transformer type="pipeline" src="p1" />

+	</pipeline>

+	

+	<pipeline uri="p3">

+	</pipeline>

+	

+</pipelines>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/struts.xml b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/struts.xml
new file mode 100644
index 0000000..dec0c3b
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/references/struts.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<struts>
+
+	<constant name="struts.devMode" value="true" />
+
+	<package name="basicstruts2" extends="struts-default">
+
+		<result-types>
+			<result-type name="UUU"
+				class="org.apache.struts.helloworld.action.HelloWorldAction"></result-type>
+		</result-types>
+
+		<!--
+			If no class attribute is specified the framework will assume success
+			and render the result index.jsp
+		-->
+		<!--
+			If no name value for the result node is specified the success value
+			is the default
+		-->
+		<action name="index">
+			<result>/index.jsp</result>
+		</action>
+
+		<action name="III">
+			<interceptor-ref name="actionMappingParams"></interceptor-ref>
+		</action>
+
+		<!--
+			If the URL is hello.action the call the execute method of class
+			HelloWorldAction. If the result returned by the execute method is
+			success render the HelloWorld.jsp
+		-->
+		<action name="hello"
+			class="org.apache.struts.helloworld.action.HelloWorldAction" method="execute">
+			<result name="success" type="xslt" >/HelloWorld.jsp</result>
+		</action>
+
+	</package>
+
+</struts>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParserTestCase.java b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParserTestCase.java
new file mode 100644
index 0000000..a0f3b37
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/MultiAttrValuesExpressionParserTestCase.java
@@ -0,0 +1,80 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.searchers.expressions;

+

+import junit.framework.TestCase;

+

+import org.eclipse.wst.xml.search.editor.references.IXMLReferenceToExpression;

+import org.eclipse.wst.xml.search.editor.references.XMLReferencesUtil;

+

+public class MultiAttrValuesExpressionParserTestCase extends TestCase {

+

+	private MultiAttrValuesExpressionParser parser;

+	private IXMLReferenceToExpression toExpression;

+

+	@Override

+	protected void setUp() throws Exception {

+		parser = new MultiAttrValuesExpressionParser();

+		toExpression = XMLReferencesUtil.createXMLReferenceToExpression("", "",

+				null, null, null, null, null, parser, null);

+		super.setUp();

+	}

+

+	public void test1() throws Exception {

+		SearcherToken token = parser.parse("a b c", "a", toExpression);

+		assertEquals("a", token.getRealMatchingString());

+		// assertEquals(0, token.getStartOffset());

+		assertEquals("", token.getBeforeText());

+	}

+

+	public void test2() throws Exception {

+		SearcherToken token = parser.parse("a b c", " a", toExpression);

+		assertEquals(" a", token.getRealMatchingString());

+		// assertEquals(0, token.getStartOffset());

+		assertEquals("", token.getBeforeText());

+	}

+

+	public void test3() throws Exception {

+		SearcherToken token = parser.parse("a b c", "a ", toExpression);

+		assertEquals("", token.getRealMatchingString());

+		// assertEquals(2, token.getStartOffset());

+		assertEquals("a ", token.getBeforeText());

+	}

+

+	public void test4() throws Exception {

+		SearcherToken token = parser.parse("a  b c", "a  ", toExpression);

+		assertEquals(" ", token.getRealMatchingString());

+		// assertEquals(2, token.getStartOffset());

+		assertEquals("a ", token.getBeforeText());

+	}

+

+	public void test5() throws Exception {

+		SearcherToken token = parser.parse("a b c", "a b", toExpression);

+		assertEquals("b", token.getRealMatchingString());

+		// assertEquals(2, token.getStartOffset());

+		assertEquals("a ", token.getBeforeText());

+	}

+

+	public void test6() throws Exception {

+		SearcherToken token = parser.parse("a b c", "a b ", toExpression);

+		assertEquals("", token.getRealMatchingString());

+		// assertEquals(4, token.getStartOffset());

+		assertEquals("a b ", token.getBeforeText());

+	}

+

+	public void test7() throws Exception {

+		SearcherToken token = parser.parse("a  b c", "a  b", toExpression);

+		assertEquals(" b", token.getRealMatchingString());

+		// assertEquals(2, token.getStartOffset());

+		assertEquals("a ", token.getBeforeText());

+	}

+

+}

diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/multi-attributes.xml b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/multi-attributes.xml
new file mode 100644
index 0000000..2f7df8c
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/searchers/expressions/multi-attributes.xml
@@ -0,0 +1,2 @@
+<root attr="a b c" >

+</root>
\ No newline at end of file
diff --git a/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/tests/Activator.java b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/tests/Activator.java
new file mode 100644
index 0000000..bff2d77
--- /dev/null
+++ b/tests/org.eclipse.wst.xml.search.editor.tests/src/org/eclipse/wst/xml/search/editor/tests/Activator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************

+ * Copyright (c) 2011 Angelo ZERR.

+ * 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:      

+ *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.wst.xml.search.editor.tests;

+

+import org.eclipse.ui.plugin.AbstractUIPlugin;

+import org.osgi.framework.BundleContext;

+

+/**

+ * The activator class controls the plug-in life cycle

+ */

+public class Activator extends AbstractUIPlugin {

+

+	// The plug-in ID

+	public static final String PLUGIN_ID = "org.eclipse.wst.xml.search.core.tests";

+

+	// The shared instance

+	private static Activator plugin;

+	

+	/**

+	 * The constructor

+	 */

+	public Activator() {

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)

+	 */

+	public void start(BundleContext context) throws Exception {

+		super.start(context);

+		plugin = this;

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)

+	 */

+	public void stop(BundleContext context) throws Exception {

+		plugin = null;

+		super.stop(context);

+	}

+

+	/**

+	 * Returns the shared instance

+	 *

+	 * @return the shared instance

+	 */

+	public static Activator getDefault() {

+		return plugin;

+	}

+

+}