/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.validation;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.validation.internal.ConfigurationManager;
import org.eclipse.wst.validation.internal.MarkerManager;
import org.eclipse.wst.validation.internal.SummaryReporter;
import org.eclipse.wst.validation.internal.ValManager;
import org.eclipse.wst.validation.internal.ValMessages;
import org.eclipse.wst.validation.internal.ValOperation;
import org.eclipse.wst.validation.internal.ValOperationManager;
import org.eclipse.wst.validation.internal.ValPrefManagerGlobal;
import org.eclipse.wst.validation.internal.ValPrefManagerProject;
import org.eclipse.wst.validation.internal.ValidationConfiguration;
import org.eclipse.wst.validation.internal.ValidatorExtensionReader;
import org.eclipse.wst.validation.internal.ValidatorMetaData;
import org.eclipse.wst.validation.internal.core.ValidatorLauncher;
import org.eclipse.wst.validation.internal.delegates.ValidatorDelegateDescriptor;
import org.eclipse.wst.validation.internal.delegates.ValidatorDelegatesRegistry;
import org.eclipse.wst.validation.internal.model.FilterGroup;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.operations.WorkbenchContext;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IValidator;

/**
 * Represents a validator. This gets instantiated through one of the validator extension points.
 * 
 * @author karasiuk
 *
 */
public abstract class Validator implements Comparable {
	// Remember is you add a new instance variable, make sure that you update the copy and become methods
	
	protected boolean	_buildValidation = true;
	
	/** If this is a delegating validator, then this field holds the validator that will be delegated to. */
	private String 		_delegatingId;
	
	/** 
	 * If this validator is also used to control an ISource validator, the id of the ISource validator is
	 * registered here.
	 */
	private String		_sourceId;
	
	protected boolean 	_manualValidation = true;
	
	/** 
	 * Version of the filter definition. By increasing this number the framework can know that a plug-in has 
	 * changed it's filters.
	 */
	private int			_version = 1;
	
	/** Map simple message id's to message settings. */
	private Map<String, MessageSeveritySetting> _messageSettings;
	
	/** The project that you are defined in. This can be null which means that you are a global validator. */
	protected IProject	_project;
	
	/**
	 * Create a new validator based on a abstract validator.
	 * 
	 * @param validator
	 *            The validator that is being wrapped.
	 * 
	 * @param project
	 *            The project that you are defined in. This can be null which
	 *            means that you are a global validator.
	 */
	public static Validator create(AbstractValidator validator, IProject project) {
		V2 v2 = new V2(validator, project);
		validator.setParent(v2);
		return v2;
	}
	
	public static Validator create(ValidatorMetaData vmd, ValidationConfiguration config, IProject project){
		V1 v1 = new V1(vmd, config);
		v1._project = project;
		return v1;
	}
	
	/**
	 * If you are a version 1 validator, answer yourself as one, otherwise answer null.
	 */
	public V1 asV1Validator(){
		return null;
	}
	
	/**
	 * If you are a version 2 validator, answer yourself as one, otherwise answer null.
	 */
	public V2 asV2Validator() {
		return null;
	}
	
	/**
	 * The project is being cleaned, this method gives the validator a chance to do any special cleanup.
	 * The default is to do nothing.
	 * 
	 * @param project the project being built.
	 * @param monitor the monitor that should be used for reporting progress if the clean takes a long time.
	 */
	public void clean(IProject project, IProgressMonitor monitor){
	}	
	
	/**
	 * Compare yourself based on Validator name.
	 */
	public int compareTo(Object validator) {
		if (validator instanceof Validator){
			Validator other = (Validator)validator;
			return getName().compareTo(other.getName());			
		}
		return -1;
	}
	
	/** Answer a deep copy of yourself. */
	public abstract Validator copy();
	
	/**
	 * Update your direct, non transient fields from the fields in v.
	 */
	protected void copyLocal(Validator v){
		_buildValidation = v._buildValidation;
		_delegatingId = v._delegatingId;
		_manualValidation = v._manualValidation;
		_messageSettings = v._messageSettings;
		_project = v._project;
		_sourceId = v._sourceId;
		_version = v._version;
	}
	
