/*******************************************************************************
 * Copyright (c) 2001, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 * IBM Corporation - initial API and implementation
 * David Schneider, david.schneider@unisys.com - [142500] WTP properties pages fonts don't follow Eclipse preferences
 *******************************************************************************/
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.dialogs.Dialog;
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(ResourceHandler.getExternalizedMessage(ResourceConstants.VALIDATOR));
	        validatorColumn.setResizable(false);
	        validatorColumn.setWidth(320);
	        TableColumn manualColumn = new TableColumn(table, SWT.NONE);
	        manualColumn.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.MANUAL));
	        manualColumn.setResizable(false);
	        manualColumn.setWidth(40);
	        TableColumn buildColumn = new TableColumn(table, SWT.NONE);
	        buildColumn.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.BUILD));
	        buildColumn.setResizable(false);
	        buildColumn.setWidth(40);
          TableColumn settingsColumn = new TableColumn(table, SWT.NONE);
          settingsColumn.setText(ResourceHandler.getExternalizedMessage(ResourceConstants.SETTINGS));
          settingsColumn.setResizable(false);
          settingsColumn.setWidth(50);
	    }

		/**
		 * 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();

		    Dialog.applyDialogFont(parent);
			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();
	}
}