first cut at Project Level validation settings.
diff --git a/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/internal/XSLCorePlugin.java b/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/internal/XSLCorePlugin.java
index e1b7641..3a95303 100644
--- a/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/internal/XSLCorePlugin.java
+++ b/bundles/org.eclipse.wst.xsl.core/src/org/eclipse/wst/xsl/core/internal/XSLCorePlugin.java
@@ -35,6 +35,11 @@
 	 */
 	public static final String PLUGIN_ID = "org.eclipse.wst.xsl.core"; //$NON-NLS-1$
 	
+	/**
+	 * 
+	 */
+	public static final String USE_PROJECT_SETTINGS = "use-project-settings";//$NON-NLS-1$
+	
 	// The shared instance
 	private static XSLCorePlugin plugin;
 	
diff --git a/bundles/org.eclipse.wst.xsl.ui/plugin.properties b/bundles/org.eclipse.wst.xsl.ui/plugin.properties
index 7aa0ebf..85231d0 100644
--- a/bundles/org.eclipse.wst.xsl.ui/plugin.properties
+++ b/bundles/org.eclipse.wst.xsl.ui/plugin.properties
@@ -29,4 +29,5 @@
 commandTooltipNewXSDFile = New XML Schema File
 commandTooltipNewXSLFile = New XSL File
 viewNameStylesheet = Stylesheet
-pageSyntaxColoring = Syntax Coloring
\ No newline at end of file
+pageSyntaxColoring = Syntax Coloring
+XSL_Property_validation = XSLT Validation
diff --git a/bundles/org.eclipse.wst.xsl.ui/plugin.xml b/bundles/org.eclipse.wst.xsl.ui/plugin.xml
index 72a2d4a..ee8fbfa 100644
--- a/bundles/org.eclipse.wst.xsl.ui/plugin.xml
+++ b/bundles/org.eclipse.wst.xsl.ui/plugin.xml
@@ -88,7 +88,7 @@
 		</page>
 
 		<page category="org.eclipse.wst.xsl.ui.preferences.BasePreferencePage"
-			class="org.eclipse.wst.xsl.ui.internal.preferences.ValidationPreferencePage"
+			class="org.eclipse.wst.xsl.ui.internal.preferences.XSLValidationPreferencePage"
 			id="org.eclipse.wst.xsl.ui.preferences.Validation" 
 			name="%pageNameValidation">
 		</page>
@@ -334,4 +334,19 @@
 			class="org.eclipse.wst.xsl.ui.internal.preferences.XSLUIPreferenceInitializer" />
 	</extension>
 	
+	<extension point="org.eclipse.ui.propertyPages">
+		<page
+			name="%XSL_Property_validation"
+			class="org.eclipse.wst.xsl.ui.internal.preferences.XSLValidationPreferencePage"
+			id="org.eclipse.wst.xsl.ui.propertyPage.project.validation"
+			category="ValidationPropertiesPage">
+			<enabledWhen>
+				<adapt type="org.eclipse.core.resources.IProject">
+					
+				</adapt>
+			</enabledWhen>
+		</page>		
+	</extension>
+	
+	
 </plugin>