	/**
	 * Answer true if this validator, based on it's filters, should validate this resource. This method
	 * does not check to see if global validation or project validation has been suspended or not.
	 * 
	 * @param resource the resource to be checked
	 * @param isManual if true then this validator must also be enabled for manual validation.
	 * @param isBuild if true then this validator must also be enabled for builder based validation.
	 * 
	 * @return true if the resource should be validated.
	 */
	public boolean shouldValidate(IResource resource, boolean isManual, boolean isBuild){
		if (isManual && !_manualValidation)return false;
		if (isBuild && !_buildValidation)return false;
		
		return shouldValidate(resource);
	}
	
	/**
	 * Answer true if this validator, based on it's filters, should validate this project. This method
	 * does not check to see if global validation or project validation has been suspended or not.
	 * 
	 * @param project the project to be checked
	 * @param isManual if true then this validator must also be enabled for manual validation.
	 * @param isBuild if true then this validator must also be enabled for builder based validation.
	 * 
	 * @return true if the project should be validated.
	 */
	public boolean shouldValidateProject(IProject project, boolean isManual, boolean isBuild){
		if (isManual && !_manualValidation)return false;
		if (isBuild && !_buildValidation)return false;
		if (project == null || !project.isOpen())return false;
		return shouldValidateProject(project);
	}
	/**
	 * Validate the resource.
	 * 
	 * @param resource the resource to be validated
	 * @param kind the kind of resource change, see IResourceDelta for values.
	 * @param operation the operation that this validation is running under. This can be null.
	 * @param monitor a way to report progress. This can be null.
	 * 
	 * @return the result of doing the validation, it can be, but usually isn't null.
	 */
	public abstract ValidationResult validate(IResource resource, int kind, ValOperation operation, IProgressMonitor monitor);	

	/**
	 * This method will be called before any validation takes place. It allows validators to perform any
	 * initialization that they might need. 
	 *  
	 * @param project the project that is being validated. For the very first call in the validation phase,
	 * this will be null. That is the signal to the validator that a top level validation is starting.
	 * Subsequently, the project will be set, as each of the individual projects are validated.
	 * 
	 * @param state a way to pass arbitrary, validator specific, data from one invocation of a validator to
	 * the next, during the validation phase.
	 * 
	 * @param monitor the monitor that should be used for reporting progress if the clean takes a long time.
	 */
	public void validationStarting(IProject project, ValidationState state, IProgressMonitor monitor){
		// subclasses need to override this, if they wish to let their validators know about this event
	}
	
	/**
	 * This method will be called when validation is complete. It allows validators to perform any
	 * cleanup that they might need to do.  
	 *  
	 * @param project the project that was validated. The very last call in the validation will set this to 
	 * null so that the validator knows that all the projects have now been validated.
	 * 
	 * @param state a way to pass arbitrary, validator specific, data from one invocation of a validator to
	 * the next, during the validation phase.
	 * 
	 * @param monitor the monitor that should be used for reporting progress if the clean takes a long time.
	 */
	public void validationFinishing(IProject project, ValidationState state, IProgressMonitor monitor){		
		// subclasses need to override this, if they wish to let their validators know about this event
	}
	
	void add(MessageSeveritySetting message){
		// I can't use getMessageSettings() here, as that will put us into an infinite loop
		if (_messageSettings == null){
			_messageSettings = new HashMap<String, MessageSeveritySetting>(10);
		}
		_messageSettings.put(message.getId(), message);
	}
	
	public IValidator asIValidator(){
		return null;
	}

	
	protected abstract boolean shouldValidate(IResource resource);
	protected abstract boolean shouldValidateProject(IProject project);
			
	public abstract String getId();
	
	public MessageSeveritySetting getMessage(String id){
		return getMessageSettings().get(id);
	}
	
	/**
	 * Answer all the message settings that this validator has defined.
	 * 
	 * @return an empty map if the validator did not define any message settings.
	 */
	public Map<String, MessageSeveritySetting> getMessageSettings(){
		Map<String, MessageSeveritySetting> settings = _messageSettings;
		if (settings == null){
			settings = new HashMap<String, MessageSeveritySetting>(10);
			init(settings);
			if (ValManager.getDefault().hasEnabledProjectPreferences(getProject())){
				ValPrefManagerProject vp = new ValPrefManagerProject(getProject());
				vp.loadMessages(this, settings);
			}
			else {
				ValPrefManagerGlobal gp = ValPrefManagerGlobal.getDefault();
				gp.loadMessages(this, settings);
				
			}
			_messageSettings = settings;
		}
		return settings;
	}
	
