* DLTK Validators API
diff --git a/core/plugins/.project b/core/plugins/.project
new file mode 100644
index 0000000..0ab6892
--- /dev/null
+++ b/core/plugins/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>plugins</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/core/plugins/org.eclipse.dltk.validators.core/.classpath b/core/plugins/org.eclipse.dltk.validators.core/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/core/plugins/org.eclipse.dltk.validators.core/.cvsignore b/core/plugins/org.eclipse.dltk.validators.core/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/core/plugins/org.eclipse.dltk.validators.core/.project b/core/plugins/org.eclipse.dltk.validators.core/.project
new file mode 100644
index 0000000..d9080be
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.dltk.validators.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/core/plugins/org.eclipse.dltk.validators.core/META-INF/MANIFEST.MF b/core/plugins/org.eclipse.dltk.validators.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..4fa28d8
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: DLTK Model Validators core
+Bundle-SymbolicName: org.eclipse.dltk.validators.core;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.dltk.validators.internal.core.ValidatorsCore
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.dltk.core,
+ org.eclipse.core.resources,
+ org.eclipse.core.filesystem,
+ org.eclipse.core.variables
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.dltk.validators.core,
+ org.eclipse.dltk.validators.internal.core;x-friends:="org.eclipse.dltk.validators.core.tests,org.eclipse.dltk.validators.ui"
diff --git a/core/plugins/org.eclipse.dltk.validators.core/build.properties b/core/plugins/org.eclipse.dltk.validators.core/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/core/plugins/org.eclipse.dltk.validators.core/plugin.xml b/core/plugins/org.eclipse.dltk.validators.core/plugin.xml
new file mode 100644
index 0000000..117816f
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/plugin.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension-point id="validator" name="DLTK Validator" schema="schema/validator.exsd"/>
+   <extension
+         point="org.eclipse.dltk.core.builder">
+      <builder
+            class="org.eclipse.dltk.validators.internal.core.ValidatorBuilder"
+            nature="#">
+      </builder>
+   </extension>
+
+</plugin>
diff --git a/core/plugins/org.eclipse.dltk.validators.core/schema/validator.exsd b/core/plugins/org.eclipse.dltk.validators.core/schema/validator.exsd
new file mode 100644
index 0000000..6edb65a
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/schema/validator.exsd
@@ -0,0 +1,119 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.dltk.validators.core">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.dltk.validators.core" id="validator" name="DLTK Validator"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="validatorType" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="validatorType">
+      <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.dltk.validators.core.IValidatorType"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="nature" type="string" use="required">
+            <annotation>
+               <documentation>
+                  Used to filter validators only for selected type of projects.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/AbstractValidator.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/AbstractValidator.java
new file mode 100644
index 0000000..0e882d3
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/AbstractValidator.java
@@ -0,0 +1,38 @@
+package org.eclipse.dltk.validators.core;
+
+
+public abstract class AbstractValidator implements IValidator {
+	private String id;
+	private String name;
+	private IValidatorType type;
+	boolean active = true;
+	
+	protected AbstractValidator(String id, String name, IValidatorType type ) {
+		this.id = id;
+		this.name = name;
+		this.type = type;
+	}
+	public String getID() {
+		return this.id;
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public IValidatorType getValidatorType() {
+		return this.type;
+	}
+	protected void setID(String id ) {
+		this.id = id;
+	}
+	public void setName( String name ) {
+		this.name = name;
+	}
+	public boolean isActive() {
+		return active;
+	}
+	public void setActive(boolean active) {
+		this.active = active;
+	}	
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/AbstractValidatorType.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/AbstractValidatorType.java
new file mode 100644
index 0000000..e9c599c
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/AbstractValidatorType.java
@@ -0,0 +1,20 @@
+package org.eclipse.dltk.validators.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class AbstractValidatorType implements IValidatorType {
+	protected Map validators = new HashMap();
+	
+	public IValidator[] getValidators() {
+		return (IValidator[])validators.values().toArray(new IValidator[validators.size()]);
+	}
+
+	public IValidator findValidator(String id) {
+		return (IValidator)this.validators.get(id);
+	}
+
+	public void disposeValidator(String id) {
+		validators.remove(id);
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/IValidator.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/IValidator.java
new file mode 100644
index 0000000..fa40db8
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/IValidator.java
@@ -0,0 +1,33 @@
+package org.eclipse.dltk.validators.core;
+
+import java.io.OutputStream;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.dltk.core.ISourceModule;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Contains validator properties.
+ * @author Haiodo
+ *
+ */
+public interface IValidator {
+	String getID();
+	String getName();
+	void setName(String name);
+	IValidatorType getValidatorType();
+	boolean isValidatorValid();
+	
+	//Per-resouce operations
+	// If console is non null then output to console are possible.
+	IStatus validate(ISourceModule module, OutputStream console );
+	IStatus validate(IResource resource, OutputStream console );
+	
+	// Used to store information into
+	void storeTo(Document doc, Element element);
+	
+	boolean isActive();
+	void setActive(boolean active);
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/IValidatorChangedListener.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/IValidatorChangedListener.java
new file mode 100644
index 0000000..334ad38
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/IValidatorChangedListener.java
@@ -0,0 +1,7 @@
+package org.eclipse.dltk.validators.core;
+
+public interface IValidatorChangedListener {
+	public void validatorChanged(IValidator validator);	
+	public void validatorAdded(IValidator validator);		
+	public void validatorRemoved(IValidator validator);				
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/IValidatorType.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/IValidatorType.java
new file mode 100644
index 0000000..c8a67a0
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/IValidatorType.java
@@ -0,0 +1,55 @@
+package org.eclipse.dltk.validators.core;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.dltk.compiler.problem.IProblemReporter;
+import org.eclipse.dltk.core.ISourceModule;
+import org.w3c.dom.Element;
+
+/**
+ * Validator class
+ * 
+ * @author Haiodo
+ * 
+ */
+public interface IValidatorType {
+	/**
+	 * Return validator identifier, must be equal to extension point id. Used to
+	 * determine validator UI configuration preferences.
+	 * 
+	 * @return
+	 */
+	String getID();
+
+	String getNature();
+	
+	String getName();
+
+	/**
+	 * If return true, then this validatorh has UI, and some instances of this
+	 * validator could be used. For example external tool validator should
+	 * return true here, to support specify external progman and arguments.
+	 * 
+	 * If return false, then this is always runningm builtin validator. Static checkers could be here.
+	 * 
+	 * @return
+	 */
+	boolean isConfigurable();
+	
+	/**
+	 * If true then validators of this type could not be added, edited or removed, only activated or diactivated.
+	 * @return
+	 */
+	boolean isBuiltin();
+
+	IValidator createValidatorFrom(String id, Element validatorElement) throws IOException;
+	IValidator createValidator(String id);
+	
+	IValidator[] getValidators();
+
+	IValidator findValidator(String id);
+
+	void disposeValidator(String id);
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/PropertyChangeEvent.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/PropertyChangeEvent.java
new file mode 100644
index 0000000..2765b99
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/PropertyChangeEvent.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.dltk.validators.core;
+
+
+import java.util.EventObject;
+/**
+ * An event object describing a change to a named property.
+ * <p>
+ * ScriptRuntime provides change notification for properties of Interpreter installs
+ * </p>
+ * <p>
+ * Clients may instantiate this class; not intended to be subclassed.
+ * </p>
+	 *
+ */
+public class PropertyChangeEvent extends EventObject {
+    
+    /**
+     * All serializable objects should have a stable serialVersionUID
+     */
+    private static final long serialVersionUID = 1L;
+
+	/**
+	 * The name of the changed property.
+	 */
+	private String propertyName;
+	
+	/**
+	 * The old value of the changed property, or <code>null</code> if
+	 * not known or not relevant.
+	 */
+	private Object oldValue;
+	
+	/**
+	 * The new value of the changed property, or <code>null</code> if
+	 * not known or not relevant.
+	 */
+	private Object newValue;
+	
+	/**
+	 * Creates a new property change event.
+	 *
+	 * @param source the object whose property has changed
+	 * @param property the property that has changed (must not be 
+	 *    <code>null</code>)
+	 * @param oldValue the old value of the property, or 
+	 *    <code>null</code> if none
+	 * @param newValue the new value of the property, or 
+	 *    <code>null</code> if none
+	 */
+	public PropertyChangeEvent(
+		Object source,
+		String property,
+		Object oldValue,
+		Object newValue) {
+	
+		super(source);
+		if (property == null) {
+			throw new IllegalArgumentException();
+		}
+		this.propertyName = property;
+		this.oldValue = oldValue;
+		this.newValue = newValue;
+	}
+	
+	/**
+	 * Returns the name of the property that changed.
+	 *
+	 * @return the name of the property that changed
+	 */
+	public String getProperty() {
+		return propertyName;
+	}
+	
+	/**
+	 * Returns the new value of the property.
+	 *
+	 * @return the new value, or <code>null</code> if not known
+	 *  or not relevant
+	 */
+	public Object getNewValue() {
+		return newValue;
+	}
+	
+	/**
+	 * Returns the old value of the property.
+	 *
+	 * @return the old value, or <code>null</code> if not known
+	 *  or not relevant
+	 */
+	public Object getOldValue() {
+		return oldValue;
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/ValidatorRuntime.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/ValidatorRuntime.java
new file mode 100644
index 0000000..4db5b25
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/core/ValidatorRuntime.java
@@ -0,0 +1,374 @@
+package org.eclipse.dltk.validators.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dltk.compiler.problem.DLTKProblemReporter;
+import org.eclipse.dltk.compiler.problem.DefaultProblemFactory;
+import org.eclipse.dltk.compiler.problem.IProblem;
+import org.eclipse.dltk.compiler.problem.IProblemFactory;
+import org.eclipse.dltk.compiler.problem.IProblemReporter;
+import org.eclipse.dltk.core.DLTKLanguageManager;
+import org.eclipse.dltk.core.IDLTKLanguageToolkit;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.IProblemRequestor;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.validators.internal.core.CompositeId;
+import org.eclipse.dltk.validators.internal.core.ListenerList;
+import org.eclipse.dltk.validators.internal.core.ValidatorDefinitionsContainer;
+import org.eclipse.dltk.validators.internal.core.ValidatorManager;
+import org.eclipse.dltk.validators.internal.core.ValidatorsCore;
+
+public final class ValidatorRuntime {
+
+	public static final String PREF_VALIDATOR_XML = ValidatorsCore.PLUGIN_ID
+			+ ".PREF_VALIDATOR_XML"; //$NON-NLS-1$
+
+	public static final String MARKER_VALIDATOR = ValidatorsCore.PLUGIN_ID
+			+ ".marker_validator_id";
+
+	// lock for interpreter initialization
+	private static Object fgValidatorLock = new Object();
+	private static boolean fgInitializingValidators = false;
+	//
+	private static ListenerList fgValidatorListeners = new ListenerList(5);
+	//	
+	//
+	// private static ThreadLocal fgProjects = new ThreadLocal(); // Lists
+	// private static ThreadLocal fgEntryCount = new ThreadLocal(); // Integers
+
+	private static Set fgContributedValidators = new HashSet();
+
+	private ValidatorRuntime() {
+	}
+
+	public static IValidatorType getValidatorType(String id) {
+		IValidatorType[] interpreterTypes = getValidatorTypes();
+		for (int i = 0; i < interpreterTypes.length; i++) {
+			if (interpreterTypes[i].getID().equals(id)) {
+				return interpreterTypes[i];
+			}
+		}
+		return null;
+	}
+
+	public static IValidatorType[] getValidatorTypes() {
+		initializeValidators();
+		try {
+			return ValidatorManager.getAllValidatorTypes();
+		} catch (CoreException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	public static IValidatorType[] getValidatorTypes(String nature) {
+		try {
+			return ValidatorManager.getValidators(nature);
+		} catch (CoreException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	public static String getCompositeIdFromValidator(IValidator validator) {
+		if (validator == null) {
+			return null;
+		}
+		IValidatorType validatorType = validator.getValidatorType();
+		String typeID = validatorType.getID();
+		CompositeId id = new CompositeId(new String[] { typeID,
+				validator.getID() });
+		return id.toString();
+	}
+
+	public static IValidator getValidatorFromCompositeId(String idString) {
+		if (idString == null || idString.length() == 0) {
+			return null;
+		}
+		CompositeId id = CompositeId.fromString(idString);
+		if (id.getPartCount() == 2) {
+			IValidatorType validatorType = getValidatorType(id.get(0));
+			if (validatorType != null) {
+				return validatorType.findValidator(id.get(1));
+			}
+		}
+		return null;
+	}
+
+	public static void saveInterpreterConfiguration() throws CoreException {
+		IValidatorType[] vals = getValidatorTypes();
+		if (vals == null || vals.length == 0) {
+			// if the Interpreter types have not been instantiated, there can be
+			// no changes.
+			return;
+		}
+		try {
+			String xml = getValidatorsAsXML();
+			getPreferences().setValue(PREF_VALIDATOR_XML, xml);
+			savePreferences();
+		} catch (IOException e) {
+			throw new CoreException(new Status(IStatus.ERROR, "Error",
+					IStatus.ERROR, "Exception occured", e));
+		} catch (ParserConfigurationException e) {
+			throw new CoreException(new Status(IStatus.ERROR, "Error",
+					IStatus.ERROR, "Exception occured", e));
+		} catch (TransformerException e) {
+			throw new CoreException(new Status(IStatus.ERROR, "Error",
+					IStatus.ERROR, "Exception occured", e));
+		}
+	}
+
+	private static String getValidatorsAsXML() throws IOException,
+			ParserConfigurationException, TransformerException {
+		ValidatorDefinitionsContainer container = new ValidatorDefinitionsContainer();
+
+		IValidatorType[] validatorTypes = getValidatorTypes();
+		for (int i = 0; i < validatorTypes.length; ++i) {
+			IValidator[] Interpreters = validatorTypes[i].getValidators();
+			for (int j = 0; j < Interpreters.length; j++) {
+				IValidator install = Interpreters[j];
+				container.addValidator(install);
+			}
+		}
+		return container.getAsXML();
+	}
+
+	private static boolean addPersistedValidators(
+			ValidatorDefinitionsContainer interpreterDefs) throws IOException {
+
+		String validatorXMLString = getPreferences().getString(
+				PREF_VALIDATOR_XML);
+
+		if (validatorXMLString.length() > 0) {
+			try {
+				ByteArrayInputStream inputStream = new ByteArrayInputStream(
+						validatorXMLString.getBytes());
+				ValidatorDefinitionsContainer.parseXMLIntoContainer(
+						inputStream, interpreterDefs);
+				return false;
+			} catch (IOException ioe) {
+				// DLTKLaunchingPlugin.log(ioe);
+			}
+		}
+		return true;
+	}
+
+	public static boolean isContributedValidator(String id) {
+		getValidatorTypes();
+		return fgContributedValidators.contains(id);
+	}
+
+	public static Preferences getPreferences() {
+		return ValidatorsCore.getDefault().getPluginPreferences();
+	}
+
+	public static void savePreferences() {
+		ValidatorsCore.getDefault().savePluginPreferences();
+	}
+
+	/**
+	 * Perform Interpreter type and Interpreter install initialization. Does not
+	 * hold locks while performing change notification.
+	 * 
+	 * 
+	 */
+	private static void initializeValidators() {
+		ValidatorDefinitionsContainer validatorDefs = null;
+		boolean setPref = false;
+		synchronized (fgValidatorLock) {
+
+			try {
+				fgInitializingValidators = true;
+				// 1. load Validators type extensions
+				// initializeValidatorTypeExtensions();
+				try {
+					validatorDefs = new ValidatorDefinitionsContainer();
+
+					// 2. add persisted Validators
+					setPref = addPersistedValidators(validatorDefs);
+
+					// 4. load contributed Validators installs
+					// addValidatorExtensions(InterpreterDefs);
+
+				} catch (IOException e) {
+					// DLTKLaunchingPlugin.log(e);
+				}
+			} finally {
+				fgInitializingValidators = false;
+			}
+		}
+		if (validatorDefs != null) {
+			// notify of initial Interpreters for backwards compatibility
+			IValidatorType[] validatorTypes = null;
+			try {
+				validatorTypes = ValidatorManager.getAllValidatorTypes();
+			} catch (CoreException e1) {
+				return;
+			}
+			for (int i = 0; i < validatorTypes.length; i++) {
+				IValidatorType type = validatorTypes[i];
+				IValidator[] installs = type.getValidators();
+				if (installs != null) {
+					for (int j = 0; j < installs.length; j++) {
+						fireInterpreterAdded(installs[j]);
+					}
+				}
+			}
+
+			// save settings if required
+			if (setPref) {
+				try {
+					String xml = validatorDefs.getAsXML();
+					getPreferences().setValue(PREF_VALIDATOR_XML, xml);
+				} catch (ParserConfigurationException e) {
+					// DLTKLaunchingPlugin.log(e);
+				} catch (IOException e) {
+					// DLTKLaunchingPlugin.log(e);
+				} catch (TransformerException e) {
+					// DLTKLaunchingPlugin.log(e);
+				}
+
+			}
+
+		}
+	}
+
+	public static void addValidatorChangedListener(
+			IValidatorChangedListener listener) {
+		fgValidatorListeners.add(listener);
+	}
+
+	public static void removeValidatorInstallChangedListener(
+			IValidatorChangedListener listener) {
+		fgValidatorListeners.remove(listener);
+	}
+
+	public static void fireInterpreterChanged(IValidator validator) {
+		Object[] listeners = fgValidatorListeners.getListeners();
+		for (int i = 0; i < listeners.length; i++) {
+			IValidatorChangedListener listener = (IValidatorChangedListener) listeners[i];
+			listener.validatorChanged(validator);
+		}
+	}
+
+	public static void fireInterpreterAdded(IValidator Interpreter) {
+		if (!fgInitializingValidators) {
+			Object[] listeners = fgValidatorListeners.getListeners();
+			for (int i = 0; i < listeners.length; i++) {
+				IValidatorChangedListener listener = (IValidatorChangedListener) listeners[i];
+				listener.validatorAdded(Interpreter);
+			}
+		}
+	}
+
+	public static void fireInterpreterRemoved(IValidator Interpreter) {
+		Object[] listeners = fgValidatorListeners.getListeners();
+		for (int i = 0; i < listeners.length; i++) {
+			IValidatorChangedListener listener = (IValidatorChangedListener) listeners[i];
+			listener.validatorRemoved(Interpreter);
+		}
+	}
+
+	public static IValidatorType[] getPossibleValidatorTypes() {
+		List possible = new ArrayList();
+		IValidatorType[] vals = getValidatorTypes();
+		for (int i = 0; i < vals.length; i++) {
+			if (!vals[i].isBuiltin()) {
+				possible.add(vals[i]);
+			}
+		}
+		return (IValidatorType[]) possible.toArray(new IValidatorType[possible
+				.size()]);
+	}
+
+	public static IValidator[] getActiveValidators() {
+		List possible = new ArrayList();
+		IValidatorType[] vals = getValidatorTypes();
+		for (int i = 0; i < vals.length; i++) {
+			IValidator[] v = vals[i].getValidators();
+			for (int j = 0; j < v.length; j++) {
+				if (v[j].isActive() && v[j].isValidatorValid()) {
+					if (!possible.contains(v[j])) {
+						possible.add(v[j]);
+					}
+				}
+			}
+		}
+		return (IValidator[]) possible.toArray(new IValidator[possible.size()]);
+	}
+
+	public static void executeActiveValidatorsWithConsole(OutputStream stream,
+			List elements, List resources) {
+		IValidator[] activeValidators = getActiveValidators();
+		if (elements != null) {
+			for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
+				IModelElement el = (IModelElement) iterator.next();
+				if (el instanceof ISourceModule) {
+					ISourceModule module = (ISourceModule) el;
+					IDLTKLanguageToolkit toolkit = null;
+					try {
+						toolkit = DLTKLanguageManager
+								.getLanguageToolkit(module);
+					} catch (CoreException e) {
+						try {
+							if (stream != null) {
+								stream
+										.write(("Error to check element:" + module
+												.getPath()).getBytes());
+							}
+						} catch (IOException e1) {
+							e1.printStackTrace();
+						}
+						e.printStackTrace();
+						continue;
+					}
+					for (int i = 0; i < activeValidators.length; i++) {
+						IValidator v = activeValidators[i];
+						String nature = v.getValidatorType().getNature();
+						if (toolkit.getNatureID().equals(nature)
+								|| nature.equals("#")) {
+
+							IStatus e = v.validate(module, stream);
+							if (e.getSeverity() == IStatus.ERROR) {
+								if (stream != null) {
+									String message = e.getMessage();
+									try {
+										stream.write(message.getBytes());
+									} catch (IOException e1) {
+										e1.printStackTrace();
+									}
+								}
+							}
+						}
+					}
+				}
+
+			}
+		}
+		if (resources != null) {
+			for (Iterator iterator = resources.iterator(); iterator.hasNext();) {
+				IResource el = (IResource) iterator.next();
+				for (int i = 0; i < activeValidators.length; i++) {
+					IValidator v = activeValidators[i];
+					v.validate(el, stream);
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/CompositeId.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/CompositeId.java
new file mode 100644
index 0000000..2aa79ed
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/CompositeId.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.dltk.validators.internal.core;
+
+import java.util.ArrayList;
+
+/**
+ * Utility class for id's made of multiple Strings
+ */
+public class CompositeId {
+	private String[] fParts;
+	
+	public CompositeId(String[] parts) {
+		fParts= parts;
+	}
+	
+	public static CompositeId fromString(String idString) {
+		ArrayList parts= new ArrayList();
+		int commaIndex= idString.indexOf(',');
+		while (commaIndex > 0) {
+			int length= Integer.valueOf(idString.substring(0, commaIndex)).intValue();
+			String part= idString.substring(commaIndex+1, commaIndex+1+length);
+			parts.add(part);
+			idString= idString.substring(commaIndex+1+length);
+			commaIndex= idString.indexOf(',');
+		}
+		String[] result= (String[])parts.toArray(new String[parts.size()]);
+		return new CompositeId(result);
+	}
+	
+	public String toString() {
+		StringBuffer buf= new StringBuffer();
+		for (int i= 0; i < fParts.length; i++) {
+			buf.append(fParts[i].length());
+			buf.append(',');
+			buf.append(fParts[i]);
+		}
+		return buf.toString();
+	}
+	
+	public String get(int index) {
+		return fParts[index];
+	}
+	
+	public int getPartCount() {
+		return fParts.length;
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ListenerList.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ListenerList.java
new file mode 100644
index 0000000..07550dc
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ListenerList.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.dltk.validators.internal.core;
+
+
+/**
+ * Local version of org.eclipse.jface.util.ListenerList (modified)s
+ */
+public class ListenerList {
+	/**
+	 * The current number of listeners.
+	 * Maintains invariant: 0 <= fSize <= listeners.length.
+	 */
+	private int fSize;
+
+	/**
+	 * The list of listeners.  Initially <code>null</code> but initialized
+	 * to an array of size capacity the first time a listener is added.
+	 * Maintains invariant: listeners != null if and only if fSize != 0
+	 */
+	private Object[] fListeners= null;
+
+	/**
+	 * The empty array singleton instance, returned by getListeners()
+	 * when size == 0.
+	 */
+	private static final Object[] EmptyArray= new Object[0];
+
+	/**
+	 * Creates a listener list with the given initial capacity.
+	 *
+	 * @param capacity the number of listeners which this list can initially accept 
+	 *    without growing its internal representation; must be at least 1
+	 */
+	public ListenerList(int capacity) {
+		if (capacity < 1) {
+			throw new IllegalArgumentException();
+		}
+		fListeners= new Object[capacity];
+		fSize= 0;
+	}
+
+	/**
+	 * Adds a listener to the list.
+	 * Has no effect if an identical listener is already registered.
+	 *
+	 * @param listener a listener
+	 */
+	public synchronized void add(Object listener) {
+		if (listener == null) {
+			throw new IllegalArgumentException();
+		}
+		// check for duplicates using identity
+		for (int i= 0; i < fSize; ++i) {
+			if (fListeners[i] == listener) {
+				return;
+			}
+		}
+		// grow array if necessary
+		if (fSize == fListeners.length) {
+			Object[] temp= new Object[(fSize * 2) + 1];
+			System.arraycopy(fListeners, 0, temp, 0, fSize);
+			fListeners= temp;
+		}
+		fListeners[fSize++]= listener;
+	}
+
+	/**
+	 * Returns an array containing all the registered listeners.
+	 * The resulting array is unaffected by subsequent adds or removes.
+	 * If there are no listeners registered, the result is an empty array
+	 * singleton instance (no garbage is created).
+	 * Use this method when notifying listeners, so that any modifications
+	 * to the listener list during the notification will have no effect on the
+	 * notification itself.
+	 */
+	public synchronized Object[] getListeners() {
+		if (fSize == 0) {
+			return EmptyArray;
+		}
+		Object[] result= new Object[fSize];
+		System.arraycopy(fListeners, 0, result, 0, fSize);
+		return result;
+	}
+
+	/**
+	 * Removes a listener from the list.
+	 * Has no effect if an identical listener was not already registered.
+	 *
+	 * @param listener a listener
+	 */
+	public synchronized void remove(Object listener) {
+		if (listener == null) {
+			throw new IllegalArgumentException();
+		}
+
+		for (int i= 0; i < fSize; ++i) {
+			if (fListeners[i] == listener) {
+				if (--fSize == 0) {
+					fListeners= new Object[1];
+				} else {
+					if (i < fSize) {
+						fListeners[i]= fListeners[fSize];
+					}
+					fListeners[fSize]= null;
+				}
+				return;
+			}
+		}
+	}
+
+	/**
+	 * Removes all the listeners from the list.
+	 */
+	public void removeAll() {
+		fListeners= new Object[0];
+		fSize= 0;
+	}
+
+	/**
+	 * Returns the number of registered listeners
+	 *
+	 * @return the number of registered listeners
+	 */
+	public int size() {
+		return fSize;
+	}
+}
+
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorBuilder.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorBuilder.java
new file mode 100644
index 0000000..3d008e1
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorBuilder.java
@@ -0,0 +1,30 @@
+package org.eclipse.dltk.validators.internal.core;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.dltk.core.IDLTKProject;
+import org.eclipse.dltk.core.builder.IScriptBuilder;
+import org.eclipse.dltk.validators.core.ValidatorRuntime;
+
+public class ValidatorBuilder implements IScriptBuilder {
+
+	public IStatus[] buildModelElements(IDLTKProject project, List elements,
+			IProgressMonitor monitor) {
+		ValidatorRuntime.executeActiveValidatorsWithConsole(null, elements, null);
+		return null;
+	}
+
+	public IStatus[] buildResources(IDLTKProject project, List resources,
+			IProgressMonitor monitor) {
+		ValidatorRuntime.executeActiveValidatorsWithConsole(null, null, resources);
+		return null;
+	}
+
+	public List getDependencies(IDLTKProject project, List resources) {
+		//We don't provide dependencies here.
+		return null;
+	}
+
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorDefinitionsContainer.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorDefinitionsContainer.java
new file mode 100644
index 0000000..392ed8a
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorDefinitionsContainer.java
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.dltk.validators.internal.core;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.validators.core.IValidator;
+import org.eclipse.dltk.validators.core.IValidatorType;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class ValidatorDefinitionsContainer {
+
+	private Map fValidatorTypeToValidatorMap;
+
+	private List fValidatorList;
+
+	private List fInvalidValidatorList;
+
+	public ValidatorDefinitionsContainer() {
+		fValidatorTypeToValidatorMap = new HashMap(10);
+		fInvalidValidatorList = new ArrayList(10);
+		fValidatorList = new ArrayList(10);
+	}
+
+	public void addValidator(IValidator validator) {
+		if (!fValidatorList.contains(validator)) {
+			IValidatorType InterpreterInstallType = validator
+					.getValidatorType();
+			List validatorList = (List) fValidatorTypeToValidatorMap
+					.get(InterpreterInstallType);
+			if (validatorList == null) {
+				validatorList = new ArrayList(3);
+				fValidatorTypeToValidatorMap.put(InterpreterInstallType,
+						validatorList);
+			}
+			validatorList.add(validator);
+			if (!validator.isValidatorValid()) {
+				fInvalidValidatorList.add(validator);
+			}
+			fValidatorList.add(validator);
+		}
+	}
+
+	public void addValidatorList(List validatorList) {
+		Iterator iterator = validatorList.iterator();
+		while (iterator.hasNext()) {
+			IValidator validator = (IValidator) iterator.next();
+			addValidator(validator);
+		}
+	}
+
+	public Map getValidateTypeToValidatorsMap() {
+		return fValidatorTypeToValidatorMap;
+	}
+
+	public List getValidatorList() {
+		return fValidatorList;
+	}
+
+	public List getValidatorList(String nature) {
+		List res = new ArrayList(fValidatorList.size());
+		for (Iterator iter = fValidatorList.iterator(); iter.hasNext();) {
+			IValidator validator = (IValidator) iter.next();
+			String sharp = "#";
+			String nature2 = validator.getValidatorType().getNature();
+			if (nature2.equals(nature) || nature2.equals(sharp)) {
+				res.add(validator);
+			}
+		}
+		return res;
+	}
+
+	public List getValidValidatorsList() {
+		List validators = getValidatorList();
+		List resultList = new ArrayList(validators.size());
+		resultList.addAll(validators);
+		resultList.removeAll(fInvalidValidatorList);
+		return resultList;
+	}
+
+	public List getValidValidatorsList(String nature) {
+		List Interpreters = getValidatorList(nature);
+		List resultList = new ArrayList(Interpreters.size());
+		resultList.addAll(Interpreters);
+		resultList.removeAll(fInvalidValidatorList);
+		return resultList;
+	}
+
+	public String getAsXML() throws ParserConfigurationException, IOException,
+			TransformerException {
+
+		// Create the Document and the top-level node
+		Document doc = ValidatorsCore.getDocument();
+		Element config = doc.createElement("validatorSettings"); //$NON-NLS-1$
+		doc.appendChild(config);
+
+		// Create a node for each install type represented in this container
+		Set validatorTypeSet = getValidateTypeToValidatorsMap().keySet();
+		Iterator keyIterator = validatorTypeSet.iterator();
+		while (keyIterator.hasNext()) {
+			IValidatorType validatorType = (IValidatorType) keyIterator.next();
+			if (validatorType.isConfigurable()) {
+				Element valiatorTypeElement = validatorTypeAsElement(doc,
+						validatorType);
+				config.appendChild(valiatorTypeElement);
+			}
+		}
+
+		// Serialize the Document and return the resulting String
+		return ValidatorsCore.serializeDocument(doc);
+	}
+
+	private Element validatorTypeAsElement(Document doc,
+			IValidatorType validatorType) {
+
+		// Create a node for the Interpreter type and set its 'id' attribute
+		Element element = doc.createElement("validatorType"); //$NON-NLS-1$
+		element.setAttribute("id", validatorType.getID()); //$NON-NLS-1$
+
+		// For each Interpreter of the specified type, create a subordinate node
+		// for it
+		List validatorList = (List) getValidateTypeToValidatorsMap().get(
+				validatorType);
+		Iterator validatorIterator = validatorList.iterator();
+		while (validatorIterator.hasNext()) {
+			IValidator validator = (IValidator) validatorIterator.next();
+			Element validatorElement = validatorAsElement(doc, validator);
+			element.appendChild(validatorElement);
+		}
+
+		return element;
+	}
+
+	private Element validatorAsElement(Document doc, IValidator validator) {
+
+		// Create the node for the Interpreter and set its 'id' & 'name'
+		// attributes
+		Element element = doc.createElement("validator"); //$NON-NLS-1$
+		element.setAttribute("id", validator.getID()); //$NON-NLS-1$
+		element.setAttribute("name", validator.getName()); //$NON-NLS-1$
+		element.setAttribute("active", Boolean.toString(validator.isActive()));
+
+		validator.storeTo(doc, element);
+
+		return element;
+	}
+
+	public static ValidatorDefinitionsContainer parseXMLIntoContainer(
+			InputStream inputStream) throws IOException {
+		ValidatorDefinitionsContainer container = new ValidatorDefinitionsContainer();
+		parseXMLIntoContainer(inputStream, container);
+		return container;
+	}
+
+	public static void parseXMLIntoContainer(InputStream inputStream,
+			ValidatorDefinitionsContainer container) throws IOException {
+
+		// Wrapper the stream for efficient parsing
+		InputStream stream = new BufferedInputStream(inputStream);
+
+		// Do the parsing and obtain the top-level node
+		Element config = null;
+		try {
+			DocumentBuilder parser = DocumentBuilderFactory.newInstance()
+					.newDocumentBuilder();
+			parser.setErrorHandler(new DefaultHandler());
+			config = parser.parse(new InputSource(stream)).getDocumentElement();
+		} catch (SAXException e) {
+			throw new IOException(ValidatorMessages.ValidatorRuntime_badFormat);
+		} catch (ParserConfigurationException e) {
+			stream.close();
+			throw new IOException(ValidatorMessages.ValidatorRuntime_badFormat);
+		} finally {
+			stream.close();
+		}
+
+		// If the top-level node wasn't what we expected, bail out
+		if (!config.getNodeName().equalsIgnoreCase("validatorSettings")) { //$NON-NLS-1$
+			throw new IOException(ValidatorMessages.ValidatorRuntime_badFormat);
+		}
+
+		// Traverse the parsed structure and populate the InterpreterType to
+		// Interpreter Map
+		NodeList list = config.getChildNodes();
+		int length = list.getLength();
+		for (int i = 0; i < length; ++i) {
+			Node node = list.item(i);
+			short type = node.getNodeType();
+			if (type == Node.ELEMENT_NODE) {
+				Element validatorTypeElement = (Element) node;
+				if (validatorTypeElement.getNodeName().equalsIgnoreCase(
+						"validatorType")) { //$NON-NLS-1$
+					populateValidatorTypes(validatorTypeElement, container);
+				}
+			}
+		}
+	}
+
+	/**
+	 * For the specified Interpreter type node, parse all subordinate
+	 * Interpreter definitions and add them to the specified container.
+	 */
+	private static void populateValidatorTypes(Element validatorTypeElement,
+			ValidatorDefinitionsContainer container) {
+
+		// Retrieve the 'id' attribute and the corresponding Interpreter type
+		// object
+		String id = validatorTypeElement.getAttribute("id"); //$NON-NLS-1$
+		IValidatorType validatorType = ValidatorManager
+				.getValidatorTypeFromID(id);
+		if (validatorType != null) {
+
+			// For each Interpreter child node, populate the container with a
+			// subordinate node
+			NodeList validatorNodeList = validatorTypeElement.getChildNodes();
+			for (int i = 0; i < validatorNodeList.getLength(); ++i) {
+				Node InterpreterNode = validatorNodeList.item(i);
+				short type = InterpreterNode.getNodeType();
+				if (type == Node.ELEMENT_NODE) {
+					Element InterpreterElement = (Element) InterpreterNode;
+					if (InterpreterElement.getNodeName().equalsIgnoreCase(
+							"validator")) { //$NON-NLS-1$
+						populateValidatorForType(validatorType,
+								InterpreterElement, container);
+					}
+				}
+			}
+		} else {
+			if (DLTKCore.DEBUG) {
+				System.err.println("Interpreter type element with unknown id."); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * Parse the specified Interpreter node, create a InterpreterStandin for it,
+	 * and add this to the specified container.
+	 */
+	private static void populateValidatorForType(
+			IValidatorType interpreterType, Element validatorElement,
+			ValidatorDefinitionsContainer container) {
+		String id = validatorElement.getAttribute("id"); //$NON-NLS-1$
+		String name = validatorElement.getAttribute("name"); //$NON-NLS-1$
+		boolean active = Boolean.parseBoolean(validatorElement.getAttribute("active"));
+		if (id != null) {
+			try {
+				IValidator validator = interpreterType
+				.createValidatorFrom(id, validatorElement);
+				validator.setName(name);
+				validator.setActive(active);
+				container.addValidator(validator);
+			}
+			catch(IOException e ) {
+				DLTKCore.getDefault().getLog().log(new Status(0,ValidatorsCore.PLUGIN_ID, "Failed to load validator from XML..."));
+			}
+		} else {
+			if (DLTKCore.DEBUG) {
+				System.err
+						.println("id attribute missing from Interpreter element specification."); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * Removes the Interpreter from this container.
+	 * 
+	 * @param Interpreter
+	 *            Interpreter intall
+	 */
+	public void removeValidator(IValidator Interpreter) {
+		fValidatorList.remove(Interpreter);
+		fInvalidValidatorList.remove(Interpreter);
+		List list = (List) fValidatorTypeToValidatorMap.get(Interpreter
+				.getValidatorType());
+		if (list != null) {
+			list.remove(Interpreter);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorManager.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorManager.java
new file mode 100644
index 0000000..4b8b3ed
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorManager.java
@@ -0,0 +1,131 @@
+package org.eclipse.dltk.validators.internal.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.dltk.validators.core.IValidatorType;
+
+public class ValidatorManager {
+
+	private final static String LANGUAGE_EXTPOINT = ValidatorsCore.PLUGIN_ID
+			+ ".validator";
+
+	private final static String NATURE_ATTR = "nature";
+
+	// Contains list of validators for selected nature.
+	private static Map validators;
+	
+	private static Map idToValidatorType = null;
+	
+	public static IValidatorType getValidatorTypeFromID( String id ) {
+		if( idToValidatorType == null ) {
+			idToValidatorType = new HashMap();
+			try {
+				IValidatorType[] allValidatorTypes = getAllValidatorTypes();
+				for (int i = 0; i < allValidatorTypes.length; i++) {
+					idToValidatorType.put(allValidatorTypes[i].getID(), allValidatorTypes[i] );
+				}
+			} catch (CoreException e) {
+				idToValidatorType = null;
+				return null;
+			}
+		}
+		return (IValidatorType)idToValidatorType.get(id);
+	}
+
+	private static void initialize() {
+		if (validators != null) {
+			return;
+		}
+
+		validators = new HashMap(5);
+		IConfigurationElement[] cfg = Platform.getExtensionRegistry()
+				.getConfigurationElementsFor(LANGUAGE_EXTPOINT);
+
+		for (int i = 0; i < cfg.length; i++) {
+			String nature = cfg[i].getAttribute(NATURE_ATTR);
+			if (validators.get(nature) != null) {
+				List elements = (List)validators.get(nature);
+				elements.add(cfg[i]);
+				continue;
+			}
+			List elements = new ArrayList();
+			elements.add( cfg[i] );
+			validators.put( nature, elements );
+		}
+	}
+	/**
+	 * Return merged with all elements with nature #
+	 * @param natureId
+	 * @return
+	 * @throws CoreException
+	 */
+	public static IValidatorType[] getValidators(String natureId)
+			throws CoreException {
+		initialize();
+
+		List results = new ArrayList();
+		processNature(natureId, results);
+		// Add from # nature.
+		processNature( "#", results );
+		return (IValidatorType[])results.toArray(new IValidatorType[results.size()]);
+	}
+	private static void processNature(String natureId, List results)
+			throws CoreException {
+		Object ext = validators.get(natureId);
+		
+		if (ext != null) {
+			if( ext instanceof IValidatorType[]) {
+				IValidatorType[] b = (IValidatorType[])ext;
+				for (int i = 0; i < b.length; i++) {
+					if( !results.contains(b[i])) {
+						results.add(b[i]);
+					}
+				}
+			}
+			else if ( ext instanceof List ) {
+				List elements = (List)ext;
+				IValidatorType[] result = new IValidatorType[elements.size()];
+				for( int i = 0; i < elements.size(); ++i ) {
+					Object e = elements.get(i);
+					if( e instanceof IValidatorType ) {
+						result[i] = (IValidatorType)e;
+					}
+					else {
+						IConfigurationElement cfg = (IConfigurationElement) e;
+						IValidatorType builder = (IValidatorType) cfg
+								.createExecutableExtension("class");
+						result[i] = builder;
+					}
+				}
+				validators.put(natureId, result) ;
+				for (int i = 0; i < result.length; i++) {
+					if( !results.contains(result[i])) {
+						results.add(result[i]);
+					}
+				}
+			}
+		}
+	}
+
+	public static IValidatorType[] getAllValidatorTypes() throws CoreException {
+		
+		initialize();
+		List result = new ArrayList();
+		Iterator iterator = validators.keySet().iterator();
+		while( iterator.hasNext() ) {
+			String nature = (String)iterator.next();
+			IValidatorType[] b = getValidators(nature);
+			for( int i = 0; i < b.length; ++i ) {
+				result.add(b[i]);
+			}
+		}
+		return (IValidatorType[])result.toArray(new IValidatorType[result.size()]);
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorMessages.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorMessages.java
new file mode 100644
index 0000000..c92a595
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorMessages.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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 - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.validators.internal.core;
+
+import org.eclipse.osgi.util.NLS;
+
+public class ValidatorMessages extends NLS {
+	private static final String BUNDLE_NAME = ValidatorMessages.class.getName();//$NON-NLS-1$
+	public static String ValidatorRuntime_badFormat;
+	
+
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, ValidatorMessages.class);
+	}
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorMessages.properties b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorMessages.properties
new file mode 100644
index 0000000..91c2aeb
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorMessages.properties
@@ -0,0 +1 @@
+ValidatorRuntime_badFormat = Bad format
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorUtils.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorUtils.java
new file mode 100644
index 0000000..f3ba8d3
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorUtils.java
@@ -0,0 +1,142 @@
+package org.eclipse.dltk.validators.internal.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.DLTKLanguageManager;
+import org.eclipse.dltk.core.IDLTKProject;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.IModelElementVisitor;
+import org.eclipse.dltk.core.IParent;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.core.ModelException;
+import org.eclipse.dltk.core.search.IDLTKSearchScope;
+import org.eclipse.dltk.core.search.SearchEngine;
+import org.eclipse.dltk.internal.core.BuiltinProjectFragment;
+import org.eclipse.dltk.internal.core.BuiltinSourceModule;
+import org.eclipse.dltk.internal.core.ExternalProjectFragment;
+import org.eclipse.dltk.internal.core.ExternalSourceModule;
+import org.eclipse.dltk.internal.core.util.HandleFactory;
+
+public class ValidatorUtils {
+	private static class ResourceVisitor implements IResourceVisitor {
+		private List resources;
+
+		public ResourceVisitor(List resources) {
+			this.resources = resources;
+		}
+
+		public boolean visit(IResource resource) {
+			if (!this.resources.contains(resource)
+					&& resource.getType() == IResource.FILE) {
+				resources.add(resource);
+				return false;
+			}
+			return true;
+		}
+	}
+
+	private static class SourceModuleVisitor implements IModelElementVisitor {
+		private List elements;
+
+		public SourceModuleVisitor(List elements) {
+			this.elements = elements;
+		}
+
+		/**
+		 * Visit only external source modules, witch we aren't builded yet.
+		 */
+		public boolean visit(IModelElement element) {
+			if (element.getElementType() == IModelElement.PROJECT_FRAGMENT) {
+				if ((element instanceof ExternalProjectFragment)
+						|| (element instanceof BuiltinProjectFragment)) {
+					return false;
+				}
+			}
+			if (element.getElementType() == IModelElement.SOURCE_MODULE
+					&& !(element instanceof ExternalSourceModule || element instanceof BuiltinSourceModule)) {
+				if (!elements.contains(element)) {
+					elements.add(element);
+				}
+				return false; // do not enter into source module content.
+			}
+			return true;
+		}
+	}
+	public static void processResourcesToElements(Object o, final List elements, final List resources ) {
+		if( o instanceof IResource ) {
+			List els = new ArrayList();
+			ResourceVisitor visitor = new ResourceVisitor(els);
+			try {
+				((IResource)o).accept(visitor);
+			} catch (CoreException e) {
+				e.printStackTrace();
+			}
+			for (int i = 0; i < els.size(); i++) {
+				Object eo = convertResourceToModelElement(els.get(i));
+				if( eo != null ) {
+					if( eo instanceof IModelElement && !elements.contains(eo) ) {
+						elements.add(eo);
+					}
+					else if( eo instanceof IResource && !resources.contains(eo) ) {
+						resources.add(eo);
+					}
+				}
+			}
+		}
+		else if( o instanceof IModelElement ) {
+			if( o instanceof IParent ) {
+				SourceModuleVisitor visitor = new SourceModuleVisitor(elements);
+				try {
+					((IModelElement)o).accept(visitor);
+				} catch (ModelException e) {
+					e.printStackTrace();
+				}
+			}
+			else if ( !(o instanceof ISourceModule )) {
+				ISourceModule module = (ISourceModule)((IModelElement)o).getAncestor(IModelElement.SOURCE_MODULE);
+				if( elements.contains(module)) {
+					elements.add(module);
+				}
+			}
+			else if( o instanceof ISourceModule) {
+				if( !elements.contains(o)) {
+					elements.add(o);
+				}
+			}
+		}
+	}
+	private static HandleFactory factory = new HandleFactory();
+	private static Object convertResourceToModelElement( Object o ) {
+		if( o instanceof IModelElement ) {
+			return o;
+		}
+		if( !(o instanceof IResource)) {
+			return null;
+		}
+		IResource res = (IResource)o;
+		IProject project = res.getProject();
+		if( !DLTKLanguageManager.hasScriptNature(project)) {
+			return null; // Lets pass not script projects. 
+		}
+		IDLTKProject scriptProject = DLTKCore.create(project);
+		IDLTKSearchScope scope = SearchEngine
+		.createSearchScope(new IModelElement[] { scriptProject });
+		
+		IModelElement element = factory.createOpenable(res.getFullPath()
+				.toString(), scope);
+		if (element != null
+				&& element.getElementType() == IModelElement.SOURCE_MODULE
+				&& element.exists()) {
+//			elements.add(element);
+			return element;
+		} else {
+			return res;
+		}
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorsCore.java b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorsCore.java
new file mode 100644
index 0000000..4e0dded
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.core/src/org/eclipse/dltk/validators/internal/core/ValidatorsCore.java
@@ -0,0 +1,202 @@
+package org.eclipse.dltk.validators.internal.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
+import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+import org.eclipse.dltk.validators.core.IValidator;
+import org.eclipse.dltk.validators.core.IValidatorChangedListener;
+import org.eclipse.dltk.validators.core.ValidatorRuntime;
+import org.osgi.framework.BundleContext;
+import org.w3c.dom.Document;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class ValidatorsCore extends Plugin implements IPropertyChangeListener {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.dltk.validators.core";
+
+	// The shared instance
+	private static ValidatorsCore plugin;
+	
+	private boolean fIgnoreValidatorDefPropertyChangeEvents = false;
+
+	private boolean fBatchingChanges;
+	
+	private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+	
+	private String fOldInterpreterPrefString = EMPTY_STRING;
+
+	/**
+	 * The constructor
+	 */
+	public ValidatorsCore() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+		
+		getPluginPreferences().addPropertyChangeListener(this);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.Plugin#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 ValidatorsCore getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * Returns a Document that can be used to build a DOM tree
+	 * 
+	 * @return the Document
+	 * @throws ParserConfigurationException
+	 *             if an exception occurs creating the document builder
+	 */
+	public static Document getDocument() throws ParserConfigurationException {
+		DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+		DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
+		Document doc = docBuilder.newDocument();
+		return doc;
+	}
+
+	public static String serializeDocument(Document doc) throws IOException,
+			TransformerException {
+		ByteArrayOutputStream s = new ByteArrayOutputStream();
+
+		TransformerFactory factory = TransformerFactory.newInstance();
+		Transformer transformer = factory.newTransformer();
+		transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+		transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+
+		DOMSource source = new DOMSource(doc);
+		StreamResult outputTarget = new StreamResult(s);
+		transformer.transform(source, outputTarget);
+
+		return s.toString("UTF8"); //$NON-NLS-1$			
+	}
+	public void setIgnoreValidatorDefPropertyChangeEvents(boolean ignore) {
+		fIgnoreValidatorDefPropertyChangeEvents = ignore;
+	}
+
+	public boolean isIgnoreValidatorDefPropertyChangeEvents() {
+		return fIgnoreValidatorDefPropertyChangeEvents;
+	}
+
+	public void propertyChange(PropertyChangeEvent event) {
+		String property = event.getProperty();
+		if (property.equals(ValidatorRuntime.PREF_VALIDATOR_XML)) {
+			if (!isIgnoreValidatorDefPropertyChangeEvents()) {
+				processValidatorPrefsChanged((String) event.getOldValue(),
+						(String) event.getNewValue());
+			}
+		}
+	}
+	private ValidatorDefinitionsContainer getValidatorDefinitions(String xml) {
+		if (xml.length() > 0) {
+			try {
+				ByteArrayInputStream stream = new ByteArrayInputStream(xml
+						.getBytes("UTF8")); //$NON-NLS-1$
+				return ValidatorDefinitionsContainer
+						.parseXMLIntoContainer(stream);
+			} catch (IOException e) {
+				ValidatorsCore.getDefault().getLog().log(new Status( 0, ValidatorsCore.PLUGIN_ID, "Exception", e ));
+			}
+		}
+		return new ValidatorDefinitionsContainer();
+	}
+	protected void processValidatorPrefsChanged(String oldValue,
+			String newValue) {
+
+		// batch changes
+		fBatchingChanges = true;
+		try {
+
+			String oldPrefString;
+			String newPrefString;
+
+			// If empty new value, save the old value and wait for 2nd
+			// propertyChange notification
+			if (newValue == null || newValue.equals(EMPTY_STRING)) {
+				fOldInterpreterPrefString = oldValue;
+				return;
+			}
+			// An empty old value signals the second notification in the import
+			// preferences
+			// sequence. Now that we have both old & new prefs, we can parse and
+			// compare them.
+			else if (oldValue == null || oldValue.equals(EMPTY_STRING)) {
+				oldPrefString = fOldInterpreterPrefString;
+				newPrefString = newValue;
+			}
+			// If both old & new values are present, this is a normal user
+			// change
+			else {
+				oldPrefString = oldValue;
+				newPrefString = newValue;
+			}
+
+			// Generate the previous Interpreters
+			ValidatorDefinitionsContainer oldResults = getValidatorDefinitions(oldPrefString);
+
+			// Generate the current
+			ValidatorDefinitionsContainer newResults = getValidatorDefinitions(newPrefString);
+
+			// Determine the deteled Interpreters
+			List deleted = oldResults.getValidatorList();
+			List current = newResults.getValidatorList();
+			deleted.removeAll(current);
+
+			// Dispose deleted Interpreters. The 'disposeInterpreterInstall'
+			// method fires notification of the
+			// deletion.
+			Iterator deletedIterator = deleted.iterator();
+			while (deletedIterator.hasNext()) {
+				IValidator deletedValidatorStandin = (IValidator) deletedIterator
+						.next();
+				deletedValidatorStandin.getValidatorType()
+						.disposeValidator(
+								deletedValidatorStandin.getID());
+			}
+		} finally {
+			// stop batch changes
+			fBatchingChanges = false;
+		}
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/.classpath b/core/plugins/org.eclipse.dltk.validators.ui/.classpath
new file mode 100644
index 0000000..751c8f2
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/.cvsignore b/core/plugins/org.eclipse.dltk.validators.ui/.cvsignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/.project b/core/plugins/org.eclipse.dltk.validators.ui/.project
new file mode 100644
index 0000000..08b820c
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.dltk.validators.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/core/plugins/org.eclipse.dltk.validators.ui/META-INF/MANIFEST.MF b/core/plugins/org.eclipse.dltk.validators.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..0b6c783
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: DLTK Validators UI
+Bundle-SymbolicName: org.eclipse.dltk.validators.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.dltk.validators.internal.ui.ValidatorsUI
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.dltk.validators.core,
+ org.eclipse.dltk.ui,
+ org.eclipse.dltk.core,
+ org.eclipse.core.resources,
+ org.eclipse.ui.console
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.dltk.validators
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/build.properties b/core/plugins/org.eclipse.dltk.validators.ui/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/plugin.xml b/core/plugins/org.eclipse.dltk.validators.ui/plugin.xml
new file mode 100644
index 0000000..4f6b088
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/plugin.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension-point id="validatorConfigPage" name="validatorConfigPage" schema="schema/validatorConfigPage.exsd"/>
+   <extension-point id="validatorConsoleTracker" name="validatorConsoleTracker" schema="schema/validatorConsoleTracker.exsd"/>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            class="org.eclipse.dltk.validators.internal.ui.ValidatorPreferencePage"
+            id="org.eclipse.dltk.validators.ui.validators"
+            name="DLTK Validators">
+      </page>
+   </extension>
+   <extension
+         point="org.eclipse.ui.popupMenus">
+      <objectContribution
+            adaptable="false"
+            id="org.eclipse.dltk.validators.ui.contribution"
+            nameFilter="*"
+            objectClass="org.eclipse.dltk.core.IModelElement">
+         <menu
+               id="org.eclipse.dltk.validators.ui.menu"
+               label="DLTK Validators"
+               path="additions">
+            <separator
+                  name="top">
+            </separator>
+         </menu>
+         <action
+               class="org.eclipse.dltk.validators.internal.ui.popup.actions.ValidatуSelectionWithConsoleAction"
+               id="org.eclipse.dltk.validators.ui.newAction"
+               label="Validate selection with console"
+               menubarPath="org.eclipse.dltk.validators.ui.menu/top"
+               >
+         </action>
+      </objectContribution>
+   </extension>
+
+</plugin>
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/schema/validatorConfigPage.exsd b/core/plugins/org.eclipse.dltk.validators.ui/schema/validatorConfigPage.exsd
new file mode 100644
index 0000000..db9646f
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/schema/validatorConfigPage.exsd
@@ -0,0 +1,112 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.dltk.validators.ui">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.dltk.validators.ui" id="validatorConfigPage" name="validatorConfigPage"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="validatorConfigPage"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="validatorConfigPage">
+      <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.dltk.validators.ValidatorConfigurationPage"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/schema/validatorConsoleTracker.exsd b/core/plugins/org.eclipse.dltk.validators.ui/schema/validatorConsoleTracker.exsd
new file mode 100644
index 0000000..e595b7c
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/schema/validatorConsoleTracker.exsd
@@ -0,0 +1,105 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.dltk.validators.ui">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.dltk.validators.ui" id="validatorConsoleTracker" name="validatorConsoleTracker"/>
+      </appInfo>
+      <documentation>
+         [Enter description of this extension point.]
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="validatorConsoleTracker"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="validatorConsoleTracker">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.ui.console.IPatternMatchListener"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/splash.bmp b/core/plugins/org.eclipse.dltk.validators.ui/splash.bmp
new file mode 100644
index 0000000..99ea60d
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/splash.bmp
Binary files differ
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/ValidatorConfigurationPage.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/ValidatorConfigurationPage.java
new file mode 100644
index 0000000..5b9922b
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/ValidatorConfigurationPage.java
@@ -0,0 +1,16 @@
+package org.eclipse.dltk.validators;
+
+import org.eclipse.dltk.validators.core.IValidator;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class ValidatorConfigurationPage {
+	protected IValidator validator;
+	public void setValidator(IValidator validator) {
+		this.validator = validator;
+	}
+	public IValidator getValidator() {
+		return this.validator;
+	}
+	public abstract void applyChanges();
+	public abstract void createControl( Composite parent, int columns );
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/AddValidatorDialog.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/AddValidatorDialog.java
new file mode 100644
index 0000000..c2a5613
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/AddValidatorDialog.java
@@ -0,0 +1,307 @@
+package org.eclipse.dltk.validators.internal.ui;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.dltk.internal.ui.dialogs.StatusInfo;
+import org.eclipse.dltk.internal.ui.wizards.dialogfields.ComboDialogField;
+import org.eclipse.dltk.internal.ui.wizards.dialogfields.DialogField;
+import org.eclipse.dltk.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import org.eclipse.dltk.internal.ui.wizards.dialogfields.StringDialogField;
+import org.eclipse.dltk.validators.ValidatorConfigurationPage;
+import org.eclipse.dltk.validators.core.IValidator;
+import org.eclipse.dltk.validators.core.IValidatorType;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.StatusDialog;
+import org.eclipse.swt.SWT;
+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.Shell;
+
+public class AddValidatorDialog extends StatusDialog {
+	
+	private IAddValidatorDialogRequestor fRequestor;
+	
+	private IValidatorType[] fValidatorTypes;
+	
+	private IValidatorType fSelectedValidatorType;
+	
+	private ComboDialogField fValidatorTypeCombo;
+	
+	private IValidator fEditedValidator;
+	
+	private StringDialogField fValidatorName;
+
+	private IStatus[] fStati;
+	private int fPrevIndex = -1;
+	
+	ValidatorConfigurationPage fConfigurationPage;
+	
+		
+	public AddValidatorDialog(IAddValidatorDialogRequestor requestor, Shell shell,
+			IValidatorType[] validatorTypes, IValidator editedValidator) {
+		super(shell);
+		setShellStyle(getShellStyle() | SWT.RESIZE);
+		fRequestor= requestor;
+		fStati= new IStatus[5];
+		for (int i= 0; i < fStati.length; i++) {
+			fStati[i]= new StatusInfo();
+		}
+		
+		fValidatorTypes= validatorTypes;
+		fSelectedValidatorType= editedValidator != null ? editedValidator.getValidatorType() : validatorTypes[0];
+		
+		fEditedValidator = editedValidator;
+	}
+	
+	/**
+	 * @see Windows#configureShell
+	 */
+	protected void configureShell(Shell newShell) {
+		super.configureShell(newShell);
+		//PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, IScriptDebugHelpContextIds.EDIT_ValidatorEnvironment_DIALOG);
+	}		
+	
+	protected void createDialogFields() {
+		fValidatorTypeCombo= new ComboDialogField(SWT.READ_ONLY);
+		fValidatorTypeCombo.setLabelText(ValidatorMessages.addValidatorDialog_ValidatorEnvironmentType); 
+		fValidatorTypeCombo.setItems(getValidatorTypeNames());
+	
+		fValidatorName= new StringDialogField();
+		fValidatorName.setLabelText(ValidatorMessages.addValidatorDialog_ValidatorEnvironmentName); 
+	}
+	
+	protected void createFieldListeners() {
+		
+		fValidatorTypeCombo.setDialogFieldListener(new IDialogFieldListener() {
+			public void dialogFieldChanged(DialogField field) {
+				updateValidatorType();
+			}
+		});
+		
+		fValidatorName.setDialogFieldListener(new IDialogFieldListener() {
+			public void dialogFieldChanged(DialogField field) {
+				setValidatorNameStatus(validateValidatorName());
+				updateStatusLine();
+			}
+		});
+	}
+	
+	protected String getValidatorName() {
+		return fValidatorName.getText();
+	}
+		
+	protected Control createDialogArea(Composite ancestor) {
+		createDialogFields();
+		Composite parent = (Composite)super.createDialogArea(ancestor);
+		((GridLayout)parent.getLayout()).numColumns= 3;
+		
+		fValidatorTypeCombo.doFillIntoGrid(parent, 3);
+		((GridData)fValidatorTypeCombo.getComboControl(null).getLayoutData()).widthHint= convertWidthInCharsToPixels(50);
+		
+		fValidatorName.doFillIntoGrid(parent, 3);
+		
+		if( this.fEditedValidator != null ) {
+			fValidatorName.setEnabled(!this.fEditedValidator.getValidatorType().isBuiltin());
+			if( this.fEditedValidator.getName().equals(this.fEditedValidator.getValidatorType().getName())) {
+					
+			}
+			try {
+				fConfigurationPage = ValidatorConfigurationPageManager.getConfigurationPage(fEditedValidator.getValidatorType().getID());
+			} catch (CoreException e) {
+				e.printStackTrace();
+			}
+			if( fConfigurationPage != null ) {
+				this.fConfigurationPage.setValidator(this.fEditedValidator);
+				this.fConfigurationPage.createControl(parent, 3);
+			}
+		}
+		
+		initializeFields();
+		createFieldListeners();
+		applyDialogFont(parent);
+		return parent;
+	}
+	
+	private void updateValidatorType() {
+		int selIndex= fValidatorTypeCombo.getSelectionIndex();
+		if (selIndex == fPrevIndex) {
+			return;
+		}
+		fPrevIndex = selIndex;
+		if (selIndex >= 0 && selIndex < fValidatorTypes.length) {
+			fSelectedValidatorType= fValidatorTypes[selIndex];
+		}
+//		setValidatorLocationStatus(validateValidatorLocation());
+	
+		updateStatusLine();
+	}	
+	
+	public void create() {
+		super.create();
+		fValidatorName.setFocus();
+		selectValidatorType();  
+	}
+	
+	private String[] getValidatorTypeNames() {
+		String[] names=  new String[fValidatorTypes.length];
+		for (int i= 0; i < fValidatorTypes.length; i++) {
+			names[i]= fValidatorTypes[i].getName();
+		}
+		return names;
+	}
+	
+	private void selectValidatorType() {
+		for (int i= 0; i < fValidatorTypes.length; i++) {
+			if (fSelectedValidatorType == fValidatorTypes[i]) {
+				fValidatorTypeCombo.selectItem(i);
+				return;
+			}
+		}
+	}
+
+	private void initializeFields() {
+		fValidatorTypeCombo.setItems(getValidatorTypeNames());
+		if (fEditedValidator == null) {
+			fValidatorName.setText(""); //$NON-NLS-1$
+			
+		} else {
+			fValidatorTypeCombo.setEnabled(false);
+			fValidatorName.setText(fEditedValidator.getName());
+		}
+		setValidatorNameStatus(validateValidatorName());
+		updateStatusLine();
+	}
+
+
+	private IValidatorType getValidatorType() {
+		return fSelectedValidatorType;
+	}
+	
+
+	private IStatus validateValidatorName() {
+		StatusInfo status= new StatusInfo();
+		String name= fValidatorName.getText();
+		if (name == null || name.trim().length() == 0) {
+			status.setInfo(ValidatorMessages.addValidatorDialog_enterName); 
+		} else {
+			if (fRequestor.isDuplicateName(name) && (fEditedValidator == null || !name.equals(fEditedValidator.getName()))) {
+				status.setError(ValidatorMessages.addValidatorDialog_duplicateName); 
+			} 
+		}
+		return status;
+	}
+	
+	public void updateStatusLine() {
+		IStatus max= null;
+		for (int i= 0; i < fStati.length; i++) {
+			IStatus curr= fStati[i];
+			if (curr.matches(IStatus.ERROR)) {
+				updateStatus(curr);
+				return;
+			}
+			if (max == null || curr.getSeverity() > max.getSeverity()) {
+				max= curr;
+			}
+		}
+		updateStatus(max);
+	}
+	
+	protected void okPressed() {
+		doOkPressed();
+		super.okPressed();
+	}
+	
+	private void doOkPressed() {
+		if (fEditedValidator == null) {
+			IValidator Validator = fSelectedValidatorType.createValidator( createUniqueId(fSelectedValidatorType));
+			setFieldValuesToValidator(Validator);
+			fRequestor.validatorAdded(Validator);
+		} else {
+			setFieldValuesToValidator(fEditedValidator);
+		}
+	}
+	
+	private String createUniqueId(IValidatorType ValidatorType) {
+		String id= null;
+		do {
+			id= String.valueOf(System.currentTimeMillis());
+		} while (ValidatorType.findValidator(id) != null);
+		return id;
+	}
+	
+	protected void setFieldValuesToValidator(IValidator validator) {
+		validator.setName(fValidatorName.getText());
+		if( this.fConfigurationPage != null ) {
+			this.fConfigurationPage.applyChanges();
+		}
+	}
+	
+	protected File getAbsoluteFileOrEmpty(String path) {
+		if (path == null || path.length() == 0) {
+			return new File(""); //$NON-NLS-1$
+		}
+		return new File(path).getAbsoluteFile();
+	}
+	
+	private void setValidatorNameStatus(IStatus status) {
+		fStati[0]= status;
+	}
+	
+	private void setValidatorLocationStatus(IStatus status) {
+		fStati[1]= status;
+	}
+	
+	protected IStatus getSystemLibraryStatus() {
+		return fStati[3];
+	}
+	
+	public void setSystemLibraryStatus(IStatus status) {
+		fStati[3]= status;
+	}
+	
+	/**
+	 * Updates the status of the ok button to reflect the given status.
+	 * Subclasses may override this method to update additional buttons.
+	 * @param status the status.
+	 */
+	protected void updateButtonsEnableState(IStatus status) {
+		Button ok = getButton(IDialogConstants.OK_ID);
+		if (ok != null && !ok.isDisposed())
+			ok.setEnabled(status.getSeverity() == IStatus.OK);
+	}	
+	
+	/**
+	 * @see org.eclipse.jface.dialogs.Dialog#setButtonLayoutData(org.eclipse.swt.widgets.Button)
+	 */
+	public void setButtonLayoutData(Button button) {
+		super.setButtonLayoutData(button);
+	}
+	
+	/**
+	 * Returns the name of the section that this dialog stores its settings in
+	 * 
+	 * @return String
+	 */
+	protected String getDialogSettingsSectionName() {
+		return "ADD_Validator_DIALOG_SECTION"; //$NON-NLS-1$
+	}
+	
+	 /* (non-Javadoc)
+     * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
+     */
+//    protected IDialogSettings getDialogBoundsSettings() {
+//    	 IDialogSettings settings = ValidatorsUI.getDefault().getDialogSettings();
+//         IDialogSettings section = settings.getSection(getDialogSettingsSectionName());
+//         if (section == null) {
+//             section = settings.addNewSection(getDialogSettingsSectionName());
+//         } 
+//         return section;
+//    }
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/IAddValidatorDialogRequestor.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/IAddValidatorDialogRequestor.java
new file mode 100644
index 0000000..fb1c343
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/IAddValidatorDialogRequestor.java
@@ -0,0 +1,13 @@
+
+package org.eclipse.dltk.validators.internal.ui;
+
+import org.eclipse.dltk.validators.core.IValidator;
+
+
+public interface IAddValidatorDialogRequestor {
+
+	public boolean isDuplicateName(String name);
+	
+	public void validatorAdded(IValidator validator);
+	
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorBlock.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorBlock.java
new file mode 100644
index 0000000..94bfb6b
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorBlock.java
@@ -0,0 +1,814 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 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.dltk.validators.internal.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.dltk.core.DLTKLanguageManager;
+import org.eclipse.dltk.core.IDLTKLanguageToolkit;
+import org.eclipse.dltk.internal.ui.util.SWTUtil;
+import org.eclipse.dltk.internal.ui.util.TableLayoutComposite;
+import org.eclipse.dltk.ui.util.PixelConverter;
+import org.eclipse.dltk.validators.core.IValidator;
+import org.eclipse.dltk.validators.core.IValidatorType;
+import org.eclipse.dltk.validators.core.ValidatorRuntime;
+import org.eclipse.jface.dialogs.IDialogSettings;
+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.jface.window.Window;
+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.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * A composite that displays installed InterpreterEnvironment's in a table.
+ * InterpreterEnvironments can be added, removed, edited, and searched for.
+ * <p>
+ * This block implements ISelectionProvider - it sends selection change events
+ * when the checked InterpreterEnvironment in the table changes, or when the
+ * "use default" button check state changes.
+ * </p>
+ */
+public class ValidatorBlock implements ISelectionProvider,
+		IAddValidatorDialogRequestor {
+
+	/**
+	 * This block's control
+	 */
+	private Composite fControl;
+
+	/**
+	 * Interpreters being displayed
+	 */
+	protected List fValidator = new ArrayList();
+
+	/**
+	 * The main list control
+	 */
+	protected CheckboxTableViewer fValidatorList;
+
+	// Action buttons
+	private Button fAddButton;
+	private Button fRemoveButton;
+	private Button fEditButton;
+	private Button fCopyButton;
+	// private Button fSearchButton;
+
+	// index of column used for sorting
+	private int fSortColumn = 0;
+
+	/**
+	 * Selection listeners (checked InterpreterEnvironment changes)
+	 */
+	private ListenerList fSelectionListeners = new ListenerList();
+
+	/**
+	 * Previous selection
+	 */
+	private ISelection fPrevSelection = new StructuredSelection();
+
+	private Table fTable;
+
+	/**
+	 * Content provider to show a list of InterpreterEnvironments
+	 */
+	class ValidatorContentProvider implements IStructuredContentProvider {
+		public Object[] getElements(Object input) {
+			return fValidator.toArray();
+		}
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+
+		public void dispose() {
+		}
+	}
+
+	/**
+	 * Label provider for installed InterpreterEnvironments table.
+	 */
+	class ValidatorLabelProvider extends LabelProvider implements
+			ITableLabelProvider {
+
+		/**
+		 * @see ITableLabelProvider#getColumnText(Object, int)
+		 */
+		public String getColumnText(Object element, int columnIndex) {
+			if (element instanceof IValidator) {
+				IValidator validator = (IValidator) element;
+				switch (columnIndex) {
+				case 0:
+					return validator.getName();
+				case 1:
+					return validator.getValidatorType().getName();
+				case 2:
+					String nature = validator.getValidatorType().getNature();
+					if (nature == "#") {
+						return "All";
+					}
+					try {
+						IDLTKLanguageToolkit languageToolkit = DLTKLanguageManager
+								.getLanguageToolkit(nature);
+						if (languageToolkit != null) {
+							return languageToolkit.getLanguageName();
+						}
+					} catch (CoreException e) {
+					}
+					return "Unknown";
+				}
+			}
+			return element.toString();
+		}
+
+		/**
+		 * @see ITableLabelProvider#getColumnImage(Object, int)
+		 */
+		public Image getColumnImage(Object element, int columnIndex) {
+			if (columnIndex == 0) {
+				// TODO: instert interpreter logo here
+			}
+			return null;
+		}
+
+	}
+
+	public ValidatorBlock() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
+	 */
+	public void addSelectionChangedListener(ISelectionChangedListener listener) {
+		fSelectionListeners.add(listener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
+	 */
+	public ISelection getSelection() {
+		return new StructuredSelection(fValidatorList.getCheckedElements());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
+	 */
+	public void removeSelectionChangedListener(
+			ISelectionChangedListener listener) {
+		fSelectionListeners.remove(listener);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
+	 */
+	public void setSelection(ISelection selection) {
+		if (selection instanceof IStructuredSelection) {
+			if (!selection.equals(fPrevSelection)) {
+				fPrevSelection = selection;
+				Object interp = ((IStructuredSelection) selection)
+						.getFirstElement();
+				if (interp == null) {
+					fValidatorList.setCheckedElements(new Object[0]);
+				} else {
+					fValidatorList.setCheckedElements(new Object[] { interp });
+					fValidatorList.reveal(interp);
+				}
+				fireSelectionChanged();
+			}
+		}
+	}
+
+	/**
+	 * Creates this block's control in the given control.
+	 * 
+	 * @param ancestor
+	 *            containing control
+	 * @param useManageButton
+	 *            whether to present a single 'manage...' button to the user
+	 *            that opens the installed InterpreterEnvironments pref page for
+	 *            InterpreterEnvironment management, or to provide 'add, remove,
+	 *            edit, and search' buttons.
+	 */
+	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;
+
+		Font font = ancestor.getFont();
+		parent.setFont(font);
+		parent.setLayout(layout);
+
+		fControl = parent;
+
+		GridData data;
+
+		Label tableLabel = new Label(parent, SWT.NONE);
+		tableLabel.setText(ValidatorMessages.InstalledValidatorBlock_15);
+		data = new GridData();
+		data.horizontalSpan = 2;
+		tableLabel.setLayoutData(data);
+		tableLabel.setFont(font);
+
+		PixelConverter conv = new PixelConverter(parent);
+		data = new GridData(GridData.FILL_BOTH);
+		data.widthHint = conv.convertWidthInCharsToPixels(50);
+		TableLayoutComposite tblComposite = new TableLayoutComposite(parent,
+				SWT.NONE);
+		tblComposite.setLayoutData(data);
+		fTable = new Table(tblComposite, SWT.CHECK | SWT.BORDER | SWT.MULTI
+				| SWT.FULL_SELECTION);
+
+		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.NULL);
+		column1.setText(ValidatorMessages.InstalledValidatorBlock_0);
+		column1.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				sortByName();
+			}
+		});
+
+		TableColumn column2 = new TableColumn(fTable, SWT.NULL);
+		column2.setText(ValidatorMessages.InstalledValidatorBlock_2);
+		column2.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				sortByType();
+			}
+		});
+
+		TableColumn column3 = new TableColumn(fTable, SWT.NULL);
+		column3.setText(ValidatorMessages.InstalledValidatorBlock_1);
+		// column3.addSelectionListener(new SelectionAdapter() {
+		// public void widgetSelected(SelectionEvent e) {
+		// sortByLocation();
+		// }
+		// });
+
+		fValidatorList = new CheckboxTableViewer(fTable);
+		fValidatorList.setLabelProvider(new ValidatorLabelProvider());
+		fValidatorList.setContentProvider(new ValidatorContentProvider());
+		fValidatorList.addCheckStateListener(new ICheckStateListener() {
+			public void checkStateChanged(CheckStateChangedEvent event) {
+				IValidator validator = (IValidator)event.getElement();
+				validator.setActive(event.getChecked());
+			}
+		});
+		
+		// by default, sort by name
+		sortByName();
+
+		fValidatorList
+				.addSelectionChangedListener(new ISelectionChangedListener() {
+					public void selectionChanged(SelectionChangedEvent evt) {
+						enableButtons();
+					}
+				});
+
+		// fValidatorList.addCheckStateListener(new ICheckStateListener() {
+		// public void checkStateChanged(CheckStateChangedEvent event) {
+		// if (event.getChecked()) {
+		// setCheckedInterpreter((IValidator)event.getElement());
+		// } else {
+		// setCheckedInterpreter(null);
+		// }
+		// }
+		// });
+
+		fValidatorList.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent e) {
+				if (!fValidatorList.getSelection().isEmpty()) {
+					editValidator();
+				}
+			}
+		});
+		fTable.addKeyListener(new KeyAdapter() {
+			public void keyPressed(KeyEvent event) {
+				if (event.character == SWT.DEL && event.stateMask == 0) {
+					if (fRemoveButton.getEnabled())
+						removeValidator();
+				}
+			}
+		});
+
+		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,
+				ValidatorMessages.InstalledValidatorBlock_3);
+		fAddButton.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event evt) {
+				addValidator();
+			}
+		});
+
+		fEditButton = createPushButton(buttons,
+				ValidatorMessages.InstalledValidatorBlock_4);
+		fEditButton.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event evt) {
+				editValidator();
+			}
+		});
+
+		fCopyButton = createPushButton(buttons,
+				ValidatorMessages.InstalledValidatorBlock_16);
+		fCopyButton.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event evt) {
+				copyValidator();
+			}
+		});
+
+		fRemoveButton = createPushButton(buttons,
+				ValidatorMessages.InstalledValidatorBlock_5);
+		fRemoveButton.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event evt) {
+				removeValidator();
+			}
+		});
+
+		// 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);
+
+		// fSearchButton = createPushButton(buttons,
+		// ValidatorMessages.InstalledValidatorBlock_6);
+		// fSearchButton.addListener(SWT.Selection, new Listener() {
+		// public void handleEvent(Event evt) {
+		// search();
+		// }
+		// });
+
+		fillWithWorkspaceValidator();
+		enableButtons();
+		fAddButton.setEnabled(ValidatorRuntime
+				.getValidatorTypes(/* getCurrentNature() */).length > 0);
+	}
+
+	/**
+	 * Fire current selection
+	 */
+	private void fireSelectionChanged() {
+		SelectionChangedEvent event = new SelectionChangedEvent(this,
+				getSelection());
+		Object[] listeners = fSelectionListeners.getListeners();
+		for (int i = 0; i < listeners.length; i++) {
+			ISelectionChangedListener listener = (ISelectionChangedListener) listeners[i];
+			listener.selectionChanged(event);
+		}
+	}
+
+	/**
+	 * Sorts by Interpreter type, and name within type.
+	 */
+	private void sortByType() {
+		fValidatorList.setSorter(new ViewerSorter() {
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				if ((e1 instanceof IValidator) && (e2 instanceof IValidator)) {
+					IValidator left = (IValidator) e1;
+					IValidator right = (IValidator) e2;
+					String leftType = left.getValidatorType().getName();
+					String rightType = right.getValidatorType().getName();
+					int res = leftType.compareToIgnoreCase(rightType);
+					if (res != 0) {
+						return res;
+					}
+					return left.getName().compareToIgnoreCase(right.getName());
+				}
+				return super.compare(viewer, e1, e2);
+			}
+
+			public boolean isSorterProperty(Object element, String property) {
+				return true;
+			}
+		});
+		fSortColumn = 3;
+	}
+
+	/**
+	 * Sorts by Interpreter name.
+	 */
+	private void sortByName() {
+		fValidatorList.setSorter(new ViewerSorter() {
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				if ((e1 instanceof IValidator) && (e2 instanceof IValidator)) {
+					IValidator left = (IValidator) e1;
+					IValidator right = (IValidator) e2;
+					return left.getName().compareToIgnoreCase(right.getName());
+				}
+				return super.compare(viewer, e1, e2);
+			}
+
+			public boolean isSorterProperty(Object element, String property) {
+				return true;
+			}
+		});
+		fSortColumn = 1;
+	}
+
+	private void enableButtons() {
+		IStructuredSelection selection = (IStructuredSelection) fValidatorList
+				.getSelection();
+		int selectionCount = selection.size();
+		
+		boolean addEnabled = true;
+		boolean editEnabled = selectionCount == 1;
+		boolean removeEnabled = true;
+		boolean copyEnabled = selectionCount > 0;
+		
+		if (selectionCount > 0) {
+			Iterator iterator = selection.iterator();
+			while (iterator.hasNext()) {
+				IValidator install = (IValidator) iterator.next();
+				boolean builtin = install.getValidatorType().isBuiltin();
+				if (isContributed(install) || builtin) {
+					removeEnabled = false;
+					copyEnabled = false;
+				}
+			}
+		} else {
+			removeEnabled = false;
+		}
+		fAddButton.setEnabled(addEnabled);
+		fEditButton.setEnabled(editEnabled);
+		fRemoveButton.setEnabled(removeEnabled);
+		fCopyButton.setEnabled(copyEnabled);
+	}
+
+	protected Button createPushButton(Composite parent, String label) {
+		return SWTUtil.createPushButton(parent, label, null);
+	}
+
+	private boolean isContributed(IValidator install) {
+		return ValidatorRuntime.isContributedValidator(install.getID());
+	}
+
+	/**
+	 * Returns this block's control
+	 * 
+	 * @return control
+	 */
+	public Control getControl() {
+		return fControl;
+	}
+
+	/**
+	 * Sets the InterpreterEnvironments to be displayed in this block
+	 * 
+	 * @param validators
+	 *            InterpreterEnvironments to be displayed
+	 */
+	protected void setValidator(IValidator[] validators) {
+		fValidator.clear();
+		List active = new ArrayList();
+		for (int i = 0; i < validators.length; i++) {
+			if( validators[i].isActive()) {
+				active.add(validators[i]);
+			}
+			fValidator.add(validators[i]);
+		}
+		fValidatorList.setInput(fValidator);
+		fValidatorList.setCheckedElements(active.toArray());
+		fValidatorList.refresh();
+	}
+
+	/**
+	 * Returns the InterpreterEnvironments currently being displayed in this
+	 * block
+	 * 
+	 * @return InterpreterEnvironments currently being displayed in this block
+	 */
+	public IValidator[] getValidator() {
+		return (IValidator[]) fValidator.toArray(new IValidator[fValidator
+				.size()]);
+	}
+
+	/**
+	 * @see IAddValidatorDialogRequestor#isDuplicateName(String)
+	 */
+	public boolean isDuplicateName(String name) {
+		for (int i = 0; i < fValidator.size(); i++) {
+			IValidator Interpreter = (IValidator) fValidator.get(i);
+			if (Interpreter.getName().equals(name)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private void removeValidator() {
+		IStructuredSelection selection = (IStructuredSelection) fValidatorList
+				.getSelection();
+		IValidator[] Validator = new IValidator[selection.size()];
+		Iterator iter = selection.iterator();
+		int i = 0;
+		while (iter.hasNext()) {
+			Validator[i] = (IValidator) iter.next();
+			i++;
+		}
+		removeValidator(Validator);
+	}
+
+	/**
+	 * Removes the given Validator from the table.
+	 * 
+	 * @param Validator
+	 */
+	public void removeValidator(IValidator[] Validator) {
+		IStructuredSelection prev = (IStructuredSelection) getSelection();
+		for (int i = 0; i < Validator.length; i++) {
+			fValidator.remove(Validator[i]);
+		}
+		fValidatorList.refresh();
+		IStructuredSelection curr = (IStructuredSelection) getSelection();
+		if (!curr.equals(prev)) {
+			IValidator[] installs = getValidator();
+			if (curr.size() == 0 && installs.length == 1) {
+				// pick a default Interpreter automatically
+				setSelection(new StructuredSelection(installs[0]));
+			} else {
+				fireSelectionChanged();
+			}
+		}
+	}
+
+	protected Shell getShell() {
+		return getControl().getShell();
+	}
+
+	/**
+	 * Persist table settings into the give dialog store, prefixed with the
+	 * given key.
+	 * 
+	 * @param settings
+	 *            dialog store
+	 * @param qualifier
+	 *            key qualifier
+	 */
+	public void saveColumnSettings(IDialogSettings settings, String qualifier) {
+		int columnCount = fTable.getColumnCount();
+		for (int i = 0; i < columnCount; i++) {
+			settings
+					.put(
+							qualifier + ".columnWidth" + i, fTable.getColumn(i).getWidth()); //$NON-NLS-1$
+		}
+		settings.put(qualifier + ".sortColumn", fSortColumn); //$NON-NLS-1$
+	}
+
+	/**
+	 * Restore table settings from the given dialog store using the given key.
+	 * 
+	 * @param settings
+	 *            dialog settings store
+	 * @param qualifier
+	 *            key to restore settings from
+	 */
+	public void restoreColumnSettings(IDialogSettings settings, String qualifier) {
+		fValidatorList.getTable().layout(true);
+		restoreColumnWidths(settings, qualifier);
+		try {
+			fSortColumn = settings.getInt(qualifier + ".sortColumn"); //$NON-NLS-1$
+		} catch (NumberFormatException e) {
+			fSortColumn = 1;
+		}
+		switch (fSortColumn) {
+		case 1:
+			sortByName();
+			break;
+		case 2:
+			// sortByLocation();
+			break;
+		case 3:
+			sortByType();
+			break;
+		}
+	}
+
+	private void restoreColumnWidths(IDialogSettings settings, String qualifier) {
+		int columnCount = fTable.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) {
+				fTable.getColumn(i).pack();
+			} else {
+				fTable.getColumn(i).setWidth(width);
+			}
+		}
+	}
+
+	/**
+	 * Populates the InterpreterEnvironment table with existing
+	 * InterpreterEnvironments defined in the workspace.
+	 */
+	protected void fillWithWorkspaceValidator() {
+		// fill with Validator
+		List standins = new ArrayList();
+		IValidatorType[] types = ValidatorRuntime
+				.getValidatorTypes(/* getCurrentNature() */);
+		for (int i = 0; i < types.length; i++) {
+			IValidatorType type = types[i];
+			IValidator[] installs = type.getValidators();
+			if (installs != null)
+				for (int j = 0; j < installs.length; j++) {
+					IValidator validator = installs[j];
+					// standins.add(new Validatortandin(install));
+					standins.add(validator);
+				}
+		}
+		setValidator((IValidator[]) standins.toArray(new IValidator[standins
+				.size()]));
+	}
+
+	public void validatorAdded(IValidator Interpreter) {
+		fValidator.add(Interpreter);
+		fValidatorList.refresh();
+
+		IValidator[] installs = getValidator();
+		if (installs.length == 1) {
+			// pick a default Interpreter automatically
+			setSelection(new StructuredSelection(installs[0]));
+		}
+		fireSelectionChanged();
+	}
+
+	// Make sure that Validatortandin ids are unique if multiple calls to
+	// System.currentTimeMillis()
+	// happen very quickly
+	private static String fgLastUsedID;
+
+	/**
+	 * Find a unique Interpreter id. Check existing 'real' Validator, as well as
+	 * the last id used for a Validatortandin.
+	 */
+	protected String createUniqueId(IValidatorType InterpreterType) {
+		String id = null;
+		do {
+			id = String.valueOf(System.currentTimeMillis());
+		} while (InterpreterType.findValidator(id) != null
+				|| id.equals(fgLastUsedID));
+		fgLastUsedID = id;
+		return id;
+	}
+
+	/**
+	 * Compares the given name against current names and adds the appropriate
+	 * numerical suffix to ensure that it is unique.
+	 * 
+	 * @param name
+	 *            the name with which to ensure uniqueness
+	 * @return the unique version of the given name
+	 * 
+	 */
+	protected String generateName(String name) {
+		if (!isDuplicateName(name)) {
+			return name;
+		}
+
+		if (name.matches(".*\\(\\d*\\)")) { //$NON-NLS-1$
+			int start = name.lastIndexOf('(');
+			int end = name.lastIndexOf(')');
+			String stringInt = name.substring(start + 1, end);
+			int numericValue = Integer.parseInt(stringInt);
+			String newName = name.substring(0, start + 1) + (numericValue + 1)
+					+ ")"; //$NON-NLS-1$
+			return generateName(newName);
+		} else {
+			return generateName(name + " (1)"); //$NON-NLS-1$
+		}
+	}
+
+	// protected String getCurrentNature() {
+	// return this.nature;
+	// }
+
+	// protected abstract AddDLTKInterpreterDialog
+	// createInterpreterDialog(IValidator standin);
+
+	protected void copyValidator() {
+		// IStructuredSelection selection = (IStructuredSelection)
+		// fValidatorList.getSelection();
+		// Iterator it = selection.iterator();
+		//	
+		// ArrayList newEntries = new ArrayList();
+		// while (it.hasNext()) {
+		// IValidator selectedInterpreter = (IValidator) it.next();
+		//	
+		// // duplicate & add Interpreter
+		// IValidator standin = new IValidator(selectedInterpreter,
+		// createUniqueId(selectedInterpreter.getValidatorType()));
+		// standin.setName(generateName(selectedInterpreter.getName()));
+		// // AddDLTKInterpreterDialog dialog =
+		// createInterpreterDialog(standin);
+		// dialog.setTitle(ValidatorMessages.InstalledValidatorBlock_18);
+		// if (dialog.open() != Window.OK) {
+		// return;
+		// }
+		// newEntries.add(standin);
+		// fValidator.add(standin);
+		// }
+		// fValidatorList.refresh();
+		// fValidatorList.setSelection(new
+		// StructuredSelection(newEntries.toArray()));
+	}
+
+	/**
+	 * Bring up a dialog that lets the user create a new Interpreter definition.
+	 */
+	protected void addValidator() {
+		AddValidatorDialog dialog = new AddValidatorDialog(this, getShell(),
+				ValidatorRuntime.getPossibleValidatorTypes(), null);
+		dialog.setTitle(ValidatorMessages.InstalledValidatorBlock_7);
+		if (dialog.open() != Window.OK) {
+			return;
+		}
+		fValidatorList.refresh();
+	}
+
+	protected void editValidator() {
+		IStructuredSelection selection = (IStructuredSelection) fValidatorList
+				.getSelection();
+		IValidator validator = (IValidator) selection.getFirstElement();
+		if (validator == null) {
+			return;
+		}
+
+		AddValidatorDialog dialog = new AddValidatorDialog(this, getShell(),
+				ValidatorRuntime.getValidatorTypes(), validator);
+		dialog.setTitle(ValidatorMessages.InstalledValidatorBlock_8);
+		if (dialog.open() != Window.OK) {
+			return;
+		}
+		fValidatorList.refresh(validator);
+	}
+}
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorConfigurationPageManager.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorConfigurationPageManager.java
new file mode 100644
index 0000000..2218248
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorConfigurationPageManager.java
@@ -0,0 +1,55 @@
+package org.eclipse.dltk.validators.internal.ui;
+
+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.Platform;
+import org.eclipse.dltk.validators.ValidatorConfigurationPage;
+
+public class ValidatorConfigurationPageManager {
+
+	private final static String LANGUAGE_EXTPOINT = ValidatorsUI.PLUGIN_ID
+			+ ".validatorConfigPage";
+
+	private final static String ID_ATTR = "id";
+
+	private static Map toolkits;
+
+	private static void initialize() {
+		if (toolkits != null) {
+			return;
+		}
+
+		toolkits = new HashMap(5);
+		IConfigurationElement[] cfg = Platform.getExtensionRegistry()
+				.getConfigurationElementsFor(LANGUAGE_EXTPOINT);
+
+		for (int i = 0; i < cfg.length; i++) {
+			String id = cfg[i].getAttribute(ID_ATTR);
+			if (toolkits.get(id) != null)
+				System.err.println("TODO log redeclaration");
+			toolkits.put(id, cfg[i]);
+		}
+	}
+
+	public static ValidatorConfigurationPage getConfigurationPage(String Id)
+			throws CoreException {
+		initialize();
+
+		Object ext = toolkits.get(Id);
+
+		if (ext != null) {
+			if (ext instanceof ValidatorConfigurationPage)
+				return (ValidatorConfigurationPage) ext;
+
+			IConfigurationElement cfg = (IConfigurationElement) ext;
+			ValidatorConfigurationPage toolkit = (ValidatorConfigurationPage) cfg
+					.createExecutableExtension("class");
+			toolkits.put(Id, toolkit);
+			return toolkit;
+		}
+		return null;
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorConsoleTrackerManager.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorConsoleTrackerManager.java
new file mode 100644
index 0000000..53ae54f
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorConsoleTrackerManager.java
@@ -0,0 +1,42 @@
+package org.eclipse.dltk.validators.internal.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.ui.console.IPatternMatchListener;
+
+public class ValidatorConsoleTrackerManager {
+
+	private final static String EXTPOINT = ValidatorsUI.PLUGIN_ID
+			+ ".validatorConsoleTracker";
+
+	private static List listeners;
+
+	private static void initialize() throws CoreException {
+		if (listeners != null) {
+			return;
+		}
+
+		listeners = new ArrayList(5);
+		IConfigurationElement[] cfg = Platform.getExtensionRegistry()
+				.getConfigurationElementsFor(EXTPOINT);
+
+		for (int i = 0; i < cfg.length; i++) {
+			IPatternMatchListener listener = (IPatternMatchListener) cfg[i]
+					.createExecutableExtension("class");
+			listeners.add(listener);
+		}
+	}
+	public static IPatternMatchListener[] getListeners() {
+		try {
+			initialize();
+		} catch (CoreException e) {
+			e.printStackTrace();
+			return null;
+		}
+		return (IPatternMatchListener[])listeners.toArray(new IPatternMatchListener[listeners.size()]);
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorMessages.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorMessages.java
new file mode 100644
index 0000000..4ce7aca
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorMessages.java
@@ -0,0 +1,80 @@
+package org.eclipse.dltk.validators.internal.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class ValidatorMessages extends NLS {
+	private static final String BUNDLE_NAME = "org.eclipse.dltk.validators.internal.ui.ValidatorMessages";//$NON-NLS-1$
+	public static String addValidatorDialog_ValidatorEnvironmentName;
+	public static String ValidatorPreferencePage_1;
+	public static String ValidatorPreferencePage_2;
+	public static String InstalledValidatorBlock_15;
+	public static String InstalledValidatorBlock_0;
+	public static String InstalledValidatorBlock_1;
+	public static String InstalledValidatorBlock_2;
+	public static String InstalledValidatorBlock_3;
+	public static String InstalledValidatorBlock_4;
+	public static String InstalledValidatorBlock_16;
+	public static String InstalledValidatorBlock_5;
+	public static String InstalledValidatorBlock_6;
+	public static String InstalledValidatorBlock_18;
+	public static String InstalledValidatorBlock_8;
+	public static String InstalledValidatorBlock_7;
+	public static String addValidatorDialog_ValidatorExecutableName;
+	public static String addValidatorDialog_browse1;
+	public static String AddValidatorDialog_23;
+	public static String AddValidatorDialog_Validator_system_libraries__1;
+	public static String addValidatorDialog_enterLocation;
+	public static String addValidatorDialog_locationNotExists;
+	public static String addValidatorDialog_enterName;
+	public static String addValidatorDialog_duplicateName;
+	public static String addValidatorDialog_pickValidatorRootDialog_message;
+	public static String ValidatorComboBlock_3;
+	public static String ValidatorComboBlock_1;
+	public static String ValidatorComboBlock_0;
+	public static String ValidatorComboBlock_2;
+	public static String ValidatorComboBlock_12;
+	public static String ValidatorComboBlock_13;
+	public static String ValidatorComboBlock_11;
+	public static String ValidatorComboBlock_10;
+	public static String ValidatorComboBlock_9;
+	public static String ValidatorComboBlock_8;
+	public static String addValidatorDialog_ValidatorEnvironmentType;
+	public static String LibraryStandin_0;
+	public static String ValidatorLibraryBlock_0;
+	public static String ValidatorLibraryBlock_7;
+	public static String ValidatorLibraryBlock_6;
+	public static String ValidatorLibraryBlock_4;
+	public static String ValidatorLibraryBlock_5;
+	public static String ValidatorLibraryBlock_9;
+	public static String ValidatorLibraryBlock_Libraries_cannot_be_empty__1;
+	public static String ValidatorLibraryBlock_10;
+	public static String ValidatorPreferencePage_11;
+	public static String ValidatorPreferencePage_10;
+	public static String ValidatorUpdater_0;
+	public static String InstalledValidatorBlock_11;
+	public static String InstalledValidatorBlock_12;
+	public static String InstalledValidatorBlock_13;
+	public static String InstalledValidatorBlock_9;
+	public static String InstalledValidatorBlock_10;
+	public static String InstalledValidatorBlock_14;
+	public static String ValidatorPreferencePage_addValidator;
+	public static String ValidatorPreferencePage_pleaseSetDefaultValidator;
+	public static String ValidatorContainerWizardPage_3;
+	public static String ValidatorContainerWizardPage_Validator_System_Library_1;
+	public static String ValidatorContainerWizardPage_Select_the_Validator_used_to_build_this_project__4;
+	public static String BuildValidatorDescriptor_0;
+	public static String InstalledValidatorBlock_113;
+	public static String statusFetchingLibs;
+	public static String AddValidatorDialog_iArgs;
+	
+
+	
+	
+	private ValidatorMessages() {
+	// dont instatiate
+	}
+	static {
+		// load message values from bundle file
+		NLS.initializeMessages(BUNDLE_NAME, ValidatorMessages.class);
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorMessages.properties b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorMessages.properties
new file mode 100644
index 0000000..b71dce6
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorMessages.properties
@@ -0,0 +1,94 @@
+
+BuildValidatorDescriptor_0=Workspace &default Validator ({0})
+
+InstalledValidatorBlock_0=Name
+InstalledValidatorBlock_1=Language
+InstalledValidatorBlock_2=Type
+InstalledValidatorBlock_3=&Add...
+InstalledValidatorBlock_4=&Edit...
+InstalledValidatorBlock_5=&Remove
+InstalledValidatorBlock_6=&Search...
+InstalledValidatorBlock_7=Add Validator
+InstalledValidatorBlock_8=Edit Validator
+InstalledValidatorBlock_9=Select a directory to search in:
+InstalledValidatorBlock_10=Directory Selection
+InstalledValidatorBlock_11=Searching...
+InstalledValidatorBlock_12=Information
+InstalledValidatorBlock_13=No Validator found in {0}
+InstalledValidatorBlock_113=No Validator found
+InstalledValidatorBlock_14=Found {0} - Searching {1}
+InstalledValidatorBlock_15=Installed &Validator:
+InstalledValidatorBlock_16=&Copy...
+InstalledValidatorBlock_18=Copy Validator
+#InstalledValidatorBlock_19={0} (locked)
+
+ValidatorComboBlock_1=Alternate &Validator:
+ValidatorComboBlock_10=Validator name not specified for Validator type: {0}
+ValidatorComboBlock_11=Unable to resolve Validator: {0} ({1})
+ValidatorComboBlock_12=Validator path not specified
+ValidatorComboBlock_13=Validator path does not exist
+#ValidatorComboBlock_14=Envir&onments...
+ValidatorComboBlock_2=&Installed Validator...
+ValidatorComboBlock_3=Runtime Validator:
+ValidatorComboBlock_0=No Validator defined in workspace
+#ValidatorComboBlock_4=E&xecution Environment:
+#ValidatorComboBlock_5=No execution environments defined in workspace
+#ValidatorComboBlock_6=Unknown execution environment specified: {0}
+#ValidatorComboBlock_7=No Validator in workspace compatible with specified execution environment: {0}
+ValidatorComboBlock_8=Validator type not specified
+ValidatorComboBlock_9=Unknown Validator type specified: {0}
+
+ValidatorContainerWizardPage_Validator_System_Library_1=System Library
+ValidatorContainerWizardPage_Select_the_Validator_used_to_build_this_project__4=Select a Validator to add to the buildpath.
+ValidatorContainerWizardPage_3=System library
+
+ValidatorPreferencePage_1=Installed Validator
+ValidatorPreferencePage_2=Add, remove or edit Validators.\nChecked Validator is included into auto build.\n
+ValidatorPreferencePage_10=Installed Validator location no longer exists. Validator will be removed.
+ValidatorPreferencePage_11=Validator removed
+
+addValidatorDialog_browse1=&Browse...
+addValidatorDialog_duplicateName=The name is already used.
+addValidatorDialog_enterLocation=Enter the location of the Validator.
+addValidatorDialog_enterName=Enter a name for the Validator.
+addValidatorDialog_ValidatorExecutableName=&Validator executable:
+addValidatorDialog_ValidatorEnvironmentName=Validator &name:
+addValidatorDialog_ValidatorEnvironmentType=Validator &type:
+addValidatorDialog_locationNotExists=The location does not exist.
+AddValidatorDialog_iArgs=Validator arguments:
+addValidatorDialog_pickValidatorRootDialog_message=Select the root directory of the Validator installation:
+AddValidatorDialog_Validator_system_libraries__1=Validator system libraries:
+#AddValidatorDialog_Validator_name_must_be_a_valid_file_name___0__1=Validator name must be a valid file name: {0}
+AddValidatorDialog_23=Default &Validator Arguments:
+#AddValidatorDialog_0=Validator
+
+ValidatorLibraryBlock_Libraries_cannot_be_empty__1=Libraries cannot be empty.
+
+ValidatorUpdater_0=Save Validator Definitions
+ValidatorLibraryBlock_0=Source attachment:
+I#nterpreterLibraryBlock_1=(none)
+ValidatorLibraryBlock_10=Library Selection
+#ValidatorDetailsDialog_0=Validator Details
+ValidatorLibraryBlock_4=U&p
+ValidatorLibraryBlock_5=&Down
+ValidatorLibraryBlock_6=Re&move
+ValidatorLibraryBlock_7=Add E&xternal libraries...
+#ValidatorLibraryBlock_8=Ed&it...
+ValidatorLibraryBlock_9=&Restore Default
+LibraryStandin_0=System library does not exist: {0}
+LibraryStandin_1=Source attachment does not exist: {0}
+
+
+ValidatorPreferencePage_addValidator=Add Validator, if you want to launch anything
+ValidatorPreferencePage_pleaseSetDefaultValidator=Select a default Validator
+ValidatorContainerWizardPage_Validator_System_Library_1=Validator System Library
+ValidatorContainerWizardPage_3=System library
+ValidatorContainerWizardPage_Validator_System_Library_1=Validator system library
+ValidatorContainerWizardPage_Select_the_Validator_used_to_build_this_project__4=Select an Validator
+BuildValidatorDescriptor_0=Workspace &default Validator ({0})
+
+statusFetchingLibs=Fetching default Validator library locations...
+
+
+#GenericPythonArgumentsTab_1=Validator arguments:
+#GenericPythonArgumentsTab_2
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorPreferencePage.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorPreferencePage.java
new file mode 100644
index 0000000..0ddb6ab
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorPreferencePage.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.dltk.validators.internal.ui;
+
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.dltk.core.DLTKCore;
+import org.eclipse.dltk.core.IScriptModel;
+import org.eclipse.dltk.validators.core.IValidator;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.custom.BusyIndicator;
+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;
+
+/**
+ * The Installed InterpreterEnvironments preference page.
+ * 
+ *
+ */
+public class ValidatorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+							
+	private static final String VALIDATOR_PREFERENCE_PAGE = ValidatorsUI.PLUGIN_ID + ".ValidatorPreferencePage";
+	// InterpreterEnvironment Block
+	private ValidatorBlock fInterpretersBlock;
+	
+	public ValidatorPreferencePage() {
+		super();
+		
+		// only used when page is shown programatically
+		setTitle(ValidatorMessages.ValidatorPreferencePage_1);	 
+		
+		setDescription(ValidatorMessages.ValidatorPreferencePage_2); 
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+	 */
+	public void init(IWorkbench workbench) {
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createContents(Composite ancestor) {
+		initializeDialogUnits(ancestor);
+		
+		noDefaultAndApplyButton();
+		
+		GridLayout layout= new GridLayout();
+		layout.numColumns= 1;
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		ancestor.setLayout(layout);
+					
+		fInterpretersBlock = createValidatorsBlock();
+		fInterpretersBlock.createControl(ancestor);
+		Control control = fInterpretersBlock.getControl();
+		GridData data = new GridData(GridData.FILL_BOTH);
+		data.horizontalSpan = 1;
+		control.setLayoutData(data);
+		
+		fInterpretersBlock.restoreColumnSettings(ValidatorsUI.getDefault().getDialogSettings(), 
+				VALIDATOR_PREFERENCE_PAGE);
+						
+//		PlatformUI.getWorkbench().getHelpSystem().setHelp(ancestor, IDLTKDebugHelpContextIds.INTERPRETER_PREFERENCE_PAGE);		
+//		initDefaultInterpreter();
+		fInterpretersBlock.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+//				IValidator install = getCurrentDefaultInterpreter();
+//				if (install == null) {
+//					if (fInterpretersBlock.getInterpreters().length > 0)
+//						setErrorMessage(ValidatorMessages.InterpreterPreferencePage_pleaseSetDefaultInterpreter);
+//					else
+//						setErrorMessage(ValidatorMessages.InterpreterPreferencePage_addInterpreter);
+//				} else {
+//					setErrorMessage(null);
+//				}
+			}
+		});	
+		applyDialogFont(ancestor);
+		return ancestor;
+	}
+			
+	private ValidatorBlock createValidatorsBlock() {
+		return new ValidatorBlock(); 
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.IPreferencePage#performOk()
+	 */
+	public boolean performOk() {
+		final boolean[] canceled = new boolean[] {false};
+		BusyIndicator.showWhile(null, new Runnable() {
+			public void run() {
+				IValidator[] vnterpreters = fInterpretersBlock.getValidator();
+				ValidatorUpdater updater = new ValidatorUpdater();
+				if (!updater.updateValidatorSettings(vnterpreters)) {
+					canceled[0] = true;
+				}
+			}
+		});
+		
+		if(canceled[0]) {
+			return false;
+		}
+		
+		// save column widths
+		IDialogSettings settings = ValidatorsUI.getDefault().getDialogSettings();
+		fInterpretersBlock.saveColumnSettings(settings, VALIDATOR_PREFERENCE_PAGE);
+		
+		return super.performOk();
+	}	
+	
+	protected IScriptModel getScriptModel() {
+		return DLTKCore.create(ResourcesPlugin.getWorkspace().getRoot());
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorUpdater.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorUpdater.java
new file mode 100644
index 0000000..07e0753
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorUpdater.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.dltk.validators.internal.ui;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.dltk.validators.core.IValidator;
+import org.eclipse.dltk.validators.core.IValidatorType;
+import org.eclipse.dltk.validators.core.ValidatorRuntime;
+import org.eclipse.dltk.validators.internal.core.ValidatorDefinitionsContainer;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+
+
+/**
+ * Processes add/removed/changed Interpreters.
+ */
+public class ValidatorUpdater {
+	
+	// the Interpreters defined when this updated is instantiated
+	private ValidatorDefinitionsContainer fOriginalValidators;	
+	
+	/**
+	 * Contstructs a new Validator updater to update Validator install settings.
+	 */
+	public ValidatorUpdater() {
+		saveCurrentAsOriginal ();
+	}
+	
+	private void saveCurrentAsOriginal () {
+		fOriginalValidators = new ValidatorDefinitionsContainer();
+	
+		IValidatorType[] types = ValidatorRuntime.getValidatorTypes();
+		for (int i = 0; i < types.length; i++) {
+			IValidator[] validators = types[i].getValidators();
+			if (validators != null)
+				for (int j = 0; j < validators.length; j++) {
+					fOriginalValidators.addValidator(validators[j]);
+				}
+		}
+	}
+	
+	/**
+	 * Updates Validator settings and returns whether the update was successful.
+	 * 
+	 * @param validatorEnvironments new installed ValidatorEnvironments
+	 * @param defaultInterp new default Validator
+	 * @return whether the update was successful
+	 */
+	public boolean updateValidatorSettings(IValidator[] validatorEnvironments) {
+		
+		// Create a Validator definition container
+		ValidatorDefinitionsContainer validatorContainer = new ValidatorDefinitionsContainer();
+		
+		// Set the Validators on the container
+		for (int i = 0; i < validatorEnvironments.length; i++) {
+			validatorContainer.addValidator(validatorEnvironments[i]);
+		}	
+		
+		// Generate XML for the Validator defs and save it as the new value of the Validator preference
+		saveValidatorDefinitions(validatorContainer);
+		
+		saveCurrentAsOriginal ();
+		
+		return true;
+	}
+	
+	private void saveValidatorDefinitions(final ValidatorDefinitionsContainer container) {
+		IRunnableWithProgress runnable = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+				try {
+					monitor.beginTask(ValidatorMessages.ValidatorUpdater_0, 100); 
+					String ValidatorDefXML = container.getAsXML();
+					monitor.worked(40);
+					ValidatorRuntime.getPreferences().setValue(ValidatorRuntime.PREF_VALIDATOR_XML, ValidatorDefXML);
+					monitor.worked(30);
+					ValidatorRuntime.savePreferences();
+					monitor.worked(30);
+				} catch (IOException ioe) {
+					ValidatorsUI.log(ioe);
+				} catch (ParserConfigurationException e) {
+					ValidatorsUI.log(e);
+				} catch (TransformerException e) {
+					ValidatorsUI.log(e);
+				} finally {
+					monitor.done();
+				}
+				
+			}
+		};
+		try {
+			ValidatorsUI.getDefault().getWorkbench().getProgressService().busyCursorWhile(runnable);			
+		} catch (InvocationTargetException e) {
+			ValidatorsUI.log(e);
+		} catch (InterruptedException e) {
+			ValidatorsUI.log(e);
+		} 
+	}
+}
diff --git a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorsUI.java b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorsUI.java
new file mode 100644
index 0000000..5b07c77
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/ValidatorsUI.java
@@ -0,0 +1,63 @@
+package org.eclipse.dltk.validators.internal.ui;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class ValidatorsUI extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.dltk.validators.ui";
+
+	// The shared instance
+	private static ValidatorsUI plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public ValidatorsUI() {
+	}
+
+	/*
+	 * (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 ValidatorsUI getDefault() {
+		return plugin;
+	}
+	public static void log(String message) {
+		log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR,
+				message, null));
+	}
+	public static void log(IStatus status) {
+		getDefault().getLog().log(status);
+	}
+
+	public static void log(Throwable e) {
+		log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, e
+				.getMessage(), e));
+	}
+}
diff --git "a/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/popup/actions/Validat\303\263SelectionWithConsoleAction.java" "b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/popup/actions/Validat\303\263SelectionWithConsoleAction.java"
new file mode 100644
index 0000000..f39ce71
--- /dev/null
+++ "b/core/plugins/org.eclipse.dltk.validators.ui/src/org/eclipse/dltk/validators/internal/ui/popup/actions/Validat\303\263SelectionWithConsoleAction.java"
@@ -0,0 +1,94 @@
+package org.eclipse.dltk.validators.internal.ui.popup.actions;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.IParent;
+import org.eclipse.dltk.validators.core.ValidatorRuntime;
+import org.eclipse.dltk.validators.internal.core.ValidatorUtils;
+import org.eclipse.dltk.validators.internal.ui.ValidatorConsoleTrackerManager;
+import org.eclipse.dltk.validators.internal.ui.ValidatorUpdater;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IActionDelegate;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.IOConsole;
+import org.eclipse.ui.console.IOConsoleOutputStream;
+import org.eclipse.ui.console.IPatternMatchListener;
+
+public class ValidatóSelectionWithConsoleAction implements
+		IObjectActionDelegate {
+	ISelection selection;
+
+	/**
+	 * Constructor for Action1.
+	 */
+	public ValidatóSelectionWithConsoleAction() {
+		super();
+	}
+
+	/**
+	 * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
+	 */
+	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+	}
+
+	/**
+	 * @see IActionDelegate#run(IAction)
+	 */
+	public void run(IAction action) {
+		IConsoleManager consoleManager = ConsolePlugin.getDefault()
+				.getConsoleManager();
+		IOConsole ioConsole = new IOConsole("DLTK Validators output", null);
+		IPatternMatchListener[] listeners = ValidatorConsoleTrackerManager.getListeners();
+		for (int i = 0; i < listeners.length; i++) {
+			ioConsole.addPatternMatchListener(listeners[i]);
+		}
+		consoleManager.addConsoles(new IConsole[] { ioConsole });
+		consoleManager.showConsoleView(ioConsole);
+		IOConsoleOutputStream newOutputStream = ioConsole.newOutputStream();
+		if( this.selection == null ) {
+			return;
+		}
+		processSelectionToElements(newOutputStream, selection);
+		try {
+			newOutputStream.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	private void processSelectionToElements(OutputStream out, ISelection selection ) {
+		List elements = new ArrayList();
+		List resources = new ArrayList();
+		if (this.selection != null
+				&& this.selection instanceof IStructuredSelection) {
+			IStructuredSelection sel = (IStructuredSelection) this.selection;
+			Iterator iterator = sel.iterator();
+			for (; iterator.hasNext();) {
+				Object o = iterator.next();
+				ValidatorUtils.processResourcesToElements(o, elements, resources);
+			}
+		}
+		ValidatorRuntime.executeActiveValidatorsWithConsole(out, elements, resources);
+	}
+
+	/**
+	 * @see IActionDelegate#selectionChanged(IAction, ISelection)
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+		this.selection = selection;
+	}
+
+}