/*******************************************************************************
 * Copyright (c) 2001, 2004 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.internal.ui;


import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import javax.swing.event.HyperlinkEvent;

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jem.util.logger.LogEntry;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.wst.common.frameworks.internal.ui.WTPUIPlugin;
import org.eclipse.wst.validation.internal.ConfigurationManager;
import org.eclipse.wst.validation.internal.GlobalConfiguration;
import org.eclipse.wst.validation.internal.ProjectConfiguration;
import org.eclipse.wst.validation.internal.ValidatorMetaData;
import org.eclipse.wst.validation.internal.operations.ValidatorManager;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.eclipse.wst.validation.internal.ui.plugin.ValidationUIPlugin;

/**
 * This class and its inner classes are not intended to be subclassed outside of the validation
 * framework.
 * 
 * This page implements the PropertyPage for validators; viewed when the user right-clicks on the
 * IProject, selects "Properties", and then "Validation."
 * 
 * There exist three possible page layouts: if there is an eclipse internal error, and the page is
 * brought up on a non-IProject type; if there are no validators configured on that type of
 * IProject, and a page which lists all validators configured on that type of IProject. These three
 * pages are implemented as inner classes, so that it's clear which method is needed for which
 * input. When all of the methods, and behaviour, were implemented in this one class, much more
 * error-checking had to be done, to ensure that the method wasn't being called incorrectly by one
 * of the pages.
 */
public class ValidationPropertiesPage extends PropertyPage {
	static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
	static final String TAB = "\t"; //$NON-NLS-1$
	static final String NEWLINE_AND_TAB = NEWLINE + TAB;
	private IValidationPage _pageImpl = null;

	/**
	 * Initially, this interface was created as an abstract class, and getControl() was implemented.
	 * (getProject() could also have been implemented in the abstract class.) However, at runtime, a
	 * NullPointerException was thrown; the inner class had lost its pointer to its enclosing class.
	 * After some experimentation, I discovered that if I changed the parent to an interface, the
	 * enclosing class could be found. (Merely moving the AValidationPage into its own file was
	 * insufficient.)
	 */
	public interface IValidationPage {
		public abstract Composite createPage(Composite parent) throws InvocationTargetException;

		public abstract boolean performOk() throws InvocationTargetException;

		public boolean performDefaults() throws InvocationTargetException;
		
		public Composite getControl();

		public abstract void dispose();

		public abstract boolean performCancel();
	}

	public class InvalidPage implements IValidationPage {
		private Composite page = null;

		private Composite composite = null;
		private GridLayout layout = null;
		private Label messageLabel = null;

		public InvalidPage(Composite parent) {
			page = createPage(parent);
		}

		/**
		 * This page is added to the Properties guide if some internal problem occurred; for
		 * example, the highlighted item in the workbench is not an IProject (according to this
		 * page's plugin.xml, this page is only valid when an IProject is selected).
		 */
		public Composite createPage(Composite parent) {
			// Don't create the default and apply buttons.
			noDefaultAndApplyButton();

			final ScrolledComposite sc1 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
			sc1.setLayoutData(new GridData(GridData.FILL_BOTH));
			composite = new Composite(sc1, SWT.NONE);
			sc1.setContent(composite);
			layout = new GridLayout();
			composite.setLayout(layout);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ContextIds.VALIDATION_PROPERTIES_PAGE);