	private void init(Map<String, MessageSeveritySetting> settings) {
		for (MessageSeveritySetting ms : ValidatorExtensionReader.getDefault().addMessages(this)){
			settings.put(ms.getId(), ms);
		}		
	}

	public abstract String getName();
	
	/**
	 * Answer the project that you were enabled on. 
	 * 
	 * @return null if you are a global (i.e. workspace level) validator.
	 */
	public IProject getProject(){
		return _project;
	}
		
	/**
	 * Answer the name of the class that implements the validator.
	 * @return
	 */
	public abstract String getValidatorClassname();
	
	/**
	 * Is this validator currently enabled for validations that are triggered manually? 
	 */
	public boolean isManualValidation() {
		return _manualValidation;
	}

	/**
	 * Set whether this validator should be triggered as part of a manual validation.
	 * 
	 * @param manualValidation
	 */
	public void setManualValidation(boolean manualValidation) {
		setManualValidation2(manualValidation);
	}
	
	protected final void setManualValidation2(boolean manualValidation) {
		_manualValidation = manualValidation;
	}

	/**
	 * Is this validator currently enabled for validations that are triggered by builds? 
	 */
	public boolean isBuildValidation() {
		return _buildValidation;
	}

	/**
	 * Set whether this validator should be triggered by the build process.
	 * 
	 * @param buildValidation
	 */
	public void setBuildValidation(boolean buildValidation) {
		setBuildValidation2(buildValidation);
	}
	
	protected final void setBuildValidation2(boolean buildValidation) {
		_buildValidation = buildValidation;
	}

	/**
	 * Get the id of the "real" validator, that is the validator that will be called when this delegating
	 * validator is asked to validate something. If this isn't a delegating validator answer null.
	 */
	public String getDelegatingId() {
		return _delegatingId;
	}
	
	public String getDependencyId(){
		return getId();
	}
	
	/**
	 * Set the id of the "real" validator, that is the validator that will be called when this delegating
	 * validator is asked to validate something.
	 * 
	 * @param delegating the id of the validator that is actually going to perform the validation.
	 */
	public void setDelegatingId(String delegating) {
		_delegatingId = delegating;
	}
	
	public int getVersion() {
		return _version;
	}
	
	public void setVersion(int version) {
		_version = version;
	}
	
	@Override
	public String toString() {
		return getName();
	}
		
/**
 * A validator that uses version 1 of the validation framework.
 * @author karasiuk
 *
 */ 
public static class V1 extends Validator {
	private ValidatorMetaData _vmd;
	
	/**
	 * Create a new version 1 validator. 
	 * @param vmd
	 * @param config this is used to set the global enablement options. In some case this can be null.
	 */
	public V1(ValidatorMetaData vmd, ValidationConfiguration config){
		_vmd = vmd;
		if (config != null){
			setBuildValidation(config.isBuildEnabled(vmd));
			setManualValidation(config.isManualEnabled(vmd));
		}
		setDelegatingId(ValidatorDelegatesRegistry.getInstance().getDefaultDelegate(getValidatorClassname()));
	}
	
	@Override
	public IValidator asIValidator() {
		IValidator v = null;
		try {
			v = _vmd.getValidator();
		}
		catch (InstantiationException e){
			ValidationPlugin.getPlugin().handleException(e);
			return null;
		}
		return v;
	}
	
	public V1 asV1Validator() {
		return this;
	}
	
	@Override
	public void become(Validator val) {
		super.become(val);
		V1 v1 = val.asV1Validator();
		if (v1 == null)throw new IllegalArgumentException("Internal error, the incoming validator must be a v1 validator"); //$NON-NLS-1$
		_vmd = v1._vmd;
	}
		
	public Validator copy() {
		V1 v = new V1Copy(_vmd, null);
		v.copyLocal(this);
				
		return v;
	}
	
	public String getName() {
		return _vmd.getValidatorDisplayName();
	}
	
	public ValidatorMetaData getVmd(){
		return _vmd;
	}
	
	public String getValidatorClassname(){
		String name = ""; //$NON-NLS-1$
		try {
			name = _vmd.getValidator().getClass().getName();
		}
		catch (Exception e){
			// eat it
		}
		return name;
	}
	public String getId() {
		return _vmd.getValidatorUniqueName();
	}
	
