[224238] Make validation message severity user controllable
diff --git a/bundles/org.eclipse.jst.jsp.ui/plugin.properties b/bundles/org.eclipse.jst.jsp.ui/plugin.properties
index 91e74ba..24649a3 100644
--- a/bundles/org.eclipse.jst.jsp.ui/plugin.properties
+++ b/bundles/org.eclipse.jst.jsp.ui/plugin.properties
@@ -19,6 +19,8 @@
 JSP_Styles.name=Styles
 JSP_Syntax_Coloring=Syntax Coloring
 JSP_Source_target_name=JSP Source
+JSP_Validation=Validation
+JSP_Property_validation=JSP Syntax
 
 # Snippets contributions for helping with JSP syntax
 jsp_scriptlet=<%..%> scriptlet
@@ -50,6 +52,7 @@
 JSP_Type_Move_Participant_Extension_Element.name=JSP Type Move Participant
 All_JSP_context_type_Extension_Element.name=All JSP
 JSP_New_context_type_Extension_Element.name=New JSP
+Tag_New_context_type_Extension_Element.name=New Tag
 JSP_Tag_context_type_Extension_Element.name=JSP Tag
 JSP_Attribute_context_type_Extension_Element.name=JSP Attribute
 JSP_Attribute_value_context_type_Extension_Element.name=JSP Attribute value
@@ -58,6 +61,8 @@
 #org.eclipse.ui.newWizards extension point
 _UI_WIZARD_NAME = JSP
 _UI_WIZARD_CREATE_NEW_FILE = Create a new JavaServer Page
+_UI_WIZARD_TAG_NAME = Tag
+_UI_WIZARD_TAG_CREATE_NEW_FILE = Create a new Tag file
 ##
 AddTask.label=Add &Task...
 AddTask.tooltip=Add Task...
@@ -90,6 +95,8 @@
 preferenceKeywords.templates=editor jsp templates snippet macros
 preferenceKeywords.styles=editor jsp style customize syntax highlighting type text content foreground background bold color
 preferenceKeywords.fragments=editor jsp fragment language content type validate
+preferenceKeywords.severities=errors warnings ignore options severity severities suppress project specific projectspecific
+
 ##
 JSPJava_hyperlink=Java Content In JSP
-Taglib_hyperlink=Taglib Directive
\ No newline at end of file
+Taglib_hyperlink=Taglib Directive
diff --git a/bundles/org.eclipse.jst.jsp.ui/plugin.xml b/bundles/org.eclipse.jst.jsp.ui/plugin.xml
index e50b382..c98347c 100644
--- a/bundles/org.eclipse.jst.jsp.ui/plugin.xml
+++ b/bundles/org.eclipse.jst.jsp.ui/plugin.xml
@@ -60,7 +60,7 @@
 			target="org.eclipse.jst.jsp.core.jspsource" />
 		<provisionalDefinition
 			type="preferencepages"
-			value="org.eclipse.jst.jsp.ui.preferences.jsp, org.eclipse.wst.sse.ui.preferences.jsp.source, org.eclipse.wst.sse.ui.preferences.jsp.templates, org.eclipse.wst.sse.ui.preferences.jsp.styles"
+			value="org.eclipse.jst.jsp.ui.preferences.jsp, org.eclipse.wst.sse.ui.preferences.jsp.source, org.eclipse.wst.sse.ui.preferences.jsp.templates, org.eclipse.wst.sse.ui.preferences.jsp.styles,,org.eclipse.jst.jsp.ui.preferences.validation"
 			target="org.eclipse.jst.jsp.core.jspsource" />
 		<provisionalDefinition
 			type="showintarget"
@@ -202,7 +202,7 @@
 			category="org.eclipse.wst.html.ui.preferences.web"
 			class="org.eclipse.jst.jsp.ui.internal.preferences.ui.JSPFilesPreferencePage"
 			id="org.eclipse.jst.jsp.ui.preferences.jsp">
