* DLTK Validators API
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;
+		}
+	}
+}