	@Override
	public void setBuildValidation(boolean buildValidation) {
		super.setBuildValidation(buildValidation);
		_vmd.setBuildValidation(buildValidation);
	}
	
	@Override
	public void setManualValidation(boolean manualValidation) {
		super.setManualValidation(manualValidation);
		_vmd.setManualValidation(manualValidation);
	}

	@Override
	protected boolean shouldValidate(IResource resource) {
		return _vmd.isApplicableTo(resource);
	}

	@Override
	protected boolean shouldValidateProject(IProject project) {
		// TODO determine if this can be optimized
		return true;
	}

	@Override
	public ValidationResult validate(IResource resource, int kind, ValOperation operation, 
		IProgressMonitor monitor) {
		
		if (monitor == null)monitor = new NullProgressMonitor();
		
		ValidationResult vr = new ValidationResult();
		IValidator v = asIValidator();
		if (v == null)return null;
		
		try {
			IProject project = resource.getProject();
			SummaryReporter reporter = new SummaryReporter(project, monitor);
			IWorkbenchContext helper = _vmd.getHelper(project);
			if (helper instanceof WorkbenchContext){
				WorkbenchContext wc = (WorkbenchContext)helper;
				List<String> files = new LinkedList<String>();
				// [213631] The JSP validator expects full paths not relative paths, but the XML validator
				// expects relative paths.
				files.add(wc.getPortableName(resource));
				wc.setValidationFileURIs(files);
			}
			ValidatorLauncher.getLauncher().start(helper, v, reporter);
			
			vr.incrementError(reporter.getSeverityHigh());
			vr.incrementWarning(reporter.getSeverityNormal());
			vr.incrementInfo(reporter.getSeverityLow());
			
		}
		catch (Exception e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		return vr;
	}
	
	/*
	 * GRK - Because I didn't want to try to make a true copy of the V1 validator, (because I didn't
	 * want to copy the vmd object), I came up with this approach to only copy the fields that
	 * the preference page was worried about. 
	 */
	public static class V1Copy extends V1 {
		public V1Copy(ValidatorMetaData vmd, ValidationConfiguration vc){
			super(vmd, vc);
		}
		
		@Override
		public void setManualValidation(boolean bool) {
			setManualValidation2(bool);
		}
		
		@Override
		public void setBuildValidation(boolean bool) {
			setBuildValidation2(bool);
		}
		
		@Override
		public void become(Validator val) {
			super.become(val);
			super.setBuildValidation(val.isBuildValidation());
			super.setManualValidation(val.isManualValidation());
		}
		
	}
		
}

/**
 * A validator that uses version 2 of the validation framework.
 * @author karasiuk
 *
 */
public final static class V2 extends Validator implements IAdaptable {
	private AbstractValidator	_validator;
	
	private List<FilterGroup>	_groups = new LinkedList<FilterGroup>();
	private FilterGroup[]		_groupsArray;
	
	/** The full id of the extension. */
	private String			_id;
	
	/** Name of the validator. */
	private String			_name;
		
	/** 
	 * If this validator is a delegating validator, then this is the "real" validator (i.e. the one that
	 * does the work).
	 */
	private AbstractValidator	_delegated;
	
	V2(AbstractValidator base, IProject project){
		_validator = base;
		_project = project;
		base.setParent(this);
		try {
			String target = getValidatorClassname();
			String id = ConfigurationManager.getManager().getConfiguration(project).getDelegateForTarget(target);
			if (id == null) id = ValidatorDelegatesRegistry.getInstance().getDefaultDelegate(target);
			setDelegatingId(id);
		}
		catch (InvocationTargetException e){
			ValidationPlugin.getPlugin().handleException(e);
		}
	}

	public synchronized void add(FilterGroup fg) {
		_groupsArray = null;
		_groups.add(fg);
	}
	
	@Override
	public IValidator asIValidator() {
		AbstractValidator av = getDelegatedValidator();
		if (av instanceof IValidator)return (IValidator)av;
		return super.asIValidator();
	}
	
	public V2 asV2Validator() {
		return this;
	}
	