			messageLabel = new Label(composite, SWT.NONE);
			messageLabel.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INVALID_REGISTER));

			composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));

			return composite;
		}

		public boolean performDefaults() {
			return true;
		}

		/**
		 * Since this page occurs under invalid circumstances, there is nothing to save.
		 */
		public boolean performOk() {
			return true;
		}

		public Composite getControl() {
			return page;
		}

		public void dispose() {
			messageLabel.dispose();
			//			layout.dispose();
			composite.dispose();
		}

		public boolean performCancel() {
			return true;
		}
	}

	public class NoValidatorsPage implements IValidationPage {
		private Composite page = null;

		private Composite composite = null;
		private GridLayout layout = null;
		private GridData data = null;
		private Label messageLabel = null;
		
		public NoValidatorsPage(Composite parent) {
			page = createPage(parent);
		}

		/**
		 * This page is created if an IProject is selected, but that project has no validators
		 * configured (i.e., the page is valid, but an empty list.)
		 */
		public Composite createPage(Composite parent) {
			// Don't create the default and apply buttons.
			noDefaultAndApplyButton();

			// top level group
			final ScrolledComposite sc1 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
			sc1.setLayoutData(new GridData(GridData.FILL_BOTH));
			composite = new Composite(sc1, SWT.NONE);
			sc1.setContent(composite);
			layout = new GridLayout();
			composite.setLayout(layout);
			data = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL);
			composite.setLayoutData(data);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ContextIds.VALIDATION_PROPERTIES_PAGE);

			messageLabel = new Label(composite, SWT.NONE);
			String[] msgParm = {getProject().getName()};
			messageLabel.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_UI_LBL_NOVALIDATORS_DESC, msgParm));
			composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
			return composite;
		}

		public boolean performDefaults() {
			return true;
		}

		/**
		 * Since there are no validators, there is nothing to save.
		 */
		public boolean performOk() {
			return true;
		}

		public Composite getControl() {
			return page;
		}

		public void dispose() {
			messageLabel.dispose();
			//			layout.dispose();
			//			data.dispose();
			composite.dispose();
		}

		public boolean performCancel() {
			return true;
		}
	}

	public class ValidatorListPage implements IValidationPage {
		Composite page = null;
		GridLayout layout = null;
		GridData data = null;
		Label messageLabel = null;
		TableViewer validatorList = null;
		Button overrideGlobalButton = null;
		boolean existingOverrideGlobalVal = false;
		Button disableAllValidation = null;
		boolean existingDisableAllValidation = false;
		private Button enableAllButton = null;
		private Button disableAllButton = null;
		Label emptyRowPlaceholder = null;
		private Table validatorsTable;
		private Label globalPrefLink = null;
		ProjectConfiguration pagePreferences = null;
		private boolean canOverride = false;
		private Button addValidationBuilder = null;
		private Color color = null;

		private ValidatorMetaData[] oldVmd = null; // Cache the enabled validators so that, if there
    private Map oldDelegates = null; // Cache the validator delegates.

		// is no change to this list, the expensive task
		// list update can be avoided

		/**
		 * This class is provided for the CheckboxTableViewer in the
		 * ValidationPropertiesPage$ValidatorListPage class.
		 */
		public class ValidationContentProvider implements IStructuredContentProvider {
			/**
			 * Disposes of this content provider. This is called by the viewer when it is disposed.
			 */
			public void dispose() {
				//dispose
			}

			/**
			 * Returns the elements to display in the viewer when its input is set to the given
			 * element. These elements can be presented as rows in a table, items in a list, etc.
			 * The result is not modified by the viewer.
			 * 
			 * @param inputElement
			 *            the input element
			 * @return the array of elements to display in the viewer
			 */
			public java.lang.Object[] getElements(Object inputElement) {
				if (inputElement instanceof ValidatorMetaData[]) {
					// The ValidatorMetaData[] is the array which is returned by ValidatorManager's
					// getConfiguredValidatorMetaData(IProject) call.
					// This array is set to be the input of the CheckboxTableViewer in
					// ValidationPropertiesPage$ValidatorListPage's createPage(Composite)
					// method.
					return (ValidatorMetaData[]) inputElement;
				}
				return new Object[0];
			}

			/**
			 * Notifies this content provider that the given viewer's input has been switched to a
			 * different element.
			 * <p>
			 * A typical use for this method is registering the content provider as a listener to
			 * changes on the new input (using model-specific means), and deregistering the viewer
			 * from the old input. In response to these change notifications, the content provider
			 * propagates the changes to the viewer.
			 * </p>
			 * 
			 * @param viewer
			 *            the viewer
			 * @param oldInput
			 *            the old input element, or <code>null</code> if the viewer did not
			 *            previously have an input
			 * @param newInput
			 *            the new input element, or <code>null</code> if the viewer does not have
			 *            an input
			 */
			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
				//do nothing
			}



		}

		/**
		 * This class is provided for ValidationPropertiesPage$ValidatorListPage's
		 * checkboxTableViewer element.
		 */
		public class ValidationLabelProvider extends LabelProvider implements ITableLabelProvider {
			/**
			 * Override the LabelProvider's text, by customizing the text for a ValidatorMetaData
			 * element.
			 */
			public String getText(Object element) {
				if (element == null) {
					return ""; //$NON-NLS-1$
				} else if (element instanceof ValidatorMetaData) {
					return ((ValidatorMetaData) element).getValidatorDisplayName();
				} else {
					return super.getText(element);
				}
			}
			
			public String getColumnText(Object element, int columnIndex) {
				if(columnIndex == 0) {
					return ((ValidatorMetaData) element).getValidatorDisplayName();
				}
				/*if(columnIndex == 1) {
					if(((ValidatorMetaData)element).isManualValidation())
						return ENABLED;
					return DISABLED;	
				} else if(columnIndex == 2) {
					if(((ValidatorMetaData)element).isBuildValidation())
						return ENABLED;
					return DISABLED;
				}*/
				return null;
			}

      private Image getImage(String imageName) {
        boolean isDisabled = !validatorsTable.isEnabled();
        if (isDisabled) {
            imageName = imageName + "_disabled";  //$NON-NLS-N$
        }
        Image image = ValidationUIPlugin.getPlugin().getImage(imageName);
        return image;
      }
      

      public Image getColumnImage(Object element, int columnIndex) {
				if(columnIndex == 1) {
					if(((ValidatorMetaData)element).isManualValidation())
						return  getImage("ok_tbl");
					return getImage("fail_tbl");
				} else if(columnIndex == 2) {
					if(((ValidatorMetaData)element).isBuildValidation())
						return getImage("ok_tbl");;
					return getImage("fail_tbl");
				}
        else if (columnIndex == 3)
        {
          ValidatorMetaData vmd = (ValidatorMetaData)element;

          if (vmd.isDelegating())
          {
            return getImage("settings");          
          }
        }
				return null;
			}
		}

		/**
		 * This class is used to sort the CheckboxTableViewer elements.
		 */
		public class ValidationViewerSorter extends ViewerSorter {
			/**
			 * Returns a negative, zero, or positive number depending on whether the first element
			 * is less than, equal to, or greater than the second element.
			 * <p>
			 * The default implementation of this method is based on comparing the elements'
			 * categories as computed by the <code>category</code> framework method. Elements
			 * within the same category are further subjected to a case insensitive compare of their
			 * label strings, either as computed by the content viewer's label provider, or their
			 * <code>toString</code> values in other cases. Subclasses may override.
			 * </p>
			 * 
			 * @param viewer
			 *            the viewer
			 * @param e1
			 *            the first element
			 * @param e2
			 *            the second element
			 * @return a negative number if the first element is less than the second element; the
			 *         value <code>0</code> if the first element is equal to the second element;
			 *         and a positive number if the first element is greater than the second element
			 */
			public int compare(Viewer viewer, Object e1, Object e2) {
				// Can't instantiate ViewerSorter because it's abstract, so use this
				// inner class to represent it.
				return super.compare(viewer, e1, e2);
			}
		}

		public ValidatorListPage(Composite parent) throws InvocationTargetException {
			ConfigurationManager prefMgr = ConfigurationManager.getManager();
			ValidatorManager vMgr = ValidatorManager.getManager();

			pagePreferences = prefMgr.getProjectConfiguration(getProject()); // This
			// represents the values on the page that haven't been persisted yet.
			// Start with the last values that were persisted into the current
			// page's starting values.

			// store the default values for the widgets
			canOverride = prefMgr.getGlobalConfiguration().canProjectsOverride();
			//isAutoBuildEnabled = vMgr.isGlobalAutoBuildEnabled();
			//isBuilderConfigured = ValidatorManager.doesProjectSupportBuildValidation(getProject());
			oldVmd = pagePreferences.getEnabledValidators(); // Cache the enabled validators so
      // that, if there is no change to this
      // list, the expensive task list update
      // can be avoided

      oldDelegates =  new HashMap(pagePreferences.getDelegatingValidators());

			createPage(parent);
			
			existingOverrideGlobalVal = overrideGlobalButton.getSelection();
			existingDisableAllValidation = disableAllValidation.getSelection();
		}
		
		private void setupTableColumns(Table table, TableViewer viewer) {
			TableColumn validatorColumn = new TableColumn(table, SWT.NONE);
	        validatorColumn.setText("Validator");
	        validatorColumn.setResizable(false);
	        validatorColumn.setWidth(240);
	        TableColumn manualColumn = new TableColumn(table, SWT.NONE);
	        manualColumn.setText("Manual");
	        manualColumn.setResizable(false);
	        manualColumn.setWidth(40);
	        TableColumn buildColumn = new TableColumn(table, SWT.NONE);
	        buildColumn.setText("Build");
	        buildColumn.setResizable(false);
	        buildColumn.setWidth(30);
          TableColumn settingsColumn = new TableColumn(table, SWT.NONE);
          settingsColumn.setText("Settings");
          settingsColumn.setResizable(false);
          settingsColumn.setWidth(40);
	    }

		/**
		 * This page is created if the current project has at least one validator configured on it.
		 */
		public Composite createPage(Composite parent) throws InvocationTargetException {
			// top level group
			final ScrolledComposite sc1 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
			sc1.setLayoutData(new GridData(GridData.FILL_BOTH));
			page = new Composite(sc1, SWT.NONE);
			sc1.setContent(page);
			page.setLayout(new GridLayout()); // use the layout's default preferences
			
			Composite validatorGroup = new Composite(page, SWT.NONE);
			GridLayout validatorGroupLayout = new GridLayout();
			validatorGroupLayout.numColumns = 2;
			validatorGroup.setLayout(validatorGroupLayout);
			
			Hyperlink link = new Hyperlink(validatorGroup,SWT.None);
			GridData layout = new GridData(GridData.HORIZONTAL_ALIGN_END);
			layout.horizontalSpan = 2;
			link.setLayoutData(layout);
			link.setUnderlined(true);
			color = new Color(validatorGroup.getDisplay(),new RGB(0,0,255) );
			link.setForeground(color);
			link.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.CONFIG_WS_SETTINGS));
			link.addHyperlinkListener(new IHyperlinkListener() {
				public static final String DATA_NO_LINK = "PropertyAndPreferencePage.nolink"; //$NON-NLS-1$

				public void hyperlinkUpdate(HyperlinkEvent e) {
				}

				public void linkEntered(org.eclipse.ui.forms.events.HyperlinkEvent e) {
				}

				public void linkExited(org.eclipse.ui.forms.events.HyperlinkEvent e) {
				}

				public void linkActivated(org.eclipse.ui.forms.events.HyperlinkEvent e) {
					String id = getPreferencePageID();
					PreferencesUtil.createPreferenceDialogOn(getShell(), id, new String[]{id}, DATA_NO_LINK).open();
					try {
						updateWidgets();
					} catch (InvocationTargetException ie) {

					}
				}

				private String getPreferencePageID() {
					return "ValidationPreferencePage";
				}
			});
			
			GridData overrideData = new GridData(GridData.GRAB_HORIZONTAL);
			overrideData.horizontalSpan = 2;
			overrideGlobalButton = new Button(validatorGroup, SWT.CHECK);
			overrideGlobalButton.setLayoutData(overrideData);
			overrideGlobalButton.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.PROP_BUTTON_OVERRIDE, new String[]{getProject().getName()}));
			overrideGlobalButton.setFocus(); // must focus on something for F1 to have a topic to lanuch
			overrideGlobalButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					pagePreferences.setDoesProjectOverride(overrideGlobalButton.getSelection());
					try {
						updateWidgets();
					} catch (InvocationTargetException exc) {
						displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
					}
				}
			});
			
			emptyRowPlaceholder = new Label(validatorGroup, SWT.NONE);
			emptyRowPlaceholder.setLayoutData(new GridData());
			
			GridData data = new GridData(GridData.FILL_HORIZONTAL);
			data.horizontalSpan = 2;
			disableAllValidation = new Button(validatorGroup, SWT.CHECK);
			disableAllValidation.setLayoutData(data);
			disableAllValidation.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.DISABLE_VALIDATION));
			disableAllValidation.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					pagePreferences.setDisableAllValidation(disableAllValidation.getSelection());
					disableAllValidation.setFocus();
					validatorsTable.setEnabled(!disableAllValidation.getSelection());
					enableAllButton.setEnabled(!disableAllValidation.getSelection());
					disableAllButton.setEnabled(!disableAllValidation.getSelection());
	          try {
	            updateWidgets();
	          } catch (InvocationTargetException exc) {
	            displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
	          }
				}
			});
			
			emptyRowPlaceholder = new Label(validatorGroup, SWT.NONE);
			emptyRowPlaceholder.setLayoutData(new GridData());



			GridData listLabelData = new GridData(GridData.FILL_HORIZONTAL);
			listLabelData.horizontalSpan = 2;
			messageLabel = new Label(validatorGroup, SWT.NONE);
			messageLabel.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_UI_LBL_DESC, new String[]{getProject().getName()}));
			messageLabel.setLayoutData(listLabelData);

			validatorsTable = new Table(validatorGroup,SWT.BORDER | SWT.FULL_SELECTION);
			TableLayout tableLayout = new TableLayout();
			tableLayout.addColumnData(new ColumnWeightData(160, true));
			tableLayout.addColumnData(new ColumnWeightData(40, true));
			tableLayout.addColumnData(new ColumnWeightData(30, true));
			tableLayout.addColumnData(new ColumnWeightData(40, true));
			validatorsTable.setHeaderVisible(true);
			validatorsTable.setLinesVisible(true);
	        validatorsTable.setLayout(tableLayout);
			
			validatorList = new TableViewer(validatorsTable);
	        GridData validatorListData = new GridData(GridData.FILL_HORIZONTAL);
			validatorListData.horizontalSpan = 2;
			validatorsTable.setLayoutData(validatorListData);
			validatorList.getTable().setLayoutData(validatorListData);
			validatorList.setLabelProvider(new ValidationLabelProvider());
			validatorList.setContentProvider(new ValidationContentProvider());
			validatorList.setSorter(new ValidationViewerSorter());
	    setupTableColumns(validatorsTable,validatorList);
      validatorsTable.addMouseListener(new MouseAdapter() {

        public void mouseDown(MouseEvent e)
        {
          if (e.button != 1) {
            return;
          }

          // Handles mouse clicks in the table.
          TableItem tableItem = validatorsTable.getItem(new Point(e.x, e.y));
          if (tableItem == null || tableItem.isDisposed())
          {
            // item no longer exists
            return;
          }
          int columnNumber;
          int columnsCount = validatorsTable.getColumnCount();
          if (columnsCount == 0)
          {
            // If no TableColumn, Table acts as if it has a single column
            // which takes the whole width.
            columnNumber = 0;
          }
          else
          {
            columnNumber = -1;
            for (int i = 0; i < columnsCount; i++)
            {
              Rectangle bounds = tableItem.getBounds(i);
              if (bounds.contains(e.x, e.y))
              {
                columnNumber = i;
                break;
              }
            }
            if (columnNumber == -1)
            {
              return;
            }
          }

          columnClicked(columnNumber);          
        }});
      
      validatorsTable.setMenu(createContextMenu());
      validatorsTable.addFocusListener(new FocusAdapter(){

        public void focusGained(FocusEvent e)
        {
          super.focusGained(e);
          if (validatorsTable.getSelectionCount() == 0)
          {
            validatorsTable.select(0);
          }
        }});			
      
			validatorList.setInput(pagePreferences.getValidators());
			
			enableAllButton = new Button(validatorGroup, SWT.PUSH);
			GridData selectData = new GridData();
			enableAllButton.setLayoutData(selectData);
			enableAllButton.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.PREF_BUTTON_ENABLEALL));
			enableAllButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					try {
						performEnableAll();
					} catch (InvocationTargetException exc) {
						displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
					}
				}
			});
			PlatformUI.getWorkbench().getHelpSystem().setHelp(enableAllButton, ContextIds.VALIDATION_PROPERTIES_PAGE);

			GridData deselectData = new GridData();
			disableAllButton = new Button(validatorGroup, SWT.PUSH);
			disableAllButton.setLayoutData(deselectData);
			disableAllButton.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.PREF_BUTTON_DISABLEALL));
			disableAllButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					try {
						performDisableAll();
					} catch (InvocationTargetException exc) {
						displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
					}
				}
			});
			PlatformUI.getWorkbench().getHelpSystem().setHelp(disableAllButton, ContextIds.VALIDATION_PROPERTIES_PAGE);

			emptyRowPlaceholder = new Label(validatorGroup, SWT.NONE);
			emptyRowPlaceholder.setLayoutData(new GridData());
			
			GridData disableValidationData = new GridData(GridData.FILL_HORIZONTAL);
			disableValidationData.horizontalSpan = 2;
			addValidationBuilder = new Button(validatorGroup, SWT.CHECK);
			addValidationBuilder.setLayoutData(disableValidationData);
			addValidationBuilder.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.ADD_VALIDATION_BUILDER));

			// Have to set the tab order or only the first checkbox in a Composite can
			// be tab-ed to. (Seems to apply only to checkboxes. Have to use the arrow
			// key to navigate the checkboxes.)
			validatorGroup.setTabList(new Control[]{overrideGlobalButton,disableAllValidation, validatorList.getTable(), enableAllButton, disableAllButton});

			updateWidgets();

			page.setSize(page.computeSize(SWT.DEFAULT, SWT.DEFAULT));

			return page;
		}

		protected void updateTable() throws InvocationTargetException {
			TableItem[] items = validatorsTable.getItems();
			for (int i = 0; i < items.length; i++) {
				TableItem item = items[i];
				ValidatorMetaData vmd = (ValidatorMetaData) item.getData();

				// Should the validator be enabled? Read the user's preferences from last time,
				// if they exist, and set from that. If they don't exist, use the Validator class'
				if (pagePreferences.isManualEnabled(vmd))
					vmd.setManualValidation(true);
				else
					vmd.setManualValidation(false);
				
				if (pagePreferences.isBuildEnabled(vmd))
					vmd.setBuildValidation(true);
				else
					vmd.setBuildValidation(false);
			}
			validatorList.refresh();
		}
		
		protected void enableManualAndBuildValues() {
			TableItem[] items = validatorsTable.getItems();
			for (int i = 0; i < items.length; i++) {
				TableItem item = items[i];
				ValidatorMetaData vmd = (ValidatorMetaData) item.getData();
				vmd.setManualValidation(true);
				vmd.setBuildValidation(true);
			}
			validatorList.refresh();
		}
		
		protected void disableManualAndBuildValues() {
			TableItem[] items = validatorsTable.getItems();
			for (int i = 0; i < items.length; i++) {
				TableItem item = items[i];
				ValidatorMetaData vmd = (ValidatorMetaData) item.getData();
				vmd.setManualValidation(false);
				vmd.setBuildValidation(false);
			}
			validatorList.refresh();
		}

		public boolean performDefaults() throws InvocationTargetException {
			pagePreferences.resetToDefault();
			updateWidgets();
			getDefaultsButton().setFocus();
			return true;
		}

		public boolean performEnableAll() throws InvocationTargetException {
			setAllValidators(true);
			pagePreferences.setEnabledValidators(getEnabledValidators());
			enableManualAndBuildValues();
			enableAllButton.setFocus();
			return true;
		}

		public boolean performDisableAll() throws InvocationTargetException {
			setAllValidators(false);
			pagePreferences.setEnabledValidators(getEnabledValidators());
			disableManualAndBuildValues();
			disableAllButton.setFocus();
			return true;
		}
		
		public ValidatorMetaData[] getEnabledValidators() {
			List enabledValidators = new ArrayList();
			TableItem[] items = validatorsTable.getItems();
			for (int i = 0; i < items.length; i++) {
				ValidatorMetaData validatorMetaData = (ValidatorMetaData) items[i].getData();
				if(validatorMetaData.isManualValidation() || validatorMetaData.isBuildValidation())
					enabledValidators.add(validatorMetaData);
			}
			return (ValidatorMetaData[])enabledValidators.toArray(new ValidatorMetaData[enabledValidators.size()]);
		}
		
		public ValidatorMetaData[] getManualEnabledValidators() {
			List enabledValidators = new ArrayList();
			TableItem[] items = validatorsTable.getItems();
			for (int i = 0; i < items.length; i++) {
				ValidatorMetaData validatorMetaData = (ValidatorMetaData) items[i].getData();
				if(validatorMetaData.isManualValidation())
					enabledValidators.add(validatorMetaData);
			}
			return (ValidatorMetaData[])enabledValidators.toArray(new ValidatorMetaData[enabledValidators.size()]);
		}
		
		public ValidatorMetaData[] getBuildEnabledValidators() {
			List enabledValidators = new ArrayList();
			TableItem[] items = validatorsTable.getItems();
			for (int i = 0; i < items.length; i++) {
				ValidatorMetaData validatorMetaData = (ValidatorMetaData) items[i].getData();
				if(validatorMetaData.isBuildValidation())
					enabledValidators.add(validatorMetaData);
			}
			return (ValidatorMetaData[])enabledValidators.toArray(new ValidatorMetaData[enabledValidators.size()]);
		}

		
		/**
		 * 
		 */
		private void setAllValidators(boolean bool) {
			TableItem[] items = validatorsTable.getItems();
			for (int i = 0; i < items.length; i++) {
				ValidatorMetaData validatorMetaData = (ValidatorMetaData) items[i].getData();
				validatorMetaData.setManualValidation(bool);
				validatorMetaData.setBuildValidation(bool);
			}
		}

    protected Menu createContextMenu()
    {
      final Menu menu = new Menu(validatorsTable.getShell(), SWT.POP_UP);
      final MenuItem manualItem = new MenuItem (menu, SWT.CHECK);
      manualItem.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.PREF_MNU_MANUAL));
      final MenuItem buildItem = new MenuItem (menu, SWT.CHECK);
      buildItem.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.PREF_MNU_BUILD));
      final MenuItem settingsItem = new MenuItem (menu, SWT.PUSH);
      settingsItem.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.PREF_MNU_SETTINGS));
      
      class MenuItemListener extends SelectionAdapter
      {
        public void widgetSelected(SelectionEvent e)
        {
          MenuItem menuItem = (MenuItem) e.getSource();
          int index = menu.indexOf(menuItem) + 1;
          columnClicked(index);
        }   
      }
      MenuItemListener listener = new MenuItemListener();
      manualItem.addSelectionListener(listener);
      buildItem.addSelectionListener(listener);
      settingsItem.addSelectionListener(listener);

      menu.addMenuListener(new MenuAdapter() {
        public void menuShown(MenuEvent e)
        {
          IStructuredSelection selection = (IStructuredSelection) validatorList.getSelection();
          ValidatorMetaData vmd = (ValidatorMetaData) selection.getFirstElement();
          manualItem.setSelection(vmd.isManualValidation());
          buildItem.setSelection(vmd.isBuildValidation());
          settingsItem.setEnabled(vmd.isDelegating());
        }});
      
      return menu;
    }
    
    protected void columnClicked(int columnToEdit)
    {
      IStructuredSelection selection = (IStructuredSelection) validatorList.getSelection();
      ValidatorMetaData vmd = (ValidatorMetaData) selection.getFirstElement();
      
      switch (columnToEdit)
      {
      case 1:
        vmd.setManualValidation(!vmd.isManualValidation());
        break;
      case 2:
        vmd.setBuildValidation(!vmd.isBuildValidation());
        break;
      case 3:
      {
        if (!vmd.isDelegating()) {
          break;
        }
        
        String delegateID = pagePreferences.getDelegateUniqueName(vmd);
  
        Shell shell = Display.getCurrent().getActiveShell();
        DelegatingValidatorPreferencesDialog dialog = new DelegatingValidatorPreferencesDialog(shell, vmd, delegateID);
  
        dialog.setBlockOnOpen(true);
        dialog.create();
  
        int result = dialog.open();
  
        if (result == Window.OK)
        {
          pagePreferences.setDelegateUniqueName(vmd, dialog.getDelegateID());
        }
      }
      default:
        break;
      }
      validatorList.refresh();      
    }
    
		void updateWidgets() throws InvocationTargetException {
			// Since the setting of the "override" button enables/disables the other widgets on the
			// page, update the enabled state of the other widgets from the "override" button.
			updateTable();
			updateAllWidgets();
			
		}
		
		protected void updateWidgetsForDefaults() throws InvocationTargetException {
			updateTableForDefaults();
			updateAllWidgets();
		}
		
		private void updateAllWidgets() throws InvocationTargetException {
			// Since the setting of the "override" button enables/disables the other widgets on the
			// page, update the enabled state of the other widgets from the "override" button.
			ConfigurationManager prefMgr = ConfigurationManager.getManager();
			canOverride = prefMgr.getGlobalConfiguration().canProjectsOverride();
			boolean overridePreferences = canOverride && pagePreferences.doesProjectOverride();
			overrideGlobalButton.setEnabled(canOverride);
			overrideGlobalButton.setSelection(overridePreferences);
			disableAllValidation.setEnabled(overridePreferences);
			disableAllValidation.setSelection(pagePreferences.isDisableAllValidation());
			if (overridePreferences)
				enableDependentControls(!pagePreferences.isDisableAllValidation());
			else
				enableDependentControls(overridePreferences);
			setAddValidationBuilderButtonEnablement();
			updateHelp();
		}

		private void setAddValidationBuilderButtonEnablement() {
			try {
				boolean builderExists = false;
				IProjectDescription description = getProject().getDescription();
				ICommand[] commands = description.getBuildSpec();
				for (int i = 0; i < commands.length; i++) {
					if (commands[i].getBuilderName().equals(ValidationPlugin.VALIDATION_BUILDER_ID) | isValidationBuilderEnabled(commands[i]))
						builderExists = true;
				}
				if (builderExists) {
					addValidationBuilder.setVisible(false);
				} else {
					addValidationBuilder.setVisible(true);
					addValidationBuilder.setSelection(false);
					addValidationBuilder.setEnabled(true);
				}

			} catch (CoreException ce) {
				Logger.getLogger().log(ce);
			}
		}
		
		private  boolean isValidationBuilderEnabled(ICommand command) {
			Map args = command.getArguments();
			if(args.isEmpty())
				return false;
			String handle = (String)args.get("LaunchConfigHandle");
			if(handle != null && handle.length() > 0 && handle.indexOf(ValidationPlugin.VALIDATION_BUILDER_ID) != -1)
				return true;
			return false;
		}

		private void updateTableForDefaults() throws InvocationTargetException {
			TableItem[] items = validatorsTable.getItems();
			for (int i = 0; i < items.length; i++) {
				TableItem item = items[i];
				ValidatorMetaData vmd = (ValidatorMetaData) item.getData();

				// Should the validator be enabled? Read the user's preferences from last time,
				// if they exist, and set from that. If they don't exist, use the Validator class'
				if(pagePreferences.isEnabled(vmd)) {
					vmd.setManualValidation(true);
					vmd.setBuildValidation(true);
				} else {
					vmd.setManualValidation(false);
					vmd.setBuildValidation(false);
				}
			}
			validatorList.refresh();
		}

		/**
		 * @param overridePreferences
		 */
		private void enableDependentControls(boolean overridePreferences) {
			validatorsTable.setEnabled(overridePreferences);
      validatorList.refresh();
			enableAllButton.setEnabled(overridePreferences); // since help messsage isn't
			disableAllButton.setEnabled(overridePreferences);
      
		}

		protected void updateHelp() throws InvocationTargetException {
			// Whenever a widget is disabled, it cannot get focus.
			// Since it can't have focus, its context-sensitive F1 help can't come up.
			// From experimentation, I know that the composite parent of the widget
			// can't have focus either. So, fudge the focus by making the table the widget
			// surrogate so that the F1 help can be shown, with its instructions on how to
			// enable the disabled widget. The table never has F1 help associated with it other
			// than the page F1, so this fudge doesn't remove any context-sensitive help
			// from the table widget.

			/*if (autoButton.getEnabled()) {
				// set the table's help back to what it was
				PlatformUI.getWorkbench().getHelpSystem().setHelp(validatorList.getTable(), ContextIds.VALIDATION_PROPERTIES_PAGE);
				PlatformUI.getWorkbench().getHelpSystem().setHelp(autoButton, ContextIds.VALIDATION_PROPERTIES_PAGE_AUTO_ENABLED);
			} else {
				// The order of the following if statement is important!
				// If the user cannot enable automatic validation on the project, then the user
				// should not be told, for example, to turn auto-build on. Let the user know that
				// no matter what they do they cannot run auto-validate on the project. IF the
				// project
				// supports auto-validate, THEN check for the items which the user can change.
				validatorList.getTable().setFocus();
				if (pagePreferences.numberOfIncrementalValidators() == 0) {
					PlatformUI.getWorkbench().getHelpSystem().setHelp(validatorList.getTable(), ContextIds.VALIDATION_PROPERTIES_PAGE_DISABLED_AUTO_NOINCVALCONFIG);
				} else if (!ValidatorManager.getManager().isGlobalAutoBuildEnabled()) {
					PlatformUI.getWorkbench().getHelpSystem().setHelp(validatorList.getTable(), ContextIds.VALIDATION_PROPERTIES_PAGE_DISABLED_AUTO_AUTOBUILD);
				} else {
					// Incremental validators configured but not selected
					PlatformUI.getWorkbench().getHelpSystem().setHelp(validatorList.getTable(), ContextIds.VALIDATION_PROPERTIES_PAGE_DISABLED_AUTO_NOINCVALSELECTED);
				}
			}

			// if autoButton AND build button are disabled, show the build button's "to enable" text
			if (valWhenBuildButton.getEnabled()) {
				// Do NOT set the table's help back to what it was.
				// Only if auto-validate is enabled should the page go back.
				PlatformUI.getWorkbench().getHelpSystem().setHelp(valWhenBuildButton, ContextIds.VALIDATION_PROPERTIES_PAGE_REBUILD_ENABLED);
			} else {
				//				page.getParent().setFocus();
				validatorList.getTable().setFocus();
				PlatformUI.getWorkbench().getHelpSystem().setHelp(validatorList.getTable(), ContextIds.VALIDATION_PROPERTIES_PAGE_DISABLED_BUILD_NOVALSELECTED);
			}
*/
			// if the override button is disabled, show its "to enable" text.
			if (overrideGlobalButton.getEnabled()) {
				// Do NOT set the table's help back to what it was.
				// Only if auto-validate is enabled should the page go back.
				boolean doesProjectSupportBuildValidation = ValidatorManager.doesProjectSupportBuildValidation(getProject());
				GlobalConfiguration gp = ConfigurationManager.getManager().getGlobalConfiguration();
				//boolean isPrefAuto = gp.isAutoValidate();
				//boolean isPrefManual = gp.isBuildValidate();
				if (doesProjectSupportBuildValidation) {
					// Project supports build validation, so it doesn't matter what the preferences
					// are
					PlatformUI.getWorkbench().getHelpSystem().setHelp(overrideGlobalButton, ContextIds.VALIDATION_PROPERTIES_PAGE_OVERRIDE_ENABLED);
				} /*else if (!doesProjectSupportBuildValidation && (isPrefAuto && isPrefManual)) {
					// Project doesn't support build validation, and the user prefers both auto and
					// manual build validation
					PlatformUI.getWorkbench().getHelpSystem().setHelp(overrideGlobalButton, ContextIds.VALIDATION_PROPERTIES_PAGE_OVERRIDE_ENABLED_CANNOT_HONOUR_BOTH);
				} else if (!doesProjectSupportBuildValidation && isPrefAuto) {
					// Project doesn't support build validation, and the user prefers auto build
					// validation
					PlatformUI.getWorkbench().getHelpSystem().setHelp(overrideGlobalButton, ContextIds.VALIDATION_PROPERTIES_PAGE_OVERRIDE_ENABLED_CANNOT_HONOUR_AUTO);
				} else if (!doesProjectSupportBuildValidation && isPrefManual) {
					// Project doesn't support build validation, and the user prefers manual build
					// validation
					PlatformUI.getWorkbench().getHelpSystem().setHelp(overrideGlobalButton, ContextIds.VALIDATION_PROPERTIES_PAGE_OVERRIDE_ENABLED_CANNOT_HONOUR_MANUAL);
				} else if (!doesProjectSupportBuildValidation && !isPrefAuto && !isPrefManual) {
					// Project doesn't support build validation, but that doesn't matter because the
					// user prefers no build validation.
					PlatformUI.getWorkbench().getHelpSystem().setHelp(overrideGlobalButton, ContextIds.VALIDATION_PROPERTIES_PAGE_OVERRIDE_ENABLED);
				}*/
			} else {
				validatorList.getTable().setFocus();
				// Preference page doesn't allow projects to override
				PlatformUI.getWorkbench().getHelpSystem().setHelp(validatorList.getTable(), ContextIds.VALIDATION_PROPERTIES_PAGE_DISABLED_OVERRIDE);
			}
		}

		/*
		 * Store the current values of the controls into the preference store.
		 */
		private void storeValues() throws InvocationTargetException {
			pagePreferences.setDoesProjectOverride(overrideGlobalButton.getSelection());

			if (pagePreferences.doesProjectOverride()) {
				pagePreferences.setEnabledManualValidators(getManualEnabledValidators());
				pagePreferences.setEnabledBuildValidators(getBuildEnabledValidators());
			} else {
				pagePreferences.resetToDefault(); // If the project can't or doesn't override,
				// update its values to match the global
				// preference values.
			}
			pagePreferences.store();
		}

		/**
		 * Reads the list of validators, enables the validators which are selected, disables the
		 * validators which are not selected, and if the auto-validate checkbox is chosen, performs
		 * a full validation.
		 */
		public boolean performOk() throws InvocationTargetException {
			// addBuilder MUST be called before storeValues
			// addBuilder adds a builder to the project, and that changes the project description.
			// Changing a project's description triggers the validation framework's "natureChange"
			// migration, and a nature change requires that the list of validators be recalculated.
			// If the builder is added after the values are stored, the stored values are
			// overwritten.
			addBuilder();

			// If this method is being called because an APPLY was hit instead of an OK,
			// recalculate the "can build be enabled" status because the builder may have
			// been added in the addBuilder() call above.
			// Also recalculate the values that depend on the isBuilderConfigured value.
			//isBuilderConfigured = ValidatorManager.doesProjectSupportBuildValidation(getProject());

			// Persist the values.
			storeValues();

			if (pagePreferences.hasEnabledValidatorsChanged(oldVmd, false) ||
          pagePreferences.haveDelegatesChanged(oldDelegates, false)) { 
				// false means that the preference "allow" value hasn't changed
				ValidatorManager.getManager().updateTaskList(getProject()); 
			}

			return true;
		}

		/**
		 * If the current project doesn't have the validation builder configured on it, add the
		 * builder. Otherwise return without doing anything.
		 */
		private void addBuilder() {
			if (addValidationBuilder.isEnabled() && addValidationBuilder.getSelection())
				ValidatorManager.addProjectBuildValidationSupport(getProject());
		}

		public Composite getControl() {
			return page;
		}

		public void dispose() {
			enableAllButton.dispose();
			disableAllButton.dispose();
			validatorList.getTable().dispose();
			messageLabel.dispose();
			//			layout.dispose();
			//			data.dispose();
			emptyRowPlaceholder.dispose();
			overrideGlobalButton.dispose();
			page.dispose();
			color.dispose();
		}

		public boolean performCancel() {
			pagePreferences.setDoesProjectOverride(existingOverrideGlobalVal);
			pagePreferences.setDisableAllValidation(existingDisableAllValidation);
			return true;
		}
	}

	/**
	 * ValidationPreferencePage constructor comment.
	 */
	public ValidationPropertiesPage() {
		// Some of the initialization is done in the "initialize" method, which is
		// called by the "getPageType" method, because the current project must
		// be known in order to initialize those fields.
	}

	/**
	 * Given a parent (the Properties guide), create the Validators page to be added to it.
	 */
	protected Control createContents(Composite parent) {
		IProject project = getProject();

		if ((project == null) || !project.isOpen()) {
			_pageImpl = new InvalidPage(parent);
		} else {
			try {
				if (ConfigurationManager.getManager().getProjectConfiguration(project).numberOfValidators() == 0) {
					_pageImpl = new NoValidatorsPage(parent);
				} else {
					_pageImpl = new ValidatorListPage(parent);
				}
			} catch (InvocationTargetException exc) {
				_pageImpl = new InvalidPage(parent);
				displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
			} catch (Throwable exc) {
				_pageImpl = new InvalidPage(parent);
				displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
			}
		}

		return _pageImpl.getControl();
	}

	/**
	 * Since the pages are inner classes of a child PreferencePage, not a PreferencePage itself,
	 * DialogPage's automatic disposal of its children's widgets cannot be used. Instead, dispose of
	 * each inner class' widgets explicitly.
	 */
	public void dispose() {
		super.dispose();
		try {
			_pageImpl.dispose();
		} catch (Throwable exc) {
			logError(exc);
		}
	}

	/**
	 * Returns the highlighted item in the workbench.
	 */
	public IProject getProject() {
		Object element = getElement();

		if (element == null) {
			return null;
		}

		if (element instanceof IProject) {
			return (IProject) element;
		}

		return null;
	}

	protected void noDefaultAndApplyButton() {
		super.noDefaultAndApplyButton();
	}

	/**
	 * Performs special processing when this page's Defaults button has been pressed.
	 * <p>
	 * This is a framework hook method for sublcasses to do special things when the Defaults button
	 * has been pressed. Subclasses may override, but should call <code>super.performDefaults</code>.
	 * </p>
	 */
	protected void performDefaults() {
		super.performDefaults();
		try {
			_pageImpl.performDefaults();
		} catch (InvocationTargetException exc) {
			displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
		} catch (Throwable exc) {
			displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
		}
	}
	
	public boolean performCancel() {
		_pageImpl.performCancel();
		return true;
	}

	/**
	 * When the user presses the "OK" or "Apply" button on the Properties Guide/Properties Page,
	 * respectively, some processing is performed by this PropertyPage. If the page is found, and
	 * completes successfully, true is returned. Otherwise, false is returned, and the guide doesn't
	 * finish.
	 */
	public boolean performOk() {
		try {
			return _pageImpl.performOk();
		} catch (InvocationTargetException exc) {
			displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
			return false;
		} catch (Throwable exc) {
			displayAndLogError(ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_TITLE), ResourceHandler.getExternalizedMessage(ResourceConstants.VBF_EXC_INTERNAL_PAGE), exc);
			return false;
		}
	}

	void logError(Throwable exc) {
		Logger logger = WTPUIPlugin.getLogger();
		if (logger.isLoggingLevel(Level.SEVERE)) {
			LogEntry entry = ValidationUIPlugin.getLogEntry();
			entry.setSourceIdentifier("ValidationPropertiesPage.displayAndLogError"); //$NON-NLS-1$
			entry.setMessageTypeIdentifier(ResourceConstants.VBF_EXC_INTERNAL_PAGE);
			entry.setTargetException(exc);
			logger.write(Level.SEVERE, entry);

			if (exc instanceof InvocationTargetException) {
				if (((InvocationTargetException) exc).getTargetException() != null) {
					entry.setTargetException(((InvocationTargetException) exc).getTargetException());
					logger.write(Level.SEVERE, entry);
				}
			}
		}
	}

	void displayAndLogError(String title, String message, Throwable exc) {
		logError(exc);
		displayMessage(title, message, org.eclipse.swt.SWT.ICON_ERROR);
	}

	private void displayMessage(String title, String message, int iIconType) {
		MessageBox messageBox = new MessageBox(getShell(), org.eclipse.swt.SWT.OK | iIconType | org.eclipse.swt.SWT.APPLICATION_MODAL);
		messageBox.setMessage(message);
		messageBox.setText(title);
		messageBox.open();
	}

	/**
	 * @see org.eclipse.jface.preference.PreferencePage#getDefaultsButton()
	 */
	protected Button getDefaultsButton() {
		return super.getDefaultsButton();
	}
}