/*******************************************************************************
 * Copyright (c) 2005, 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
 *******************************************************************************/
package org.eclipse.ltk.ui.refactoring.history;

import com.ibm.icu.text.MessageFormat;

import java.lang.reflect.InvocationTargetException;
import java.text.ChoiceFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;

import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
import org.eclipse.ltk.core.refactoring.CreateChangeOperation;
import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
import org.eclipse.ltk.core.refactoring.PerformRefactoringHistoryOperation;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryService;
import org.eclipse.ltk.core.refactoring.history.RefactoringHistory;

import org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryImplementation;
import org.eclipse.ltk.internal.ui.refactoring.ChangeExceptionHandler;
import org.eclipse.ltk.internal.ui.refactoring.ExceptionHandler;
import org.eclipse.ltk.internal.ui.refactoring.IErrorWizardPage;
import org.eclipse.ltk.internal.ui.refactoring.IPreviewWizardPage;
import org.eclipse.ltk.internal.ui.refactoring.IRefactoringHelpContextIds;
import org.eclipse.ltk.internal.ui.refactoring.Messages;
import org.eclipse.ltk.internal.ui.refactoring.RefactoringHistoryPreviewPage;
import org.eclipse.ltk.internal.ui.refactoring.RefactoringPluginImages;
import org.eclipse.ltk.internal.ui.refactoring.RefactoringPreviewChangeFilter;
import org.eclipse.ltk.internal.ui.refactoring.RefactoringStatusEntryFilter;
import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIMessages;
import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIPlugin;
import org.eclipse.ltk.internal.ui.refactoring.UIPerformChangeOperation;
import org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter;
import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryErrorPage;
import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryOverviewPage;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.jface.action.LegacyActionTools;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jface.wizard.WizardPage;

import org.eclipse.ui.PlatformUI;

/**
 * A default implementation of a refactoring history wizard. Refactoring history
 * wizards are used to execute the refactorings described by a refactoring
 * history. A refactoring history wizard differs from a normal wizard in the
 * following characteristics:
 * <ul>
 * <li>A refactoring history wizard consists of a sequence of one error page to
 * present the outcome of a refactoring's condition checking and one preview
 * page to present a preview of the workspace changes.</li>
 * <li> Refactorings are applied to the workspace as soon as a preview has been
 * accepted. Additionally, refactoring history wizards support the headless
 * execution of refactorings. The user guided execution of a refactoring history
 * triggers a series of error pages and preview pages. Within this sequence of
 * pages, going back is not supported anymore. However, canceling the
 * refactoring history wizard will undo the already performed refactorings.</li>
 * </ul>
 * <p>
 * A refactoring history wizard is usually opened using the {@link WizardDialog}.
 * Clients must ensure that the calling thread holds the workspace lock.
 * </p>
 * <p>
 * Note: this class is intended to be extended by clients.
 * </p>
 * 
 * @see org.eclipse.ltk.core.refactoring.Refactoring
 * @see org.eclipse.ltk.core.refactoring.history.RefactoringHistory
 * 
 * @since 3.2
 */
public class RefactoringHistoryWizard extends Wizard {

	/** The no overview wizard page */
	private final class NoOverviewWizardPage extends WizardPage {

		/** The no overview wizard page name */
		private static final String PAGE_NAME= "NoOverviewWizardPage"; //$NON-NLS-1$

		/**
		 * Creates a new no overview wizard page.
		 */
		private NoOverviewWizardPage() {
			super(PAGE_NAME);
			final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptors();
			if (proxies.length > 0)
				setTitle(proxies[0], 1, proxies.length);
			else
				setTitle(fOverviewTitle);
			setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_description);
		}

		/**
		 * {@inheritDoc}
		 */
		public boolean canFlipToNextPage() {
			return true;
		}