	/**
	 * Let the validator know that a clean is about to happen.
	 * 
	 * @param project the project that is being cleaned. This can be null which means that the workspace
	 * is being cleaned (in which case a separate call will be made for each open project).
	 */
	public void clean(IProject project, IProgressMonitor monitor) {
		getDelegatedValidator().clean(project, ValOperationManager.getDefault().getOperation().getState(), monitor);
	}
	
	public Validator copy() {
		V2 v = new V2(_validator, _project);
		v.copyLocal(this);
		
		FilterGroup[] groups = getGroups();
		v._groupsArray = new FilterGroup[groups.length];
		for (int i=0; i<groups.length; i++){
			v._groupsArray[i] = groups[i].copy();
			v._groups.add(v._groupsArray[i]);
		}

		v._id = _id;
		v._name = _name;
				
		return v;
	}
	
	public String getDependencyId(){
		String id = getDelegatedValidator().getDependencyId();
		if (id != null)return id;
		return getId();
	}
	
	/**
	 * Answer the actual validator that is going to perform the validation. If this is a normal validator this
	 * method will simply answer itself. However if this is a delegating validator, then this will answer the
	 * "real" validator.
	 *
	 * @return
	 */
	public AbstractValidator getDelegatedValidator(){
		AbstractValidator delegated = _delegated;
		if (delegated != null)return delegated;
		else if (getDelegatingId() == null)return _validator;
		try {
			ValidatorDelegateDescriptor vdd = ValidatorDelegatesRegistry.getInstance()
				.getDescriptor(getValidatorClassname(), getDelegatingId());
			if (vdd == null)return _validator;
			delegated = vdd.getValidator2();
		}
		catch (Exception e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		if (delegated == null)return _validator;
		delegated.setParent(this);
		_delegated = delegated;
		return delegated;
	}
	
	public String getId() {
		return _id;
	}
	
	/**
	 * Answer the validator's filter groups.
	 *  
	 * @return an empty array if the validator does not have any filter groups.
	 */
	public synchronized FilterGroup[] getGroups(){
		FilterGroup[] groups = _groupsArray;
		if (groups == null){
			groups = new FilterGroup[_groups.size()];
			_groups.toArray(groups);
			_groupsArray = groups;
		}
		return groups;
	}
	
	public String getName() {
		return _name;
	}
	
	public AbstractValidator getValidator() {
		return _validator;
	}
	
	public String getValidatorClassname(){
		return getValidator().getClass().getName();
	}
		
	/**
	 * Answer true if this validator, based on it's filters, should validate this resource.
	 * 
	 * @return true if the resource should be validated.
	 */
	protected boolean shouldValidate(IResource resource) {
		FilterGroup[] groups = getGroups();
		IProject project = resource.getProject();
		for (FilterGroup group : groups){
			if (!group.shouldValidate(project, resource))return false;
		}
		return true;
	}
	
	
	@Override
	public void setDelegatingId(String delegating) {
		super.setDelegatingId(delegating);
		_delegated = null;
	}
	
	public synchronized void setGroups(FilterGroup[] groups){
		_groups.clear();
		_groupsArray = null;
		for (FilterGroup group : groups)_groups.add(group);
	}

	public void setId(String id) {
		_id = id;
	}
	
	public void setName(String name) {
		_name = name;
	}
	
	@Override
	public ValidationResult validate(IResource resource, int kind, ValOperation operation, IProgressMonitor monitor) {
		ValidationResult vr = null;
		if (operation == null)operation = new ValOperation();
		if (monitor == null)monitor = new NullProgressMonitor();
		try {
			vr = getDelegatedValidator().validate(resource, kind, operation.getState(), monitor);
		}
		catch (Exception e){
			ValidationPlugin.getPlugin().handleException(e);
		}
		
		if (vr != null){
			if (vr.getValidationException() != null){
				ValidationPlugin.getPlugin().handleException(vr.getValidationException());
			}
			updateResults(vr);
			if (vr.getDependsOn() != null){
				ValidationFramework.getDefault().getDependencyIndex().set(getDependencyId(), resource, vr.getDependsOn());
			}
			IResource[] validated = vr.getValidated();
			if (validated != null){
				for (int i=0; i<validated.length; i++){
					operation.addValidated(getId(), validated[i]);
				}
			}
			
			ValidatorMessage[] msgs = vr.getMessages();
			if (sanityTest(msgs.length, resource)){
				MarkerManager mm = MarkerManager.getDefault();
				for (ValidatorMessage m : msgs){
					mm.createMarker(m, getId());
				}
			}
			else {
				setBuildValidation(false);
				setManualValidation(false);
			}
		}
		return vr;		
	}
	
	/**
	 * Perform a simple sanity test to ensure that the validator is configured correctly.
	 * @param numberofMessages number of messages that the validator produced.
	 * @return true if the test passed
	 */
	private boolean sanityTest(int numberofMessages, IResource resource) {
		//FIXME make this more general and configurable
		if (numberofMessages < 201)return true;
		
		String resName = ""; //$NON-NLS-1$
		if (resource != null)resName = resource.getName();
		String message = NLS.bind(ValMessages.ConfigError, new Object[]{
				getName(), getId(), String.valueOf(numberofMessages), resName});
		ValidationPlugin.getPlugin().logMessage(IStatus.ERROR, message);
		
		return false;
	}

	/**
	 * If the validator is using a report helper then update it with any of the messages that were
	 * added directly to the validation result.
	 * @param vr
	 */
	private void updateResults(ValidationResult vr) {
		ReporterHelper rh = vr.getReporterHelper();
		if (rh == null)return;
		for (IMessage message : rh.getMessages()){
			Object target = message.getTargetObject();
			if (target != null){
				if (target instanceof IResource){
					IResource res = (IResource)target;
					ValidatorMessage vm = ValidatorMessage.create(message.getText(), res);
					vr.add(vm);
					int markerSeverity = IMarker.SEVERITY_INFO;
					int sev = message.getSeverity();
					if ((sev & IMessage.HIGH_SEVERITY) != 0)markerSeverity = IMarker.SEVERITY_ERROR;
					else if ((sev & IMessage.NORMAL_SEVERITY) != 0)markerSeverity = IMarker.SEVERITY_WARNING;
					vm.setAttribute(IMarker.SEVERITY, markerSeverity);
					vm.setAttribute(IMarker.LINE_NUMBER, message.getLineNumber());
					int offset = message.getOffset();
					if (offset != IMessage.OFFSET_UNSET){
						vm.setAttribute(IMarker.CHAR_START, offset);
						int len = message.getLength();
						if (len != IMessage.OFFSET_UNSET){
							vm.setAttribute(IMarker.CHAR_START, offset);
							vm.setAttribute(IMarker.CHAR_END, offset+len);
						}
					}					
				}
			}
		}		
	}

	@Override
	public void validationStarting(IProject project, ValidationState state, IProgressMonitor monitor) {
		getDelegatedValidator().validationStarting(project, state, monitor);
	}
	
	@Override
	public void validationFinishing(IProject project, ValidationState state, IProgressMonitor monitor) {
		getDelegatedValidator().validationFinishing(project, state, monitor);
	}

	public Object getAdapter(Class adapter) {
		return Platform.getAdapterManager().getAdapter(this, adapter);
	}

	public synchronized void remove(FilterGroup group) {
		_groups.remove(group);
		_groupsArray = null;	
	}

	@Override
	protected boolean shouldValidateProject(IProject project) {
		FilterGroup[] groups = getGroups();
		for (FilterGroup group : groups){
			if (!group.shouldValidate(project, null))return false;
		}
		return true;
	}
	
	@Override
	public void become(Validator val) {
		super.become(val);
		V2 v2 = val.asV2Validator();
		if (v2 == null)throw new IllegalArgumentException("Internal error, the incoming validator must be a v2 validator"); //$NON-NLS-1$
		_delegated = v2._delegated;
		_groups = v2._groups;
		_groupsArray = v2._groupsArray;
		_id = v2._id;
		_name = v2._name;
		_validator = v2._validator;
	}
}

public String getSourceId() {
	return _sourceId;
}

public void setSourceId(String sourceId) {
	_sourceId = sourceId;
}

/**
 * Take the instance variables from the incoming validator and set them to yourself.
 * @param validator
 */
public void become(Validator validator) {
	_buildValidation = validator._buildValidation;
	_delegatingId = validator._delegatingId;
	_manualValidation = validator._manualValidation;
	_messageSettings = validator._messageSettings;
	_project = validator._project;
	_sourceId = validator._sourceId;
	_version = validator._version;
	
}

void setMessages(Map<String, MessageSeveritySetting> map) {
	_messageSettings = map;
}

}