-			<keywordReference id="org.eclipse.wst.jsp.ui.files"/>
+			<keywordReference id="org.eclipse.jst.jsp.ui.files"/>
 		</page>
 		<page
 			name="%JSP_Source.name"
@@ -215,14 +215,21 @@
 			category="org.eclipse.wst.sse.ui.preferences.jsp.source"
 			class="org.eclipse.jst.jsp.ui.internal.preferences.ui.JSPTemplatePreferencePage"
 			id="org.eclipse.wst.sse.ui.preferences.jsp.templates">
-			<keywordReference id="org.eclipse.wst.jsp.ui.templates"/>
+			<keywordReference id="org.eclipse.jst.jsp.ui.templates"/>
 		</page>
 		<page
 			name="%JSP_Syntax_Coloring"
 			category="org.eclipse.wst.sse.ui.preferences.jsp.source"
 			class="org.eclipse.jst.jsp.ui.internal.preferences.ui.JSPSyntaxColoringPage"
 			id="org.eclipse.wst.sse.ui.preferences.jsp.styles">
-			<keywordReference id="org.eclipse.wst.jsp.ui.styles"/>
+			<keywordReference id="org.eclipse.jst.jsp.ui.styles"/>
+		</page>
+		<page
+			name="%JSP_Validation"
+			category="org.eclipse.jst.jsp.ui.preferences.jsp"
+			class="org.eclipse.jst.jsp.ui.internal.preferences.ui.JSPValidationPreferencePage"
+			id="org.eclipse.jst.jsp.ui.preferences.validation">
+			<keywordReference id="org.eclipse.jst.jsp.ui.severities"/>
 		</page>
 	</extension>
 	
@@ -230,16 +237,19 @@
 	<extension point="org.eclipse.ui.keywords">
 		<keyword
 			label="%preferenceKeywords.files"
-			id="org.eclipse.wst.jsp.ui.files"/>
+			id="org.eclipse.jst.jsp.ui.files"/>
 		<keyword
 			label="%preferenceKeywords.templates"
-			id="org.eclipse.wst.jsp.ui.templates"/>
+			id="org.eclipse.jst.jsp.ui.templates"/>
 		<keyword
 			label="%preferenceKeywords.styles"
-			id="org.eclipse.wst.jsp.ui.styles"/>
+			id="org.eclipse.jst.jsp.ui.styles"/>
 		<keyword
 			label="%preferenceKeywords.fragments"
-			id="org.eclipse.wst.jsp.ui.fragments"/>
+			id="org.eclipse.jst.jsp.ui.fragments"/>
+		<keyword
+			label="%preferenceKeywords.severities"
+			id="org.eclipse.jst.jsp.ui.severities"/>
     </extension>
 
 	<!--======================================================================================-->
@@ -486,6 +496,11 @@
 			id="jsp_new" />
 
 		<contextType
+			name="%Tag_New_context_type_Extension_Element.name"
+			class="org.eclipse.jst.jsp.ui.internal.templates.TemplateContextTypeJSP"
+			id="tag_new" />
+
+		<contextType
 			name="%JSP_Tag_context_type_Extension_Element.name"
 			class="org.eclipse.jst.jsp.ui.internal.templates.TemplateContextTypeJSP"
 			id="jsp_tag" />
@@ -545,9 +560,19 @@
 			<description>%_UI_WIZARD_CREATE_NEW_FILE</description>
 			<selection class="org.eclipse.core.resources.IResource" />
 		</wizard>
+
+		<wizard
+			id="org.eclipse.jst.jsp.ui.internal.wizard.NewTagWizard"
+			name="%_UI_WIZARD_TAG_NAME"
+			class="org.eclipse.jst.jsp.ui.internal.wizard.NewTagWizard"
+			category="org.eclipse.wst.web.ui"
+			icon="$nl$/icons/full/etool16/newjsp_wiz.gif">
+			<description>%_UI_WIZARD_TAG_CREATE_NEW_FILE</description>
+			<selection class="org.eclipse.core.resources.IResource" />
+		</wizard>
 	</extension>
 