		/**
		 * {@inheritDoc}
		 */
		public void createControl(final Composite parent) {
			final Composite composite= new Composite(parent, SWT.NULL);
			composite.setLayout(new GridLayout());
			composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
			setControl(composite);
			Dialog.applyDialogFont(composite);
			PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IRefactoringHelpContextIds.REFACTORING_PREVIEW_WIZARD_PAGE);
		}

		/**
		 * {@inheritDoc}
		 */
		public IWizardPage getNextPage() {
			return getWizard().getNextPage(this);
		}

		/**
		 * {@inheritDoc}
		 */
		public IWizardPage getPreviousPage() {
			return getWizard().getPreviousPage(this);
		}

		/**
		 * {@inheritDoc}
		 */
		public void setPageComplete(final boolean complete) {
			super.setPageComplete(true);
		}

		/**
		 * Sets the title of the page according to the refactoring.
		 * 
		 * @param descriptor
		 *            the refactoring descriptor, or <code>null</code>
		 * @param current
		 *            the non-zero based index of the current refactoring
		 * @param total
		 *            the total number of refactorings
		 */
		public void setTitle(final RefactoringDescriptorProxy descriptor, final int current, final int total) {
			final String message;
			if (descriptor != null)
				message= descriptor.getDescription();
			else
				message= RefactoringUIMessages.RefactoringHistoryOverviewPage_title;
			if (total > 1)
				setTitle(Messages.format(RefactoringUIMessages.RefactoringHistoryPreviewPage_refactoring_pattern, new String[] { message, String.valueOf(current + 1), String.valueOf(total)}));
			else
				setTitle(message);
		}
	}

	/** Preference key for the show apply preference */
	private static final String PREFERENCE_DO_NOT_SHOW_APPLY_ERROR= RefactoringUIPlugin.getPluginId() + ".do.not.show.apply.refactoring"; //$NON-NLS-1$;

	/** Preference key for the show skip preference */
	private static final String PREFERENCE_DO_NOT_SHOW_SKIP= RefactoringUIPlugin.getPluginId() + ".do.not.show.skip.refactoring"; //$NON-NLS-1$

	/** Preference key for the warn finish preference */
	private static final String PREFERENCE_DO_NOT_WARN_FINISH= RefactoringUIPlugin.getPluginId() + ".do.not.warn.finish.wizard"; //$NON-NLS-1$;

	/** Preference key for the warn undo on cancel preference */
	private static final String PREFERENCE_DO_NOT_WARN_UNDO_ON_CANCEL= RefactoringUIPlugin.getPluginId() + ".do.not.warn.undo.on.cancel.refactoring"; //$NON-NLS-1$;

	/**
	 * The status code representing an interrupted operation.
	 * <p>
	 * Note: This API must not be used from outside the refactoring framework.
	 * </p>
	 */
	public static final int STATUS_CODE_INTERRUPTED= 10003;


	/** Has the about to perform history event already been fired? */
	private boolean fAboutToPerformFired= false;

	/** Has an exception occurred while cancelling the wizard? */
	private boolean fCancelException= false;

	/** The refactoring history control configuration to use */
	private RefactoringHistoryControlConfiguration fControlConfiguration;

	/** The index of the currently executed refactoring */
	private int fCurrentRefactoring= 0;

	/**
	 * The refactoring descriptor proxies, in ascending order of their time
	 * stamps, or <code>null</code>
	 */
	private RefactoringDescriptorProxy[] fDescriptorProxies= null;

	/** The error wizard page */
	private final RefactoringHistoryErrorPage fErrorPage;

	/** The number of successfully executed refactorings */
	private int fExecutedRefactorings= 0;

	/** Are we currently in method <code>addPages</code>? */
	private boolean fInAddPages= false;

	/**
	 * The no overview wizard page, or <code>null</code> if an overview is
	 * desired
	 */
	private NoOverviewWizardPage fNoOverviewPage;

	/** The description of the overview page */
	private final String fOverviewDescription;

	/**
	 * The overview wizard page, or <code>null</code> if no overview is
	 * desired
	 */
	private RefactoringHistoryOverviewPage fOverviewPage;

	/** The title of the overview page */
	private final String fOverviewTitle;

	/** The preview change filter */
	private RefactoringPreviewChangeFilter fPreviewChangeFilter= new RefactoringPreviewChangeFilter() {

		/**
		 * {@inheritDoc}
		 */
		public final boolean select(final Change change) {
			return selectPreviewChange(change);
		}
	};

	/** The preview wizard page */
	private final RefactoringHistoryPreviewPage fPreviewPage;

	/** The refactoring history to execute */
	private RefactoringHistory fRefactoringHistory;

	/** Does the wizard show an overview of the refactorings? */
	private final boolean fShowOverview;

	/** The status entry filter */
	private RefactoringStatusEntryFilter fStatusEntryFilter= new RefactoringStatusEntryFilter() {

		/**
		 * {@inheritDoc}
		 */
		public final boolean select(final RefactoringStatusEntry entry) {
			return selectStatusEntry(entry);
		}
	};

	/**
	 * Creates a new refactoring history wizard.
	 * <p>
	 * Clients must ensure that the refactoring history and the refactoring
	 * history control configuration are set before opening the wizard in a
	 * dialog.
	 * </p>
	 * 
	 * @param overview
	 *            <code>true</code> to show an overview of the refactorings,
	 *            <code>false</code> otherwise
	 * @param caption
	 *            the caption of the wizard window
	 * @param title
	 *            the title of the overview page
	 * @param description
	 *            the description of the overview page
	 * 
	 * @see #setConfiguration(RefactoringHistoryControlConfiguration)
	 * @see #setInput(RefactoringHistory)
	 */
	public RefactoringHistoryWizard(final boolean overview, final String caption, final String title, final String description) {
		Assert.isNotNull(caption);
		Assert.isNotNull(title);
		Assert.isNotNull(description);
		fShowOverview= overview;
		fOverviewTitle= title;
		fOverviewDescription= description;
		fErrorPage= new RefactoringHistoryErrorPage();
		fErrorPage.setFilter(fStatusEntryFilter);
		fPreviewPage= new RefactoringHistoryPreviewPage();
		fPreviewPage.setFilter(fPreviewChangeFilter);
		setNeedsProgressMonitor(true);
		setWindowTitle(caption);
		setDefaultPageImageDescriptor(RefactoringPluginImages.DESC_WIZBAN_REFACTOR);
	}

	/**
	 * Creates a new refactoring history wizard.
	 * <p>
	 * Clients must ensure that the refactoring history and the refactoring
	 * history control configuration are set before opening the wizard in a
	 * dialog.
	 * </p>
	 * <p>
	 * Calling his constructor is equivalent to
	 * {@link #RefactoringHistoryWizard(boolean, String, String, String)} with
	 * the first argument equal to <code>true</code>.
	 * </p>
	 * 
	 * @param caption
	 *            the caption of the wizard window
	 * @param title
	 *            the title of the overview page
	 * @param description
	 *            the description of the overview page
	 * 
	 * @see #setConfiguration(RefactoringHistoryControlConfiguration)
	 * @see #setInput(RefactoringHistory)
	 */
	public RefactoringHistoryWizard(final String caption, final String title, final String description) {
		this(true, caption, title, description);
	}

	/**
	 * Hook method which is called before the first refactoring of the history
	 * is executed. This method may be called from non-UI threads.
	 * <p>
	 * This method is guaranteed to be called exactly once during the lifetime
	 * of a refactoring history wizard. The default implementation does nothing
	 * and returns a refactoring status of severity {@link RefactoringStatus#OK}.
	 * </p>
	 * <p>
	 * Subclasses may reimplement this method to perform any special processing.
	 * </p>
	 * <p>
	 * Returning a status of severity {@link RefactoringStatus#FATAL} will
	 * terminate the execution of the refactorings.
	 * </p>
	 * 
	 * @param monitor
	 *            the progress monitor to use
	 * 
	 * @return a status describing the outcome of the operation
	 */
	protected RefactoringStatus aboutToPerformHistory(final IProgressMonitor monitor) {
		Assert.isNotNull(monitor);
		fExecutedRefactorings= 0;
		return new RefactoringStatus();
	}

	/**
	 * Hook method which is called before the a refactoring of the history is
	 * executed. The refactoring itself is in an initialized state at the time
	 * of the method call. The default implementation does nothing and returns a
	 * status of severity {@link RefactoringStatus#OK}. This method may be
	 * called from non-UI threads.
	 * <p>
	 * Subclasses may extend this method to perform any special processing.
	 * </p>
	 * <p>
	 * Returning a status of severity {@link RefactoringStatus#FATAL} will
	 * terminate the execution of the current refactoring.
	 * </p>
	 * 
	 * @param refactoring
	 *            the refactoring about to be executed
	 * @param descriptor
	 *            the refactoring descriptor
	 * @param monitor
	 *            the progress monitor to use
	 * @return a status describing the outcome of the initialization
	 */
	protected RefactoringStatus aboutToPerformRefactoring(final Refactoring refactoring, final RefactoringDescriptor descriptor, final IProgressMonitor monitor) {
		Assert.isNotNull(refactoring);
		Assert.isNotNull(descriptor);
		return new RefactoringStatus();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * Clients must contribute their wizard pages by re-implementing
	 * {@link #addUserDefinedPages()}.
	 */
	public final void addPage(final IWizardPage page) {
		Assert.isTrue(fInAddPages);
		super.addPage(page);
	}

	/**
	 * {@inheritDoc}
	 */
	public final void addPages() {
		try {
			fInAddPages= true;
			addUserDefinedPages();
			Assert.isNotNull(fRefactoringHistory);
			Assert.isNotNull(fControlConfiguration);
			if (fShowOverview) {
				fOverviewPage= new RefactoringHistoryOverviewPage(fRefactoringHistory, fOverviewTitle, fOverviewDescription, fControlConfiguration);
				addPage(fOverviewPage);
			} else {
				fNoOverviewPage= new NoOverviewWizardPage();
				addPage(fNoOverviewPage);
			}
			addPage(fErrorPage);
			addPage(fPreviewPage);
		} finally {
			fInAddPages= false;
		}
	}

	/**
	 * Adds user defined wizard pages in front of the wizard.
	 * <p>
	 * Clients may extend this method to add custom wizard pages in front of the
	 * wizard.
	 * </p>
	 */
	protected void addUserDefinedPages() {
		Assert.isTrue(fInAddPages);

		// Do not add any as default
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean canFinish() {
		final IWizardPage page= getContainer().getCurrentPage();
		if (page == fErrorPage) {
			final RefactoringStatus status= fErrorPage.getStatus();
			return status == null || !status.hasFatalError();
		}
		return true;
	}

	/**
	 * Checks the specified kind of conditions of the refactoring.
	 * 
	 * @param refactoring
	 *            the refactoring to check its conditions
	 * @param monitor
	 *            the progress monitor to use
	 * @param style
	 *            the condition checking style
	 * @throws OperationCanceledException
	 *             if the operation has been cancelled
	 * @return the resulting status
	 */
	private RefactoringStatus checkConditions(final Refactoring refactoring, final IProgressMonitor monitor, final int style) throws OperationCanceledException {
		Assert.isNotNull(refactoring);
		Assert.isNotNull(monitor);
		final RefactoringStatus status= new RefactoringStatus();
		try {
			final CheckConditionsOperation operation= new CheckConditionsOperation(refactoring, style);
			operation.run(monitor);
			status.merge(operation.getStatus());
		} catch (CoreException exception) {
			RefactoringUIPlugin.log(exception);
			status.addFatalError(RefactoringUIMessages.RefactoringWizard_internal_error_1);
		}
		return status;
	}

	/**
	 * Creates the change for the specified refactoring.
	 * 
	 * @param refactoring
	 *            the refactoring
	 * @param monitor
	 *            the progress monitor
	 * @return the created change
	 * @throws OperationCanceledException
	 *             if the operation has been cancelled
	 * @throws CoreException
	 *             if an error occurs while creating the change
	 */
	private Change createChange(final Refactoring refactoring, final IProgressMonitor monitor) throws OperationCanceledException, CoreException {
		Assert.isNotNull(refactoring);
		Assert.isNotNull(monitor);
		final CreateChangeOperation operation= new CreateChangeOperation(refactoring);
		operation.run(monitor);
		return operation.getChange();
	}

	/**
	 * Method which is called to create a refactoring instance from a
	 * refactoring descriptor. The refactoring must be in an initialized state
	 * after the return of the method call. The default implementation delegates
	 * the task to the refactoring descriptor. This method may be called from
	 * non-UI threads.
	 * <p>
	 * Subclasses may reimplement this method to customize the initialization of
	 * a refactoring.
	 * </p>
	 * 
	 * @param descriptor
	 *            the refactoring descriptor
	 * @param status
	 *            a refactoring status describing the outcome of the
	 *            initialization
	 * @return the refactoring, or <code>null</code> if this refactoring
	 *         descriptor represents the unknown refactoring, or if no
	 *         refactoring contribution is available for this refactoring
	 *         descriptor
	 * @throws CoreException
	 *             if an error occurs while creating the refactoring instance
	 */
	protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status) throws CoreException {
		Assert.isNotNull(descriptor);
		return descriptor.createRefactoring(status);
	}

	/**
	 * Creates a refactoring from the specified refactoring descriptor.
	 * 
	 * @param descriptor
	 *            the refactoring descriptor
	 * @param status
	 *            the refactoring status
	 * @param monitor
	 *            the progress monitor to use
	 * @return the refactoring, or <code>null</code> if this refactoring
	 *         descriptor represents the unknown refactoring, or if no
	 *         refactoring contribution is available for this refactoring
	 *         descriptor
	 * @throws CoreException
	 *             if an error occurs while creating the refactoring instance
	 */
	private Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
		final Refactoring refactoring= createRefactoring(descriptor, status);
		if (refactoring != null) {
			status.merge(aboutToPerformRefactoring(refactoring, descriptor, monitor));
			if (!status.hasFatalError())
				return refactoring;
		} else
			status.addFatalError(Messages.format(RefactoringUIMessages.RefactoringHistoryWizard_error_instantiate_refactoring, descriptor.getDescription()));
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	public void dispose() {
		SafeRunner.run(new ISafeRunnable() {

			public void handleException(final Throwable exception) {
				RefactoringUIPlugin.log(exception);
			}

			public final void run() throws Exception {
				if (fAboutToPerformFired) {
					final RefactoringStatusEntry entry= historyPerformed(new NullProgressMonitor()).getEntryWithHighestSeverity();
					if (entry != null)
						RefactoringUIPlugin.log(entry.toStatus());
				}
			}
		});
		super.dispose();
	}

	/**
	 * Fires the about to perform history event.
	 * 
	 * @param monitor
	 *            the progress monitor to use
	 * 
	 * @return a status describing the outcome of the operation
	 */
	private RefactoringStatus fireAboutToPerformHistory(final IProgressMonitor monitor) {
		final RefactoringStatus status= new RefactoringStatus();
		SafeRunner.run(new ISafeRunnable() {

			public void handleException(final Throwable exception) {
				RefactoringUIPlugin.log(exception);
				status.addFatalError(RefactoringUIMessages.RefactoringWizard_unexpected_exception_1);
			}

			public final void run() throws Exception {
				status.merge(aboutToPerformHistory(monitor));
			}
		});
		return status;
	}

	/**
	 * Returns the error wizard page.
	 * <p>
	 * Note: This API must not be called from outside the refactoring framework.
	 * </p>
	 * 
	 * @return the error wizard page
	 */
	public final IErrorWizardPage getErrorPage() {
		return fErrorPage;
	}

	/**
	 * {@inheritDoc}
	 */
	public IWizardPage getNextPage(final IWizardPage page) {
		if (page == fOverviewPage || page == fNoOverviewPage) {
			fCurrentRefactoring= 0;
			return getRefactoringPage();
		} else if (page == fPreviewPage) {
			fCurrentRefactoring++;
			return getRefactoringPage();
		} else if (page == fErrorPage) {
			final RefactoringStatus status= fErrorPage.getStatus();
			final IWizardContainer wizard= getContainer();
			if (status.hasFatalError()) {
				final IPreferenceStore store= RefactoringUIPlugin.getDefault().getPreferenceStore();
				String message= null;
				String key= null;
				if (!RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error_title.equals(fErrorPage.getTitle())) {
					message= Messages.format(RefactoringUIMessages.RefactoringHistoryWizard_fatal_error_message, fErrorPage.getTitle());
					key= PREFERENCE_DO_NOT_SHOW_SKIP;
				} else {
					message= RefactoringUIMessages.RefactoringHistoryWizard_error_applying_changes;
					key= PREFERENCE_DO_NOT_SHOW_APPLY_ERROR;
				}
				if (!store.getBoolean(key)) {
					final MessageDialogWithToggle dialog= new MessageDialogWithToggle(getShell(), wizard.getShell().getText(), null, message, MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0, RefactoringUIMessages.RefactoringHistoryWizard_do_not_show_message, false);
					dialog.open();
					store.setValue(key, dialog.getToggleState());
					if (dialog.getReturnCode() == 1)
						return null;
				}
				fCurrentRefactoring++;
				return getRefactoringPage();
			}
			final Refactoring refactoring= fErrorPage.getRefactoring();
			if (refactoring != null) {
				final IRunnableWithProgress runnable= new IRunnableWithProgress() {

					public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
						Assert.isNotNull(monitor);
						try {
							fPreviewPage.setRefactoring(refactoring);
							final Change change= createChange(refactoring, monitor);
							getShell().getDisplay().syncExec(new Runnable() {

								public final void run() {
									fPreviewPage.setChange(change);
								}
							});
						} catch (CoreException exception) {
							throw new InvocationTargetException(exception);
						} catch (OperationCanceledException exception) {
							throw new InterruptedException(exception.getLocalizedMessage());
						} finally {
							monitor.done();
						}
					}
				};
				try {
					wizard.run(true, false, runnable);
				} catch (InvocationTargetException exception) {
					final Throwable throwable= exception.getTargetException();
					if (throwable != null) {
						RefactoringUIPlugin.log(exception);
						fErrorPage.setStatus(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringWizard_unexpected_exception_1));
						return fErrorPage;
					}
				} catch (InterruptedException exception) {
					return fErrorPage;
				}
			} else {
				fPreviewPage.setRefactoring(null);
				fPreviewPage.setChange(null);
			}
			final RefactoringDescriptorProxy descriptor= getRefactoringDescriptor();
			if (descriptor != null)
				fPreviewPage.setTitle(descriptor, fCurrentRefactoring, fDescriptorProxies.length);
			else
				fPreviewPage.setTitle(RefactoringUIMessages.PreviewWizardPage_changes);
			fPreviewPage.setStatus(status);
			fPreviewPage.setNextPageDisabled(isLastRefactoring());
			return fPreviewPage;
		}
		return super.getNextPage(page);
	}

	/**
	 * Returns the preview wizard page.
	 * <p>
	 * Note: This API must not be called from outside the refactoring framework.
	 * </p>
	 * 
	 * @return the preview wizard page
	 */
	public final IPreviewWizardPage getPreviewPage() {
		return fPreviewPage;
	}

	/**
	 * {@inheritDoc}
	 */
	public IWizardPage getPreviousPage(final IWizardPage page) {
		if (page == fErrorPage || page == fPreviewPage)
			return null;
		return super.getPreviousPage(page);
	}

	/**
	 * Returns the refactoring descriptor of the current refactoring.
	 * 
	 * @return the refactoring descriptor, or <code>null</code>
	 */
	private RefactoringDescriptorProxy getRefactoringDescriptor() {
		final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptors();
		if (fCurrentRefactoring >= 0 && fCurrentRefactoring < proxies.length)
			return proxies[fCurrentRefactoring];
		return null;
	}

	/**
	 * Returns the refactoring descriptors in their order of execution.
	 * 
	 * @return the refactoring descriptors
	 */
	private RefactoringDescriptorProxy[] getRefactoringDescriptors() {
		if (fDescriptorProxies == null) {
			final RefactoringDescriptorProxy[] proxies= fRefactoringHistory.getDescriptors();
			final RefactoringDescriptorProxy[] result= new RefactoringDescriptorProxy[proxies.length];
			System.arraycopy(proxies, 0, result, 0, proxies.length);
			Arrays.sort(result, new Comparator() {

				public final int compare(final Object first, final Object second) {
					final RefactoringDescriptorProxy predecessor= (RefactoringDescriptorProxy) first;
					final RefactoringDescriptorProxy successor= (RefactoringDescriptorProxy) second;
					final long delta= predecessor.getTimeStamp() - successor.getTimeStamp();
					if (delta > 0)
						return 1;
					else if (delta < 0)
						return -1;
					return 0;
				}
			});
			fDescriptorProxies= result;
		}
		return fDescriptorProxies;
	}

	/**
	 * Returns the first page of a refactoring.
	 * 
	 * @return the first page, or <code>null</code>
	 */
	private IWizardPage getRefactoringPage() {
		final IWizardPage[] result= { null};
		final RefactoringStatus status= new RefactoringStatus();
		final IWizardContainer wizard= getContainer();
		final IRunnableWithProgress runnable= new IRunnableWithProgress() {

			public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				Assert.isNotNull(monitor);
				try {
					monitor.beginTask(RefactoringUIMessages.RefactoringHistoryWizard_preparing_refactoring, 220);
					result[0]= null;
					if (!fAboutToPerformFired) {
						try {
							status.merge(fireAboutToPerformHistory(new SubProgressMonitor(monitor, 50, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)));
						} finally {
							fAboutToPerformFired= true;
						}
					}
					final boolean last= isLastRefactoring();
					final RefactoringDescriptorProxy proxy= getRefactoringDescriptor();
					preparePreviewPage(status, proxy, last);
					prepareErrorPage(status, proxy, status.hasFatalError(), last || status.hasFatalError());
					fErrorPage.setRefactoring(null);
					if (!status.isOK()) {
						result[0]= fErrorPage;
					} else if (proxy != null) {
						final IRefactoringHistoryService service= RefactoringCore.getHistoryService();
						try {
							service.connect();
							final RefactoringDescriptor descriptor= proxy.requestDescriptor(new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
							if (descriptor != null) {
								final Refactoring refactoring= createRefactoring(descriptor, status, new SubProgressMonitor(monitor, 60, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
								if (refactoring != null && status.isOK()) {
									fPreviewPage.setRefactoring(refactoring);
									fErrorPage.setRefactoring(refactoring);
									status.merge(checkConditions(refactoring, new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL), CheckConditionsOperation.INITIAL_CONDITONS));
									if (!status.isOK()) {
										prepareErrorPage(status, proxy, status.hasFatalError(), last);
										result[0]= fErrorPage;
									} else {
										status.merge(checkConditions(refactoring, new SubProgressMonitor(monitor, 65, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL), CheckConditionsOperation.FINAL_CONDITIONS));
										if (!status.isOK()) {
											prepareErrorPage(status, proxy, status.hasFatalError(), last);
											result[0]= fErrorPage;
										} else {
											final Change change= createChange(refactoring, new SubProgressMonitor(monitor, 5, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
											getShell().getDisplay().syncExec(new Runnable() {

												public final void run() {
													fPreviewPage.setChange(change);
												}
											});
											result[0]= fPreviewPage;
										}
									}
								} else {
									prepareErrorPage(status, proxy, status.hasFatalError(), last);
									result[0]= fErrorPage;
								}
							} else {
								status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringHistoryWizard_error_resolving_refactoring));
								prepareErrorPage(status, proxy, status.hasFatalError(), last);
								result[0]= fErrorPage;
							}
						} finally {
							service.disconnect();
						}
					} else {
						prepareErrorPage(status, proxy, status.hasFatalError(), last);
						result[0]= fErrorPage;
					}
				} catch (CoreException exception) {
					throw new InvocationTargetException(exception);
				} catch (OperationCanceledException exception) {
					throw new InterruptedException(exception.getLocalizedMessage());
				} finally {
					monitor.done();
				}
			}
		};
		try {
			wizard.run(true, false, runnable);
		} catch (InvocationTargetException exception) {
			RefactoringUIPlugin.log(exception);
			final Throwable throwable= exception.getTargetException();
			if (throwable != null) {
				fErrorPage.setNextPageDisabled(isLastRefactoring());
				fErrorPage.setStatus(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringWizard_unexpected_exception_1));
				result[0]= fErrorPage;
			}
		} catch (InterruptedException exception) {
			// Stay on same page
			result[0]= null;
		}
		getContainer().updateButtons();
		return result[0];
	}

	/**
	 * Hook method which is called when all refactorings of the history have
	 * been executed. This method may be called from non-UI threads.
	 * <p>
	 * This method is guaranteed to be called exactly once during the lifetime
	 * of a refactoring history wizard. It is not guaranteed that the user
	 * interface has not already been disposed of. The default implementation
	 * does nothing and returns a refactoring status of severity
	 * {@link RefactoringStatus#OK}.
	 * </p>
	 * <p>
	 * Subclasses may reimplement this method to perform any special processing.
	 * </p>
	 * 
	 * @param monitor
	 *            the progress monitor to use
	 * 
	 * @return a status describing the outcome of the operation
	 */
	protected RefactoringStatus historyPerformed(final IProgressMonitor monitor) {
		Assert.isNotNull(monitor);
		return new RefactoringStatus();
	}

	/**
	 * Is the current refactoring the last one?
	 * 
	 * @return <code>true</code> if it is the last one, <code>false</code>
	 *         otherwise
	 */
	private boolean isLastRefactoring() {
		return fCurrentRefactoring >= getRefactoringDescriptors().length - 1;
	}

	/**
	 * Is the current refactoring the second last one?
	 * 
	 * @return <code>true</code> if it is the second last one,
	 *         <code>false</code> otherwise
	 */
	private boolean isSecondLastRefactoring() {
		return fCurrentRefactoring >= getRefactoringDescriptors().length - 2;
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean performCancel() {
		if (fExecutedRefactorings > 0 && !fCancelException) {
			final IPreferenceStore store= RefactoringUIPlugin.getDefault().getPreferenceStore();
			if (!store.getBoolean(PREFERENCE_DO_NOT_WARN_UNDO_ON_CANCEL)) {
				final MessageFormat format= new MessageFormat(RefactoringUIMessages.RefactoringHistoryWizard_undo_message_pattern);
				final String message= RefactoringUIMessages.RefactoringHistoryWizard_undo_message_explanation;
				final String[] messages= { RefactoringUIMessages.RefactoringHistoryWizard_one_refactoring_undone + message, RefactoringUIMessages.RefactoringHistoryWizard_several_refactorings_undone + message};
				final ChoiceFormat choice= new ChoiceFormat(new double[] { 1, Double.MAX_VALUE}, messages);
				format.setFormatByArgumentIndex(0, choice);
				final MessageDialogWithToggle dialog= new MessageDialogWithToggle(getShell(), getShell().getText(), null, format.format(new Object[] { new Integer(fExecutedRefactorings)}), MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0, RefactoringUIMessages.RefactoringHistoryWizard_do_not_show_message, false);
				dialog.open();
				store.setValue(PREFERENCE_DO_NOT_WARN_UNDO_ON_CANCEL, dialog.getToggleState());
				if (dialog.getReturnCode() == 1)
					return false;
			}
			final IRunnableWithProgress runnable= new IRunnableWithProgress() {

				public final void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
					for (int index= 0; index < fExecutedRefactorings; index++) {
						try {
							RefactoringCore.getUndoManager().performUndo(null, new SubProgressMonitor(monitor, 100));
							if (fExecutedRefactorings > 0)
								fExecutedRefactorings--;
						} catch (CoreException exception) {
							throw new InvocationTargetException(exception);
						}
					}
				}
			};
			try {
				getContainer().run(false, false, runnable);
			} catch (InvocationTargetException exception) {
				RefactoringUIPlugin.log(exception);
				fCancelException= true;
				fErrorPage.setStatus(RefactoringStatus.createFatalErrorStatus(RefactoringUIMessages.RefactoringHistoryWizard_internal_error));
				fErrorPage.setNextPageDisabled(true);
				fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryWizard_internal_error_title);
				fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryWizard_internal_error_description);
				getContainer().showPage(fErrorPage);
				return false;
			} catch (InterruptedException exception) {
				// Does not happen
			}
		}
		return super.performCancel();
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean performFinish() {
		if (fOverviewPage != null)
			fOverviewPage.performFinish();
		final IWizardContainer wizard= getContainer();
		final RefactoringStatus status= new RefactoringStatus();
		final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptors();
		final List list= new ArrayList(proxies.length);
		for (int index= fCurrentRefactoring; index < proxies.length; index++)
			list.add(proxies[index]);
		final RefactoringDescriptorProxy[] descriptors= new RefactoringDescriptorProxy[list.size()];
		list.toArray(descriptors);
		final boolean last= isLastRefactoring();
		if (wizard.getCurrentPage() == fPreviewPage && last) {
			final Refactoring refactoring= fPreviewPage.getRefactoring();
			final Change change= fPreviewPage.getChange();
			if (refactoring != null && change != null) {
				status.merge(performPreviewChange(change, refactoring));
				if (!status.isOK()) {
					final RefactoringStatusEntry entry= status.getEntryWithHighestSeverity();
					if (entry.getSeverity() == RefactoringStatus.INFO && entry.getCode() == RefactoringHistoryWizard.STATUS_CODE_INTERRUPTED)
						return false;
					fErrorPage.setStatus(status);
					fErrorPage.setNextPageDisabled(true);
					fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error_title);
					fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error);
					wizard.showPage(fErrorPage);
					return false;
				}
			}
		} else {
			final IPreferenceStore store= RefactoringUIPlugin.getDefault().getPreferenceStore();
			if (!store.getBoolean(PREFERENCE_DO_NOT_WARN_FINISH) && proxies.length > 0) {
				final MessageDialogWithToggle dialog= new MessageDialogWithToggle(getShell(), wizard.getShell().getText(), null, Messages.format(RefactoringUIMessages.RefactoringHistoryWizard_warning_finish, LegacyActionTools.removeMnemonics(IDialogConstants.FINISH_LABEL)), MessageDialog.INFORMATION, new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0, RefactoringUIMessages.RefactoringHistoryWizard_do_not_show_message, false);
				dialog.open();
				store.setValue(PREFERENCE_DO_NOT_WARN_FINISH, dialog.getToggleState());
				if (dialog.getReturnCode() == IDialogConstants.CANCEL_ID)
					return false;
			}
			final PerformRefactoringHistoryOperation operation= new PerformRefactoringHistoryOperation(new RefactoringHistoryImplementation(descriptors)) {

				protected RefactoringStatus aboutToPerformRefactoring(final Refactoring refactoring, final RefactoringDescriptor descriptor, final IProgressMonitor monitor) {
					final RefactoringStatus[] result= { new RefactoringStatus()};
					SafeRunner.run(new ISafeRunnable() {

						public void handleException(final Throwable exception) {
							RefactoringUIPlugin.log(exception);
						}

						public final void run() throws Exception {
							result[0]= RefactoringHistoryWizard.this.aboutToPerformRefactoring(refactoring, descriptor, monitor);
						}
					});
					return result[0];
				}

				protected Refactoring createRefactoring(final RefactoringDescriptor descriptor, final RefactoringStatus state) throws CoreException {
					return RefactoringHistoryWizard.this.createRefactoring(descriptor, state);
				}

				protected void refactoringPerformed(final Refactoring refactoring, final IProgressMonitor monitor) {
					SafeRunner.run(new ISafeRunnable() {

						public void handleException(final Throwable exception) {
							RefactoringUIPlugin.log(exception);
						}

						public final void run() throws Exception {
							RefactoringHistoryWizard.this.refactoringPerformed(refactoring, monitor);
						}
					});
				}

				public void run(final IProgressMonitor monitor) throws CoreException {
					try {
						monitor.beginTask(RefactoringUIMessages.RefactoringHistoryWizard_preparing_refactorings, 100);
						if (!fAboutToPerformFired) {
							try {
								status.merge(fireAboutToPerformHistory(new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)));
							} finally {
								fAboutToPerformFired= true;
							}
						}
						if (!status.isOK()) {
							final int severity= status.getSeverity();
							throw new CoreException(new Status(severity != RefactoringStatus.FATAL ? severity : IStatus.ERROR, RefactoringUIPlugin.getPluginId(), 0, null, null));
						}
						super.run(new SubProgressMonitor(monitor, 80, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
					} finally {
						monitor.done();
					}
				}
			};
			try {
				wizard.run(false, false, new WorkbenchRunnableAdapter(operation, ResourcesPlugin.getWorkspace().getRoot()));
			} catch (InvocationTargetException exception) {
				RefactoringUIPlugin.log(exception);
				final Throwable throwable= exception.getTargetException();
				if (throwable != null) {
					final String message= throwable.getLocalizedMessage();
					if (message != null && !"".equals(message)) //$NON-NLS-1$
						status.merge(RefactoringStatus.createFatalErrorStatus(message));
					fErrorPage.setStatus(status);
					fErrorPage.setNextPageDisabled(status.hasFatalError());
					fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error_title);
					fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_apply_error);
					wizard.showPage(fErrorPage);
					return false;
				}
			} catch (InterruptedException exception) {
				// Does not happen
			}
			final RefactoringStatus result= operation.getExecutionStatus();
			if (!result.isOK()) {
				fErrorPage.setStatus(result);
				fErrorPage.setNextPageDisabled(true);
				fErrorPage.setTitle(RefactoringUIMessages.RefactoringHistoryPreviewPage_finish_error_title);
				fErrorPage.setDescription(RefactoringUIMessages.RefactoringHistoryPreviewPage_finish_error_description);
				wizard.showPage(fErrorPage);
				return false;
			}
		}
		return true;
	}

	/**
	 * Performs the change previously displayed in the preview.
	 * <p>
	 * Note: This API must not be called from outside the refactoring framework.
	 * </p>
	 * 
	 * @param change
	 *            the change displayed in the preview
	 * @param refactoring
	 *            the associated refactoring
	 * @return the status of the operation, already handled by the user
	 */
	public final RefactoringStatus performPreviewChange(final Change change, final Refactoring refactoring) {
		Assert.isNotNull(change);
		Assert.isNotNull(refactoring);
		final UIPerformChangeOperation operation= new UIPerformChangeOperation(getShell().getDisplay(), change, getContainer()) {

			public void run(final IProgressMonitor monitor) throws CoreException {
				try {
					monitor.beginTask(RefactoringUIMessages.RefactoringHistoryWizard_preparing_changes, 12);
					super.run(new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
					refactoringPerformed(refactoring, new SubProgressMonitor(monitor, 2, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
				} finally {
					monitor.done();
				}
			}
		};
		final RefactoringStatus status= performPreviewChange(operation, refactoring);
		if (status.isOK())
			status.merge(operation.getValidationStatus());
		return status;
	}

	/**
	 * Performs the change previously displayed in the preview using the
	 * specified change operation.
	 * 
	 * @param operation
	 *            the change operation
	 * @param refactoring
	 *            the associated refactoring
	 * @return the status of the operation, already handled by the user
	 */
	private RefactoringStatus performPreviewChange(final PerformChangeOperation operation, final Refactoring refactoring) {
		Assert.isNotNull(operation);
		Assert.isNotNull(refactoring);
		operation.setUndoManager(RefactoringCore.getUndoManager(), refactoring.getName());
		final IWizardContainer wizard= getContainer();
		final Shell shell= wizard.getShell();
		try {
			wizard.run(false, false, new WorkbenchRunnableAdapter(operation, ResourcesPlugin.getWorkspace().getRoot()));
		} catch (InvocationTargetException exception) {
			final Throwable throwable= exception.getTargetException();
			if (operation.changeExecutionFailed()) {
				final Change change= operation.getChange();
				final ChangeExceptionHandler handler= new ChangeExceptionHandler(shell, refactoring);
				if (throwable instanceof RuntimeException)
					handler.handle(change, (RuntimeException) throwable);
				else if (throwable instanceof CoreException)
					handler.handle(change, (CoreException) throwable);
			}
			ExceptionHandler.handle(exception, shell, RefactoringUIMessages.RefactoringWizard_refactoring, RefactoringUIMessages.RefactoringWizard_unexpected_exception_1);
		} catch (InterruptedException exception) {
			return RefactoringStatus.create(new Status(IStatus.INFO, RefactoringUIPlugin.getPluginId(), STATUS_CODE_INTERRUPTED, exception.getLocalizedMessage(), exception));
		} finally {
			fPreviewPage.setNextPageDisabled(isSecondLastRefactoring());
			getContainer().updateButtons();
		}
		return new RefactoringStatus();
	}

	/**
	 * Prepares the error page to be displayed.
	 * 
	 * @param status
	 *            the refactoring status
	 * @param descriptor
	 *            the refactoring descriptor
	 * @param fatal
	 *            <code>true</code> if the error is fatal, <code>false</code>
	 *            otherwise
	 * @param disabled
	 *            <code>true</code> if the next page is disabled,
	 *            <code>false</code> otherwise
	 */
	private void prepareErrorPage(final RefactoringStatus status, final RefactoringDescriptorProxy descriptor, final boolean fatal, final boolean disabled) {
		getShell().getDisplay().syncExec(new Runnable() {

			public final void run() {
				fErrorPage.setTitle(descriptor, fCurrentRefactoring, fDescriptorProxies.length);
				fErrorPage.setNextPageDisabled(disabled && fatal);
				fErrorPage.setPageComplete(!fatal);
				fErrorPage.setStatus(null);
				fErrorPage.setStatus(status);
				getContainer().updateButtons();
			}
		});
	}

	/**
	 * Prepares the preview page to be displayed.
	 * 
	 * @param status
	 *            the refactoring status
	 * @param descriptor
	 *            the refactoring descriptor
	 * @param disabled
	 *            <code>true</code> if the next page is disabled,
	 *            <code>false</code> otherwise
	 */
	private void preparePreviewPage(final RefactoringStatus status, final RefactoringDescriptorProxy descriptor, final boolean disabled) {
		getShell().getDisplay().syncExec(new Runnable() {

			public final void run() {
				fPreviewPage.setTitle(descriptor, fCurrentRefactoring, fDescriptorProxies.length);
				fPreviewPage.setNextPageDisabled(disabled);
				fPreviewPage.setPageComplete(!disabled);
				fPreviewPage.setStatus(status);
				getContainer().updateButtons();
			}
		});
	}

	/**
	 * Hook method which is called when the specified refactoring has been
	 * performed, e.g. its change object has been successfully applied to the
	 * workspace. The default implementation does nothing and returns a
	 * refactoring status of severity {@link RefactoringStatus#OK}. This method
	 * may be called from non-UI threads.
	 * <p>
	 * Subclasses may reimplement this method to perform any special processing.
	 * </p>
	 * <p>
	 * Returning a status of severity {@link RefactoringStatus#FATAL} will
	 * terminate the execution of the refactorings.
	 * </p>
	 * 
	 * @param refactoring
	 *            the refactoring which has been performed
	 * @param monitor
	 *            the progress monitor to use
	 * @return a status describing the outcome of the operation
	 */
	protected RefactoringStatus refactoringPerformed(final Refactoring refactoring, final IProgressMonitor monitor) {
		Assert.isNotNull(refactoring);
		Assert.isNotNull(monitor);
		fExecutedRefactorings++;
		return new RefactoringStatus();
	}

	/**
	 * Hook method which is called for each change before it is displayed in a
	 * preview page. The default implementation returns <code>true</code>.
	 * <p>
	 * Subclasses may reimplement this method to perform any special filtering
	 * of preview changes.
	 * </p>
	 * 
	 * @param change
	 *            the change to select
	 * @return <code>true</code> if the change passes the filter,
	 *         <code>false</code> otherwise
	 */
	protected boolean selectPreviewChange(final Change change) {
		return true;
	}

	/**
	 * Hook method which is called for each status entry before it is displayed
	 * in a wizard page. The default implementation returns <code>true</code>.
	 * <p>
	 * Subclasses may reimplement this method to perform any special filtering
	 * of status entries on error pages.
	 * </p>
	 * 
	 * @param entry
	 *            the status entry to select
	 * @return <code>true</code> if the status entry passes the filter,
	 *         <code>false</code> otherwise
	 */
	protected boolean selectStatusEntry(final RefactoringStatusEntry entry) {
		return true;
	}

	/**
	 * Sets the refactoring history control configuration.
	 * <p>
	 * This method must be called before opening the wizard in a dialog.
	 * </p>
	 * 
	 * @param configuration
	 *            the configuration to set
	 */
	public final void setConfiguration(final RefactoringHistoryControlConfiguration configuration) {
		Assert.isNotNull(configuration);
		fControlConfiguration= configuration;
	}

	/**
	 * Sets the refactoring history.
	 * <p>
	 * This method must be called before opening the wizard in a dialog.
	 * </p>
	 * 
	 * @param history
	 *            the refactoring history
	 */
	public final void setInput(final RefactoringHistory history) {
		Assert.isNotNull(history);
		fRefactoringHistory= history;
	}
}