diff --git a/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/AbstractValidationSettingsPage.java b/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/AbstractValidationSettingsPage.java
new file mode 100644
index 0000000..9cea2d8
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/AbstractValidationSettingsPage.java
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.xsl.ui.internal.preferences;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IPreferencesService;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.forms.events.ExpansionAdapter;
+import org.eclipse.ui.forms.events.ExpansionEvent;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.ScrolledPageContent;
+import org.eclipse.wst.validation.ValidationFramework;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * Based on org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock
+ */
+abstract class AbstractValidationSettingsPage extends PropertyPreferencePage {
+
+	private List fCombos;
+	private List fExpandables;
+	
+	private SelectionListener fSelectionListener;
+	
+	private IPreferencesService fPreferencesService = null;
+	
+	private static final String SETTINGS_EXPANDED = "expanded"; //$NON-NLS-1$
+	
+	private ValidationFramework fValidation;
+	
+	private class ComboData {
+		private String fKey;
+		private int[] fSeverities;
+		private int fIndex;
+		int originalSeverity = -2;
+		
+		public ComboData(String key, int[] severities, int index) {
+			fKey = key;
+			fSeverities = severities;
+			fIndex = index;
+		}
+		
+		public String getKey() {
+			return fKey;
+		}
+		
+		public void setIndex(int index) {
+			fIndex = index;
+		}
+		
+		public int getIndex() {
+			return fIndex;
+		}
+		
+		/**
+		 * Sets the severity index based on <code>severity</code>.
+		 * If the severity doesn't exist, the index is set to -1.
+		 * 
+		 * @param severity the severity level
+		 */
+		public void setSeverity(int severity) {
+			for(int i = 0; fSeverities != null && i < fSeverities.length; i++) {
+				if(fSeverities[i] == severity) {
+					fIndex = i;
+					return;
+				}
+			}
+			
+			fIndex = -1;
+		}
+		
+		public int getSeverity() {
+			return (fIndex >= 0 && fSeverities != null && fIndex < fSeverities.length) ? fSeverities[fIndex] : -1;
+		}
+		
+		boolean isChanged() {
+			return fSeverities[fIndex] != originalSeverity;
+		}
+	}
+	
+	public AbstractValidationSettingsPage() {
+		super();
+		fCombos = new ArrayList();
+		fExpandables = new ArrayList();
+		fPreferencesService = Platform.getPreferencesService();
+		fValidation = ValidationFramework.getDefault();
+	}
+	
+	/**
+	 * Creates a Combo widget in the composite <code>parent</code>. The data
+	 * in the Combo is associated with <code>key</code>. The Combo data is
+	 * generated based on the integer <code>values</code> where the index
+	 * of <code>values</code> corresponds to the index of <code>valueLabels</code>
+	 * 
+	 * @param parent the composite to create the combo box in
+	 * @param label the label to give the combo box
+	 * @param key the unique key to identify the combo box
+	 * @param values the values represented by the combo options
+	 * @param valueLabels the calues displayed in the combo box
+	 * @param indent how far to indent the combo box label
+	 * 
+	 * @return the generated combo box
+	 */
+	protected Combo addComboBox(Composite parent, String label, String key, int[] values, String[] valueLabels, int indent) {
+		GridData gd= new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1);
+		gd.horizontalIndent= indent;
+				
+		Label labelControl= new Label(parent, SWT.LEFT);
+		labelControl.setFont(JFaceResources.getDialogFont());
+		labelControl.setText(label);
+		labelControl.setLayoutData(gd);
+				
+		Combo comboBox= newComboControl(parent, key, values, valueLabels);
+		comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+
+		return comboBox;
+	}
+	
+	/**
+	 * Creates a combo box and associates the combo data with the
+	 * combo box.
+	 * 
+	 * @param composite the composite to create the combo box in
+	 * @param key the unique key to identify the combo box
+	 * @param values the values represented by the combo options
+	 * @param valueLabels the values displayed in the combo box
+	 * 
+	 * @return the generated combo box
+	 */
+	protected Combo newComboControl(Composite composite, String key, int[] values, String[] valueLabels) {
+		ComboData data = new ComboData(key, values, -1);
+		
+		Combo comboBox= new Combo(composite, SWT.READ_ONLY);
+		comboBox.setItems(valueLabels);
+		comboBox.setData(data);
+		comboBox.addSelectionListener(getSelectionListener());
+		comboBox.setFont(JFaceResources.getDialogFont());
+			
+		makeScrollableCompositeAware(comboBox);
+		
+		int severity = -1;
+		if(key != null)
+			severity = fPreferencesService.getInt(getPreferenceNodeQualifier(), key, ValidationMessage.WARNING, createPreferenceScopes());
+
+		if (severity == ValidationMessage.ERROR || severity == ValidationMessage.WARNING || severity == ValidationMessage.IGNORE) {
+			data.setSeverity(severity);
+			data.originalSeverity = severity;
+		}
+		
+		if(data.getIndex() >= 0)
+			comboBox.select(data.getIndex());
+		
+		fCombos.add(comboBox);
+		return comboBox;
+	}
+	
+	protected SelectionListener getSelectionListener() {
+		if (fSelectionListener == null) {
+			fSelectionListener= new SelectionListener() {
+				public void widgetDefaultSelected(SelectionEvent e) {}
+	
+				public void widgetSelected(SelectionEvent e) {
+					controlChanged(e.widget);
+				}
+			};
+		}
+		return fSelectionListener;
+	}
+	
+	protected void controlChanged(Widget widget) {
+		ComboData data= (ComboData) widget.getData();
+		if (widget instanceof Combo) {
+			data.setIndex(((Combo)widget).getSelectionIndex());
+		} else {
+			return;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractSettingsPage#storeValues()
+	 */
+	protected void storeValues() {
+		if(fCombos == null || fCombos.size() == 0)
+			return;
+		
+		Iterator it = fCombos.iterator();
+		
+		IScopeContext[] contexts = createPreferenceScopes();
+
+		while(it.hasNext()) {
+			ComboData data = (ComboData) ((Combo)it.next()).getData();
+			if(data.getKey() != null) {
+				contexts[0].getNode(getPreferenceNodeQualifier()).putInt(data.getKey(), data.getSeverity());
+			}
+		}
+		
+		for(int i = 0; i < contexts.length; i++) {
+			try {
+				contexts[i].getNode(getPreferenceNodeQualifier()).flush();
+			}
+			catch (BackingStoreException e) {
+				
+			}
+		}
+	}
+	
+	protected ExpandableComposite getParentExpandableComposite(Control control) {
+		Control parent= control.getParent();
+		while (!(parent instanceof ExpandableComposite) && parent != null) {
+			parent= parent.getParent();
+		}
+		if (parent instanceof ExpandableComposite) {
+			return (ExpandableComposite) parent;
+		}
+		return null;
+	}
+	
+	protected ExpandableComposite createTwistie(Composite parent, String label, int nColumns) {
+		ExpandableComposite excomposite= new ExpandableComposite(parent, SWT.NONE, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT);
+		excomposite.setText(label);
+		excomposite.setExpanded(false);
+		excomposite.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
+		excomposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, nColumns, 1));
+		excomposite.addExpansionListener(new ExpansionAdapter() {
+			public void expansionStateChanged(ExpansionEvent e) {
+				expandedStateChanged((ExpandableComposite) e.getSource());
+			}
+		});
+		fExpandables.add(excomposite);
+		makeScrollableCompositeAware(excomposite);
+		return excomposite;
+	}
+	
+	protected final void expandedStateChanged(ExpandableComposite expandable) {
+		ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(expandable);
+		if (parentScrolledComposite != null) {
+			parentScrolledComposite.reflow(true);
+		}
+	}
+	
+	private void makeScrollableCompositeAware(Control control) {
+		ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(control);
+		if (parentScrolledComposite != null) {
+			parentScrolledComposite.adaptChild(control);
+		}
+	}
+	
+	protected ScrolledPageContent getParentScrolledComposite(Control control) {
+		Control parent= control.getParent();
+		while (!(parent instanceof ScrolledPageContent) && parent != null) {
+			parent= parent.getParent();
+		}
+		if (parent instanceof ScrolledPageContent) {
+			return (ScrolledPageContent) parent;
+		}
+		return null;
+	}
+	
+	protected void storeSectionExpansionStates(IDialogSettings section) {
+		for(int i = 0; i < fExpandables.size(); i++) {
+			ExpandableComposite comp = (ExpandableComposite) fExpandables.get(i);
+			section.put(SETTINGS_EXPANDED + String.valueOf(i), comp.isExpanded());
+		}
+	}
+	
+	protected void restoreSectionExpansionStates(IDialogSettings settings) {
+		for (int i= 0; i < fExpandables.size(); i++) {
+			ExpandableComposite excomposite= (ExpandableComposite) fExpandables.get(i);
+			if (settings == null) {
+				excomposite.setExpanded(i == 0); // only expand the first node by default
+			} else {
+				excomposite.setExpanded(settings.getBoolean(SETTINGS_EXPANDED + String.valueOf(i)));
+			}
+		}
+	}
+	
+	protected void resetSeverities() {
+		IEclipsePreferences defaultContext = new DefaultScope().getNode(getPreferenceNodeQualifier());
+		for(int i = 0; i < fCombos.size(); i++) {
+			ComboData data = (ComboData)((Combo)fCombos.get(i)).getData();
+			int severity = defaultContext.getInt(data.getKey(), ValidationMessage.WARNING);
+			data.setSeverity(severity);
+			((Combo)fCombos.get(i)).select(data.getIndex());
+		}
+	}
+	
+	protected boolean shouldRevalidateOnSettingsChange() {
+		Iterator it = fCombos.iterator();
+
+		while (it.hasNext()) {
+			ComboData data = (ComboData) ((Combo) it.next()).getData();
+			if (data.isChanged())
+				return true;
+		}
+		return false;
+	}
+	
+	public boolean performOk() {
+		if(super.performOk() && shouldRevalidateOnSettingsChange()) {
+			MessageBox mb = new MessageBox(this.getShell(), SWT.APPLICATION_MODAL | SWT.YES | SWT.NO | SWT.CANCEL | SWT.ICON_INFORMATION | SWT.RIGHT);
+			mb.setText("XSL Validation");
+			/* Choose which message to use based on if its project or workspace settings */
+			String msg = (getProject() == null) ? "XSL Workspace Validation" : "XSL Project Level Validation";
+			mb.setMessage(msg);
+			switch(mb.open()) {
+				case SWT.CANCEL:
+					return false;
+				case SWT.YES:
+					ValidateJob job = new ValidateJob("XSL Validation Job");
+					job.schedule();
+				case SWT.NO:
+				default:
+					return true;
+			}
+		}
+		return true;
+	}
+	
+	/**
+	 * Performs validation after validation preferences have been modified.
+	 */
+	private class ValidateJob extends Job {
+		
+		public ValidateJob(String name) {
+			super(name);
+		}
+
+		protected IStatus run(IProgressMonitor monitor) {
+			IStatus status = Status.OK_STATUS;
+			try {
+				IProject[] projects = null;
+				/* Changed preferences for a single project, only validate it */
+				if(getProject() != null)
+					projects = new IProject[] {getProject()};
+				/* Workspace-wide preferences changed */
+				else {
+					/* Get all of the projects in the workspace */
+					projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+					IEclipsePreferences prefs = null;
+					List projectList = new ArrayList();
+					
+					/* Filter out projects that use project-specific settings or have been closed */
+					for(int i = 0; i < projects.length; i++) {
+						prefs = new ProjectScope(projects[i]).getNode(getPreferenceNodeQualifier());
+						if(projects[i].isAccessible() && !prefs.getBoolean(getProjectSettingsKey(), false))
+							projectList.add(projects[i]);
+					}
+					projects = (IProject[]) projectList.toArray(new IProject[projectList.size()]);
+				}
+				fValidation.validate(projects, true, false, monitor);
+			}
+			catch (CoreException ce) {
+				status = Status.CANCEL_STATUS;
+			}
+			
+			return status;
+		}
+		
+	}
+	
+}
diff --git a/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/PropertyPreferencePage.java b/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/PropertyPreferencePage.java
new file mode 100644
index 0000000..f1ad77b
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/PropertyPreferencePage.java
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 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
+ *     Jens Lukowski/Innoopract - initial renaming/restructuring
+ *     
+ *******************************************************************************/
+package org.eclipse.wst.xsl.ui.internal.preferences;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.dialogs.ControlEnableState;
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.dialogs.ListDialog;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.eclipse.ui.dialogs.PropertyPage;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.ui.views.navigator.ResourceSorter;
+import org.eclipse.wst.sse.core.internal.tasks.TaskTagPreferenceKeys;
+import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
+import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
+
+/**
+ * Based loosely on org.eclipse.jdt.internal.ui.preferences.PropertyAndPreferencePage
+ */
+abstract class PropertyPreferencePage extends PropertyPage implements IWorkbenchPreferencePage {
+	private static final boolean _debugPreferences = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/preferences-properties")); //$NON-NLS-1$ //$NON-NLS-2$
+	/*
+	 * Disable link data, prevents the display of a "workspace" or "project"
+	 * settings link to prevent recursive dialog launching
+	 */
+	private static final Object DISABLE_LINK = "DISABLE_LINK"; //$NON-NLS-1$
+
+	private Map Data = null;
+
+	private Button EnableProjectSettings;
+
+	private Link ProjectSettingsLink;
+	
+	private Control Common;
+	
+	private ControlEnableState Enablements;
+
+	public PropertyPreferencePage() {
+		super();
+	}
+
+	public final void applyData(Object data) {
+		super.applyData(data);
+		if (data instanceof Map) {
+			Data = (Map) data;
+			updateLinkEnablement();
+		}
+	}
+
+	protected abstract Control createCommonContents(Composite composite);
+
+	public final Control createContents(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+
+		GridLayout layout = new GridLayout();
+		composite.setLayout(layout);
+		GridData data = new GridData(GridData.FILL_BOTH);
+		composite.setLayoutData(data);
+
+		Composite checkLinkComposite = new Composite(composite, SWT.NONE);
+		checkLinkComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+		checkLinkComposite.setLayout(new GridLayout(2, false));
+
+		if (getProject() != null) {
+			EnableProjectSettings = new Button(checkLinkComposite, SWT.CHECK);
+			EnableProjectSettings.setText(SSEUIMessages.EnableProjectSettings); //$NON-NLS-1$//$NON-NLS-2$
+			EnableProjectSettings.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
+			boolean enabledForProject = createPreferenceScopes()[0].getNode(getPreferenceNodeQualifier()).getBoolean(getProjectSettingsKey(), false);
+			EnableProjectSettings.setSelection(enabledForProject);
+		}
+		else {
+			Label spacer = new Label(checkLinkComposite, SWT.CHECK);
+			spacer.setLayoutData(new GridData());
+		}
+
+		ProjectSettingsLink = new Link(checkLinkComposite, SWT.NONE);
+		ProjectSettingsLink.setLayoutData(new GridData(SWT.END, SWT.BEGINNING, true, false));
+
+		/*
+		 * "element" should be a project, if null, link to per-project
+		 * properties
+		 */
+		if (getProject() != null) {
+			ProjectSettingsLink.setText("<a>" + SSEUIMessages.ConfigureWorkspaceSettings + "</a>"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+		else {
+			ProjectSettingsLink.setText("<a>" + SSEUIMessages.ConfigureProjectSettings + "</a>"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+
+		updateLinkEnablement();
+
+		ProjectSettingsLink.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {
+				widgetSelected(e);
+			}
+
+			public void widgetSelected(SelectionEvent e) {
+				if (getProject() == null) {
+					openProjectSettings();
+				}
+				else {
+					openWorkspaceSettings();
+				}
+			}
+
+		});
+
+		if (getProject() != null) {
+			Label line = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
+			line.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		}
+
+//		final Control common = createCommonContents(composite);
+		Common = createCommonContents(composite);
+		
+		Common.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		if (EnableProjectSettings != null) {
+			SelectionAdapter selectionAdapter = new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					super.widgetSelected(e);
+					enablePreferenceContent(EnableProjectSettings.getSelection());
+				}
+			};
+			selectionAdapter.widgetSelected(null);
+			EnableProjectSettings.addSelectionListener(selectionAdapter);
+		}
+		
+		applyDialogFont(composite);
+		return composite;
+	}
+
+	protected IScopeContext[] createPreferenceScopes() {
+		IProject project = getProject();
+		if (project != null) {
+			return new IScopeContext[]{new ProjectScope(project), new InstanceScope(), new DefaultScope()};
+		}
+		return new IScopeContext[]{new InstanceScope(), new DefaultScope()};
+	}
+
+	protected abstract String getPreferenceNodeQualifier();
+
+	protected abstract String getPreferencePageID();
+
+	protected IProject getProject() {
+		if (getElement() != null) {
+			if (getElement() instanceof IProject) {
+				return (IProject) getElement();
+			}
+			Object adapter = getElement().getAdapter(IProject.class);
+			if (adapter instanceof IProject) {
+				return (IProject) adapter;
+			}
+			adapter = getElement().getAdapter(IResource.class);
+			if (adapter instanceof IProject) {
+				return (IProject) adapter;
+			}
+		}
+		return null;
+	}
+
+	protected abstract String getProjectSettingsKey();
+
+	protected abstract String getPropertyPageID();
+
+	protected boolean isElementSettingsEnabled() {
+		return EnableProjectSettings != null && EnableProjectSettings.getSelection();
+	}
+
+	void openProjectSettings() {
+		ListDialog dialog = new ListDialog(getShell()) {
+
+			protected Control createDialogArea(Composite container) {
+				Control area = super.createDialogArea(container);
+				getTableViewer().setSorter(new ResourceSorter(ResourceSorter.NAME));
+				return area;
+			}
+		};
+		dialog.setMessage(SSEUIMessages.PropertyPreferencePage_02);
+		dialog.setContentProvider(new IStructuredContentProvider() {
+			public void dispose() {
+			}
+
+			public Object[] getElements(Object inputElement) {
+				return ((IWorkspace) inputElement).getRoot().getProjects();
+			}
+
+			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			}
+		});
+		dialog.setLabelProvider(new DecoratingLabelProvider(new WorkbenchLabelProvider(), SSEUIPlugin.getDefault().getWorkbench().getDecoratorManager().getLabelDecorator()));
+		dialog.setInput(ResourcesPlugin.getWorkspace());
+		dialog.setTitle(SSEUIMessages.PropertyPreferencePage_01);
+		if (dialog.open() == Window.OK) {
+			Object[] result = dialog.getResult();
+			if (result.length > 0) {
+				IProject project = (IProject) dialog.getResult()[0];
+				Map data = new HashMap();
+				data.put(DISABLE_LINK, Boolean.TRUE);
+				PreferencesUtil.createPropertyDialogOn(getShell(), project, getPropertyPageID(), new String[]{getPropertyPageID()}, data).open();
+			}
+		}
+	}
+
+	void openWorkspaceSettings() {
+		Map data = new HashMap();
+		data.put(DISABLE_LINK, Boolean.TRUE);
+		PreferencesUtil.createPreferenceDialogOn(getShell(), getPreferencePageID(), new String[]{getPreferencePageID()}, data).open();
+	}
+
+	public boolean performOk() {
+		boolean ok = super.performOk();
+		IScopeContext[] preferenceScopes = createPreferenceScopes();
+		if (getProject() != null) {
+			if (isElementSettingsEnabled()) {
+				if (_debugPreferences) {
+					System.out.println(getClass().getName() + " setting " + TaskTagPreferenceKeys.TASK_TAG_PER_PROJECT + " (" + true + ") in scope " + preferenceScopes[0].getName() + ":" + preferenceScopes[0].getLocation()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$  
+				}
+				preferenceScopes[0].getNode(getPreferenceNodeQualifier()).putBoolean(getProjectSettingsKey(), EnableProjectSettings.getSelection());
+			}
+			else {
+				if (_debugPreferences) {
+					System.out.println(getClass().getName() + " removing " + TaskTagPreferenceKeys.TASK_TAG_PER_PROJECT + " from scope " + preferenceScopes[0].getName() + ":" + preferenceScopes[0].getLocation()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+				}
+				preferenceScopes[0].getNode(getPreferenceNodeQualifier()).remove(getProjectSettingsKey());
+			}
+		}
+		return ok;
+	}
+	
+	protected void performDefaults() {
+		if(getProject() != null && EnableProjectSettings != null) {
+			EnableProjectSettings.setSelection(false);
+			enablePreferenceContent(false);
+		}
+		super.performDefaults();
+	}
+
+	private void updateLinkEnablement() {
+		if (Data != null && ProjectSettingsLink != null) {
+			ProjectSettingsLink.setEnabled(!Boolean.TRUE.equals(Data.get(DISABLE_LINK)));
+		}
+	}
+	
+	/**
+	 * Controls the enablement of the common content region
+	 * of a property or preference page
+	 * 
+	 * @param enable the enabled state of the common content
+	 * area
+	 */
+	protected void enablePreferenceContent(boolean enable) {
+		if(enable) {
+			if(Enablements != null) {
+				Enablements.restore();
+				Enablements = null;
+			}
+		}
+		else {
+			if(Enablements == null)
+				Enablements = ControlEnableState.disable(Common);
+		}
+	}
+}
diff --git a/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/XSLUIPreferenceInitializer.java b/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/XSLUIPreferenceInitializer.java
index da4eae8..021e043 100755
--- a/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/XSLUIPreferenceInitializer.java
+++ b/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/XSLUIPreferenceInitializer.java
@@ -13,6 +13,8 @@
 package org.eclipse.wst.xsl.ui.internal.preferences;
 
 import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.resource.ColorRegistry;
 import org.eclipse.jface.text.templates.Template;
@@ -20,6 +22,7 @@
 import org.eclipse.wst.sse.ui.internal.preferences.ui.ColorHelper;
 import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
 import org.eclipse.wst.xml.ui.internal.style.IStyleConstantsXML;
+import org.eclipse.wst.xsl.core.internal.XSLCorePlugin;
 import org.eclipse.wst.xsl.ui.internal.XSLUIPlugin;
 import org.eclipse.wst.xsl.ui.internal.style.IStyleConstantsXSL;
 
@@ -34,6 +37,7 @@
 	 * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
 	 */
 	public void initializeDefaultPreferences() {
+		IEclipsePreferences node = new DefaultScope().getNode(XSLCorePlugin.getDefault().getBundle().getSymbolicName());
 		IPreferenceStore store = XSLUIPlugin.getDefault().getPreferenceStore();
 		ColorRegistry registry = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry();
 
diff --git a/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/XSLValidationPreferencePage.java b/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/XSLValidationPreferencePage.java
new file mode 100644
index 0000000..8ef04b3
--- /dev/null
+++ b/bundles/org.eclipse.wst.xsl.ui/src/org/eclipse/wst/xsl/ui/internal/preferences/XSLValidationPreferencePage.java
@@ -0,0 +1,289 @@
+package org.eclipse.wst.xsl.ui.internal.preferences;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.forms.events.ExpansionAdapter;
+import org.eclipse.ui.forms.events.ExpansionEvent;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.ScrolledPageContent;
+import org.eclipse.wst.xsl.core.ValidationPreferences;
+import org.eclipse.wst.xsl.core.internal.XSLCorePlugin;
+import org.eclipse.wst.xsl.ui.internal.XSLUIPlugin;
+
+public class XSLValidationPreferencePage extends AbstractValidationSettingsPage implements ModifyListener {
+
+	private static final String[] ERRORS = new String[] { "Error", "Warning", "Ignore" };
+	private static final int[] ERROR_VALUES = new int[] { IMarker.SEVERITY_ERROR, IMarker.SEVERITY_WARNING, IMarker.SEVERITY_INFO };
+	private static final Map<Integer, Integer> ERROR_MAP = new HashMap<Integer, Integer>();
+	private Text maxErrorsText;
+	private Map<String, Combo> combos = new HashMap<String, Combo>();
+	private List<ExpandableComposite> Expandables = new ArrayList<ExpandableComposite>();
+	private static final String SETTINGS_SECTION_NAME = "XSLValidationSeverities";//$NON-NLS-1$
+
+
+
+	static
+	{
+		ERROR_MAP.put(IMarker.SEVERITY_ERROR, 0);
+		ERROR_MAP.put(IMarker.SEVERITY_WARNING, 1);
+		ERROR_MAP.put(IMarker.SEVERITY_INFO, 2);
+	}
+	
+	@Override
+	protected Composite createCommonContents(Composite parent)
+	{
+		GridLayout layout= new GridLayout();
+		layout.numColumns= 2;
+		layout.marginHeight= 0;
+		layout.marginWidth= 0;
+		
+		final ScrolledPageContent pageContent = new ScrolledPageContent(parent);
+		pageContent.setLayoutData(new GridData(GridData.FILL_BOTH));
+		pageContent.setExpandHorizontal(true);
+		pageContent.setExpandVertical(true);
+		
+		Composite body = pageContent.getBody();
+		body.setLayout(layout);
+
+		GridData gd= new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1);
+		gd.horizontalIndent= 0;
+
+		Label description = new Label(body, SWT.NONE);
+		description.setText("Select the serverity level for the following validation problems:");
+		description.setFont(pageContent.getFont());
+		description.setLayoutData(gd);
+		
+
+		createLabel(body, "Maximum number of errors reported per stylesheet:");
+		maxErrorsText = createTextField(body);
+		maxErrorsText.addModifyListener(this);
+
+		ExpandableComposite twistie;
+		
+		int columns = 3;
+		twistie = createTwistie(body,"Imports and Includes",columns);
+		Composite inner = createInnerComposite(parent, twistie, columns);
+		
+		String label = "Unresolved include/import:";
+		createCombo(inner, label, ValidationPreferences.MISSING_INCLUDE);
+
+		label = "Unresolved include/import:";
+		inner = createInnerComposite(parent, twistie, columns);
+		createCombo(inner, label, ValidationPreferences.MISSING_INCLUDE);
+		createCombo(inner, "Circular references:", ValidationPreferences.CIRCULAR_REF);
+
+		twistie = createTwistie(body,"Named Templates",columns);
+		inner = createInnerComposite(parent, twistie, columns);
+		
+		createCombo(inner, "Template name conflicts:", ValidationPreferences.TEMPLATE_CONFLICT);
+		createCombo(inner, "Duplicate parameterw:", ValidationPreferences.DUPLICATE_PARAMETER);
+		createCombo(inner, "Parameter without name attribute:", ValidationPreferences.NAME_ATTRIBUTE_MISSING);
+		createCombo(inner, "Parameter with empty name attribute:", ValidationPreferences.NAME_ATTRIBUTE_EMPTY);
+		
+		twistie = createTwistie(body,"Template Calls",columns);
+		inner = createInnerComposite(parent, twistie, columns);
+		
+		createCombo(inner, "Unresolved templates:", ValidationPreferences.CALL_TEMPLATES);
+		createCombo(inner, "Missing parameters:", ValidationPreferences.MISSING_PARAM);
+		createCombo(inner, "Parameters without value:", ValidationPreferences.EMPTY_PARAM);
+
+		twistie = createTwistie(body,"XPath Problems",columns);
+		inner = createInnerComposite(parent, twistie, columns);
+		createCombo(inner, "Incorrect XPath syntax:", ValidationPreferences.XPATHS);
+
+		loadPreferences();
+		restoreSectionExpansionStates(getDialogSettings().getSection(SETTINGS_SECTION_NAME));
+		
+		return parent;
+	}
+
+	private Composite createInnerComposite(Composite parent,
+			ExpandableComposite twistie, int columns) {
+		Composite inner = new Composite(twistie, SWT.NONE);
+		inner.setFont(parent.getFont());
+		inner.setLayout(new GridLayout(columns, false));
+		twistie.setClient(inner);
+		return inner;
+	}
+	
+	protected Combo createCombo(Composite parent, String label, String key) {
+		return addComboBox(parent, label, key, ERROR_VALUES, ERRORS, 0);
+	}
+	
+	protected Label createLabel(Composite parent, String text) {
+		Label label = new Label(parent, SWT.LEFT);
+		label.setText(text);
+
+
+		//GridData
+		GridData data = new GridData(GridData.FILL);
+		data.verticalAlignment = GridData.CENTER;
+		data.horizontalAlignment = GridData.FILL;
+		label.setLayoutData(data);
+
+		return label;
+	}
+	
+	protected Text createTextField(Composite parent) {
+		Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
+
+		//GridData
+		GridData data = new GridData();
+		data.verticalAlignment = GridData.CENTER;
+		data.horizontalAlignment = GridData.FILL;
+		data.grabExcessHorizontalSpace = true;
+		text.setLayoutData(data);
+
+		return text;
+	}
+	
+	protected ExpandableComposite createTwistie(Composite parent, String label, int nColumns) {
+		ExpandableComposite excomposite= new ExpandableComposite(parent, SWT.NONE, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT);
+		excomposite.setText(label);
+		excomposite.setExpanded(false);
+		excomposite.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
+		excomposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, nColumns, 1));
+		excomposite.addExpansionListener(new ExpansionAdapter() {
+			public void expansionStateChanged(ExpansionEvent e) {
+				expandedStateChanged((ExpandableComposite) e.getSource());
+			}
+		});
+		Expandables.add(excomposite);
+		makeScrollableCompositeAware(excomposite);
+		return excomposite;
+	}
+	
+	private void makeScrollableCompositeAware(Control control)
+	{
+		ScrolledPageContent parentScrolledComposite = getParentScrolledComposite(control);
+		if (parentScrolledComposite != null)
+		{
+			parentScrolledComposite.adaptChild(control);
+		}
+	}
+	
+	
+	@Override
+	protected String getPreferenceNodeQualifier() {
+		return XSLCorePlugin.getDefault().getBundle().getSymbolicName();
+	}
+
+	@Override
+	protected String getPreferencePageID() {
+		return "org.eclipse.wst.xsl.ui.preferences.Validation";
+	}
+
+	@Override
+	protected String getProjectSettingsKey() {
+		return XSLCorePlugin.USE_PROJECT_SETTINGS;
+	}
+	
+	protected IDialogSettings getDialogSettings() {
+		return XSLUIPlugin.getDefault().getDialogSettings();
+	}	
+
+	@Override
+	protected String getPropertyPageID() {
+		return "org.eclipse.wst.xsl.ui.propertyPage.project.validation";
+	}
+
+	public void init(IWorkbench workbench) {
+
+	}
+
+	public void modifyText(ModifyEvent e) {
+		// If we are called too early, i.e. before the controls are created
+		// then return
+		// to avoid null pointer exceptions
+		if (e.widget != null && e.widget.isDisposed())
+			return;
+
+		validateValues();
+		enableValues();
+	}
+
+
+	@Override
+	protected void storeValues()
+	{
+		int maxErrors = Integer.parseInt(maxErrorsText.getText());
+		getModelPreferences().setValue(ValidationPreferences.MAX_ERRORS, maxErrors);
+		for (Map.Entry<String, Combo> entry : combos.entrySet())
+		{
+			int index = entry.getValue().getSelectionIndex();
+			getModelPreferences().setValue(entry.getKey(), ERROR_VALUES[index]);
+		}
+		super.storeValues();
+	}
+	
+	protected Preferences getModelPreferences()
+	{
+		return XSLCorePlugin.getDefault().getPluginPreferences();
+	}
+
+	protected boolean loadPreferences() {
+		BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
+			public void run() {
+				initializeValues();
+				validateValues();
+				enableValues();
+			}
+		});
+		return true;
+	}
+	
+	protected void initializeValues()
+	{
+		int maxErrors = getModelPreferences().getInt(ValidationPreferences.MAX_ERRORS);
+		maxErrorsText.setText(String.valueOf(maxErrors));
+		for (Map.Entry<String, Combo> entry : combos.entrySet())
+		{
+			int val = getModelPreferences().getInt(entry.getKey());
+			entry.getValue().select(ERROR_MAP.get(val));
+		}
+	}
+	
+	protected void validateValues()
+	{
+		String errorMessage = null;
+		try
+		{
+			int maxErrors = Integer.parseInt(maxErrorsText.getText());
+			if (maxErrors < 0)
+				errorMessage = "Max errors must be a positive integer";
+		}
+		catch (NumberFormatException e)
+		{
+			errorMessage = "Max errors must be a positive integer";
+		}
+		setErrorMessage(errorMessage);
+		setValid(errorMessage == null);
+	}	
+	
+	protected void enableValues() {
+	}	
+	
+	protected void performDefaults() {
+		resetSeverities();
+		super.performDefaults();
+	}	
+}