-	<!-- Add new JSP wizard to J2EE Project Navigator -->
+	<!-- Add new JSP wizard to Project Explorer -->
 	<extension
 		id="org.eclipse.jst.jsp.commonWizard.newJSP"
 		point="org.eclipse.ui.navigator.navigatorContent">
@@ -775,7 +800,7 @@
 					</adapt>
 				</and> 
 			</enabledWhen>
-			<keywordReference id="org.eclipse.wst.jsp.ui.fragments"/>
+			<keywordReference id="org.eclipse.jst.jsp.ui.fragments"/>
 		</page>
 		<page
 			name="%JSPFragmentContentSettings.name"
@@ -797,7 +822,19 @@
 					</adapt>
 				</and> 
 			</enabledWhen>
-			<keywordReference id="org.eclipse.wst.jsp.ui.fragments"/>
+			<keywordReference id="org.eclipse.jst.jsp.ui.fragments"/>
+		</page>
+		<page
+			name="%JSP_Property_validation" 
+			class="org.eclipse.jst.jsp.ui.internal.preferences.ui.JSPValidationPreferencePage"
+			id="org.eclipse.jst.jsp.ui.propertyPage.project.validation"
+			category="ValidationPropertiesPage">
+			<enabledWhen>
+				<adapt type="org.eclipse.core.resources.IProject">
+					<test property="org.eclipse.core.resources.projectNature" value="org.eclipse.jdt.core.javanature"/>
+				</adapt>
+			</enabledWhen>
+			<keywordReference id="org.eclipse.jst.jsp.ui.severities"/>
 		</page>
 	</extension>	
 	<!--  jsp-for-css editor configurations -->		
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/AbstractPropertyPreferencePage.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/AbstractPropertyPreferencePage.java
new file mode 100644
index 0000000..25b9311
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/AbstractPropertyPreferencePage.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.jst.jsp.ui.internal.preferences.ui;
+
+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 AbstractPropertyPreferencePage 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 fData = null;
+
+	private Button fEnableProjectSettings;
+
+	private Link fProjectSettingsLink;
+	
+	private Control fCommon;
+	
+	private ControlEnableState fEnablements;
+
+	public AbstractPropertyPreferencePage() {
+		super();
+	}
+
+	public final void applyData(Object data) {
+		super.applyData(data);
+		if (data instanceof Map) {
+			fData = (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) {
+			fEnableProjectSettings = new Button(checkLinkComposite, SWT.CHECK);
+			fEnableProjectSettings.setText(SSEUIMessages.EnableProjectSettings); //$NON-NLS-1$//$NON-NLS-2$
+			fEnableProjectSettings.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
+			boolean enabledForProject = createPreferenceScopes()[0].getNode(getPreferenceNodeQualifier()).getBoolean(getProjectSettingsKey(), false);
+			fEnableProjectSettings.setSelection(enabledForProject);
+		}
+		else {
+			Label spacer = new Label(checkLinkComposite, SWT.CHECK);
+			spacer.setLayoutData(new GridData());
+		}
+
+		fProjectSettingsLink = new Link(checkLinkComposite, SWT.NONE);
+		fProjectSettingsLink.setLayoutData(new GridData(SWT.END, SWT.BEGINNING, true, false));
+
+		/*
+		 * "element" should be a project, if null, link to per-project
+		 * properties
+		 */
+		if (getProject() != null) {
+			fProjectSettingsLink.setText("<a>" + SSEUIMessages.ConfigureWorkspaceSettings + "</a>"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+		else {
+			fProjectSettingsLink.setText("<a>" + SSEUIMessages.ConfigureProjectSettings + "</a>"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+
+		updateLinkEnablement();
+
+		fProjectSettingsLink.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);
+		fCommon = createCommonContents(composite);
+		
+		fCommon.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		if (fEnableProjectSettings != null) {
+			SelectionAdapter selectionAdapter = new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					super.widgetSelected(e);
+					enablePreferenceContent(fEnableProjectSettings.getSelection());
+				}
+			};
+			selectionAdapter.widgetSelected(null);
+			fEnableProjectSettings.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 fEnableProjectSettings != null && fEnableProjectSettings.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(), fEnableProjectSettings.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 && fEnableProjectSettings != null) {
+			fEnableProjectSettings.setSelection(false);
+			enablePreferenceContent(false);
+		}
+		super.performDefaults();
+	}
+
+	private void updateLinkEnablement() {
+		if (fData != null && fProjectSettingsLink != null) {
+			fProjectSettingsLink.setEnabled(!Boolean.TRUE.equals(fData.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(fEnablements != null) {
+				fEnablements.restore();
+				fEnablements = null;
+			}
+		}
+		else {
+			if(fEnablements == null)
+				fEnablements = ControlEnableState.disable(fCommon);
+		}
+	}
+}
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/AbstractValidationSettingsPage.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/AbstractValidationSettingsPage.java
new file mode 100644
index 0000000..b6aa10f
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/AbstractValidationSettingsPage.java
@@ -0,0 +1,405 @@
+/*******************************************************************************
+ * 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.jst.jsp.ui.internal.preferences.ui;
+
+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.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.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.html.ui.internal.HTMLUIMessages;
+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 AbstractPropertyPreferencePage {
+
+	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;
+		
+		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;
+		}
+		
+	}
+	
+	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);
+		
+		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 createStyleSection(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 Composite createStyleSectionWithContentComposite(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);
+
+		Composite inner = new Composite(excomposite, SWT.NONE);
+		inner.setFont(excomposite.getFont());
+		inner.setLayout(new GridLayout(nColumns, false));
+		excomposite.setClient(inner);
+		return inner;
+	}
+	
+	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 abstract boolean shouldRevalidateOnSettingsChange();
+	
+	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(HTMLUIMessages.Validation_Title);
+			/* Choose which message to use based on if its project or workspace settings */
+			String msg = (getProject() == null) ? HTMLUIMessages.Validation_Workspace : HTMLUIMessages.Validation_Project;
+			mb.setMessage(msg);
+			switch(mb.open()) {
+				case SWT.CANCEL:
+					return false;
+				case SWT.YES:
+					ValidateJob job = new ValidateJob(HTMLUIMessages.Validation_jobName);
+					job.schedule();
+				case SWT.NO:
+				default:
+					return true;
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * 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.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/JSPFilesPreferencePage.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/JSPFilesPreferencePage.java
index ffd71b7..f8abc65 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/JSPFilesPreferencePage.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/JSPFilesPreferencePage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * Copyright (c) 2004, 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
@@ -15,23 +15,19 @@
 import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jst.jsp.core.internal.JSPCorePlugin;
-import org.eclipse.jst.jsp.core.internal.preferences.JSPCorePreferenceNames;
 import org.eclipse.jst.jsp.core.internal.provisional.contenttype.ContentTypeIdForJSP;
-import org.eclipse.jst.jsp.ui.internal.JSPUIMessages;
 import org.eclipse.jst.jsp.ui.internal.JSPUIPlugin;
-import org.eclipse.jst.jsp.ui.internal.editor.IHelpContextIds;
-import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.ui.PlatformUI;
 import org.eclipse.wst.html.ui.internal.preferences.ui.HTMLFilesPreferencePage;
 
 public class JSPFilesPreferencePage extends HTMLFilesPreferencePage {
-	private Button fValidateFragments;
-
-	protected Preferences getModelPreferences() {
-		return JSPCorePlugin.getDefault().getPluginPreferences();
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.wst.html.ui.preferences.ui.HTMLFilesPreferencePage#createContentsForLoadingGroup(org.eclipse.swt.widgets.Composite)
+	 */
+	protected void createContentsForLoadingGroup(Composite parent) {
+		// no loading preferences
 	}
 
 	/*
@@ -47,39 +43,14 @@
 		JSPCorePlugin.getDefault().savePluginPreferences(); // model
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
-	 */
-	protected Control createContents(Composite parent) {
-		Control c = super.createContents(parent);
-
-		Group g = createGroup((Composite) c, 1);
-		g.setText(JSPUIMessages.JSPFilesPreferencePage_0);
-		fValidateFragments = createCheckBox(g, JSPUIMessages.JSPFilesPreferencePage_1);
-		boolean validateFragments = getModelPreferences().getBoolean(JSPCorePreferenceNames.VALIDATE_FRAGMENTS);
-		fValidateFragments.setSelection(validateFragments);
-
-		PlatformUI.getWorkbench().getHelpSystem().setHelp(c, IHelpContextIds.JSP_PREFWEBX_FILES_HELPID);
-		
-		setSize((Composite)c);
-		return c;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.wst.html.ui.preferences.ui.HTMLFilesPreferencePage#createContentsForLoadingGroup(org.eclipse.swt.widgets.Composite)
-	 */
-	protected void createContentsForLoadingGroup(Composite parent) {
-		// no loading preferences
-	}
-
 	protected IContentType getContentType() {
 		return Platform.getContentTypeManager().getContentType(ContentTypeIdForJSP.ContentTypeID_JSP);
 	}
 
+	protected Preferences getModelPreferences() {
+		return JSPCorePlugin.getDefault().getPluginPreferences();
+	}
+
 	/*
 	 * (non-Javadoc)
 	 * 
@@ -89,13 +60,6 @@
 		// no loading preferences
 	}
 
-	protected void performDefaults() {
-		super.performDefaults();
-
-		boolean validateFragments = getModelPreferences().getDefaultBoolean(JSPCorePreferenceNames.VALIDATE_FRAGMENTS);
-		fValidateFragments.setSelection(validateFragments);
-	}
-
 	/*
 	 * (non-Javadoc)
 	 * 
@@ -105,12 +69,6 @@
 		// no loading preferences
 	}
 
-	protected void storeValues() {
-		boolean validateFragments = fValidateFragments.getSelection();
-		getModelPreferences().setValue(JSPCorePreferenceNames.VALIDATE_FRAGMENTS, validateFragments);
-		super.storeValues();
-	}
-
 	/*
 	 * (non-Javadoc)
 	 * 
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/JSPValidationPreferencePage.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/JSPValidationPreferencePage.java
new file mode 100644
index 0000000..f0f11de
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/preferences/ui/JSPValidationPreferencePage.java
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * 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.jst.jsp.ui.internal.preferences.ui;
+
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jst.jsp.core.internal.JSPCorePlugin;
+import org.eclipse.jst.jsp.core.internal.preferences.JSPCorePreferenceNames;
+import org.eclipse.jst.jsp.ui.internal.JSPUIMessages;
+import org.eclipse.jst.jsp.ui.internal.JSPUIPlugin;
+import org.eclipse.jst.jsp.ui.internal.editor.IHelpContextIds;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.wst.sse.core.internal.validate.ValidationMessage;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.ScrolledPageContent;
+import org.eclipse.wst.sse.ui.internal.util.PixelConverter;
+
+public class JSPValidationPreferencePage extends AbstractValidationSettingsPage {
+
+	private static final String SETTINGS_SECTION_NAME = "JSPValidationSeverities";//$NON-NLS-1$
+
+	private static final int[] SEVERITIES = {ValidationMessage.ERROR, ValidationMessage.WARNING, ValidationMessage.IGNORE};
+
+	private PixelConverter fPixelConverter;
+	private Button fValidateFragments;
+
+	public JSPValidationPreferencePage() {
+		super();
+	}
+
+	/**
+	 * @param parent
+	 * @param text
+	 * @return
+	 */
+	private Button createCheckBox(Composite parent, String text) {
+		Button c = new Button(parent, SWT.CHECK);
+		c.setText(text);
+		c.setLayoutData(GridDataFactory.fillDefaults().create());
+		return c;
+	}
+
+	protected Control createCommonContents(Composite parent) {
+		final Composite page = new Composite(parent, SWT.NULL);
+
+		// GridLayout
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		page.setLayout(layout);
+
+		fPixelConverter = new PixelConverter(parent);
+		
+		Group filesGroup = new Group(page, SWT.NONE);
+		filesGroup.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
+		filesGroup.setLayout(new GridLayout(1, false));
+		filesGroup.setText(JSPUIMessages.JSPFilesPreferencePage_0);
+		createFilesSection(filesGroup);
+
+		// spacer
+//		new Label(page, SWT.NONE).setLayoutData(GridDataFactory.fillDefaults().create());
+
+		Group severitiesGroup = new Group(page, SWT.NONE);
+		severitiesGroup.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
+		severitiesGroup.setLayout(new GridLayout(1, false));
+		severitiesGroup.setText(JSPUIMessages.JSPValidationPreferencePage_0);
+		final Composite content = createValidationSection(severitiesGroup);
+
+		GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
+		gridData.heightHint = fPixelConverter.convertHeightInCharsToPixels(20);
+		content.setLayoutData(gridData);
+
+		return page;
+	}
+
+	/**
+	 * @param fragmentGroup
+	 */
+	private void createFilesSection(Group fragmentGroup) {
+		fValidateFragments = createCheckBox(fragmentGroup, JSPUIMessages.JSPFilesPreferencePage_1);
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(fValidateFragments, IHelpContextIds.JSP_PREFWEBX_FILES_HELPID);
+		IScopeContext[] contexts = createPreferenceScopes();
+		fValidateFragments.setSelection(contexts[0].getNode(getPreferenceNodeQualifier()).getBoolean(JSPCorePreferenceNames.VALIDATE_FRAGMENTS, contexts[1].getNode(getPreferenceNodeQualifier()).getBoolean(JSPCorePreferenceNames.VALIDATE_FRAGMENTS, true)));
+	}
+
+	private Composite createValidationSection(Composite page) {
+		int nColumns = 3;
+
+		final ScrolledPageContent spContent = new ScrolledPageContent(page);
+
+		Composite composite = spContent.getBody();
+
+		GridLayout layout = new GridLayout(nColumns, false);
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		composite.setLayout(layout);
+
+		Label description = new Label(composite, SWT.NONE);
+		description.setText(JSPUIMessages.Validation_description);
+		description.setFont(page.getFont());
+
+		String[] errorWarningIgnoreLabels = new String[]{JSPUIMessages.Validation_Error, JSPUIMessages.Validation_Warning, JSPUIMessages.Validation_Ignore};
+		Composite section;
+
+		// begin directives section
+		section = createStyleSectionWithContentComposite(composite, JSPUIMessages.VALIDATION_HEADER_DIRECTIVE, nColumns);
+		addComboBox(section, JSPUIMessages.VALIDATION_DIRECTIVE_TAGLIB_UNRESOLVABLE_URI_OR_TAGDIR, JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_UNRESOLVABLE_URI_OR_TAGDIR, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_DIRECTIVE_TAGLIB_DUPLICATE_PREFIXES_DIFFERENT_URIS, JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_DUPLICATE_PREFIXES_DIFFERENT_URIS, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_DIRECTIVE_TAGLIB_DUPLICATE_PREFIXES_SAME_URIS, JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_DUPLICATE_PREFIXES_SAME_URIS, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_DIRECTIVE_TAGLIB_MISSING_PREFIX, JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_MISSING_PREFIX, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_DIRECTIVE_TAGLIB_MISSING_URI_OR_TAGDIR, JSPCorePreferenceNames.VALIDATION_DIRECTIVE_TAGLIB_MISSING_URI_OR_TAGDIR, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_DIRECTIVE_INCLUDE_FILE_NOT_FOUND, JSPCorePreferenceNames.VALIDATION_DIRECTIVE_INCLUDE_FILE_NOT_FOUND, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_DIRECTIVE_INCLUDE_NO_FILE_SPECIFIED, JSPCorePreferenceNames.VALIDATION_DIRECTIVE_INCLUDE_NO_FILE_SPECIFIED, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_DIRECTIVE_PAGE_SUPERCLASS_NOT_FOUND, JSPCorePreferenceNames.VALIDATION_DIRECTIVE_PAGE_SUPERCLASS_NOT_FOUND, SEVERITIES, errorWarningIgnoreLabels, 0);
+		// end directives section
+
+		// begin custom actions section
+		section = createStyleSectionWithContentComposite(composite, JSPUIMessages.VALIDATION_HEADER_CUSTOM_ACTIONS, nColumns);
+		addComboBox(section, JSPUIMessages.VALIDATION_ACTIONS_SEVERITY_MISSING_REQUIRED_ATTRIBUTE, JSPCorePreferenceNames.VALIDATION_ACTIONS_SEVERITY_MISSING_REQUIRED_ATTRIBUTE, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_ACTIONS_SEVERITY_UNKNOWN_ATTRIBUTE, JSPCorePreferenceNames.VALIDATION_ACTIONS_SEVERITY_UNKNOWN_ATTRIBUTE, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_ACTIONS_SEVERITY_NON_EMPTY_INLINE_TAG, JSPCorePreferenceNames.VALIDATION_ACTIONS_SEVERITY_NON_EMPTY_INLINE_TAG, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_TRANSLATION_TEI_VALIDATION_MESSAGE, JSPCorePreferenceNames.VALIDATION_TRANSLATION_TEI_VALIDATION_MESSAGE, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_TRANSLATION_TEI_CLASS_NOT_FOUND, JSPCorePreferenceNames.VALIDATION_TRANSLATION_TEI_CLASS_NOT_FOUND, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_TRANSLATION_TEI_CLASS_NOT_INSTANTIATED, JSPCorePreferenceNames.VALIDATION_TRANSLATION_TEI_CLASS_NOT_INSTANTIATED, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_TRANSLATION_TEI_CLASS_RUNTIME_EXCEPTION, JSPCorePreferenceNames.VALIDATION_TRANSLATION_TEI_CLASS_RUNTIME_EXCEPTION, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_TRANSLATION_TAG_HANDLER_CLASS_NOT_FOUND, JSPCorePreferenceNames.VALIDATION_TRANSLATION_TAG_HANDLER_CLASS_NOT_FOUND, SEVERITIES, errorWarningIgnoreLabels, 0);
+		// end custom actions section
+
+		// begin standard actions section
+		section = createStyleSectionWithContentComposite(composite, JSPUIMessages.VALIDATION_HEADER_STANDARD_ACTIONS, nColumns);
+		addComboBox(section, JSPUIMessages.VALIDATION_TRANSLATION_USEBEAN_INVALID_ID, JSPCorePreferenceNames.VALIDATION_TRANSLATION_USEBEAN_INVALID_ID, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_TRANSLATION_USBEAN_MISSING_TYPE_INFO, JSPCorePreferenceNames.VALIDATION_TRANSLATION_USBEAN_MISSING_TYPE_INFO, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_TRANSLATION_USEBEAN_AMBIGUOUS_TYPE_INFO, JSPCorePreferenceNames.VALIDATION_TRANSLATION_USEBEAN_AMBIGUOUS_TYPE_INFO, SEVERITIES, errorWarningIgnoreLabels, 0);
+		// end standard actions section
+
+		// begin Java section
+		section = createStyleSectionWithContentComposite(composite, JSPUIMessages.VALIDATION_HEADER_JAVA, nColumns);
+		
+		addComboBox(section, JSPUIMessages.VALIDATION_JAVA_LOCAL_VARIABLE_NEVER_USED, JSPCorePreferenceNames.VALIDATION_JAVA_LOCAL_VARIABLE_NEVER_USED, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_JAVA_ARGUMENT_IS_NEVER_USED, JSPCorePreferenceNames.VALIDATION_JAVA_ARGUMENT_IS_NEVER_USED, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_JAVA_NULL_LOCAL_VARIABLE_REFERENCE, JSPCorePreferenceNames.VALIDATION_JAVA_NULL_LOCAL_VARIABLE_REFERENCE, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_JAVA_UNUSED_IMPORT, JSPCorePreferenceNames.VALIDATION_JAVA_UNUSED_IMPORT, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_JAVA_POTENTIAL_NULL_LOCAL_VARIABLE_REFERENCE, JSPCorePreferenceNames.VALIDATION_JAVA_POTENTIAL_NULL_LOCAL_VARIABLE_REFERENCE, SEVERITIES, errorWarningIgnoreLabels, 0);
+		// end Java section
+
+		// begin EL section
+		section = createStyleSectionWithContentComposite(composite, JSPUIMessages.VALIDATION_HEADER_EL, nColumns);
+		addComboBox(section, JSPUIMessages.VALIDATION_EL_SYNTAX, JSPCorePreferenceNames.VALIDATION_EL_SYNTAX, SEVERITIES, errorWarningIgnoreLabels, 0);
+		addComboBox(section, JSPUIMessages.VALIDATION_EL_LEXER, JSPCorePreferenceNames.VALIDATION_EL_LEXER, SEVERITIES, errorWarningIgnoreLabels, 0);
+		// end EL section
+
+		restoreSectionExpansionStates(getDialogSettings().getSection(SETTINGS_SECTION_NAME));
+
+		return spContent;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.dialogs.DialogPage#dispose()
+	 */
+	public void dispose() {
+		storeSectionExpansionStates(getDialogSettings().addNewSection(SETTINGS_SECTION_NAME));
+		super.dispose();
+	}
+
+	protected IDialogSettings getDialogSettings() {
+		return JSPUIPlugin.getDefault().getDialogSettings();
+	}
+
+	protected String getPreferenceNodeQualifier() {
+		return JSPCorePlugin.getDefault().getBundle().getSymbolicName();
+	}
+
+	protected String getPreferencePageID() {
+		return "org.eclipse.jst.jsp.ui.preferences.validation";//$NON-NLS-1$
+	}
+
+	protected String getProjectSettingsKey() {
+		return JSPCorePreferenceNames.USE_PROJECT_SETTINGS;
+	}
+
+	protected String getPropertyPageID() {
+		return "org.eclipse.jst.jsp.ui.propertyPage.project.validation";//$NON-NLS-1$
+	}
+
+	protected String getQualifier() {
+		return JSPCorePlugin.getDefault().getBundle().getSymbolicName();
+	}
+
+	public void init(IWorkbench workbench) {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+	 */
+	protected void performDefaults() {
+		resetSeverities();
+
+		IEclipsePreferences defaultContext = new DefaultScope().getNode(getPreferenceNodeQualifier());
+		boolean validateFragments = defaultContext.getBoolean(JSPCorePreferenceNames.VALIDATE_FRAGMENTS, true);
+		fValidateFragments.setSelection(validateFragments);
+
+		super.performDefaults();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.wst.sse.ui.internal.preferences.ui.AbstractSettingsPage#performOk()
+	 */
+	public boolean performOk() {
+		boolean result = super.performOk();
+		storeValues();
+		return result;
+	}
+
+	protected boolean shouldRevalidateOnSettingsChange() {
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.jst.jsp.ui.internal.preferences.ui.AbstractValidationSettingsPage#storeValues()
+	 */
+	protected void storeValues() {
+		super.storeValues();
+
+		IScopeContext[] contexts = createPreferenceScopes();
+		boolean validateFragments = fValidateFragments.getSelection();
+		contexts[0].getNode(getPreferenceNodeQualifier()).putBoolean(JSPCorePreferenceNames.VALIDATE_FRAGMENTS, validateFragments);
+	}
+}