/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Leon J. Breedt - Added multiple folder creation support (in WizardNewFolderMainPage)
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 430694, 472784
 *     Patrik Suzzi <psuzzi@gmail.com> - Bug 371776
 *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 548799
 *******************************************************************************/
package org.eclipse.ui.dialogs;

import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.Iterator;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.AbstractOperation;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.CompositeImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ResourceLocator;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
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.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.dialogs.UIResourceFilterDescription;
import org.eclipse.ui.ide.undo.CreateFolderOperation;
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.internal.ide.dialogs.CreateLinkedResourceGroup;
import org.eclipse.ui.internal.ide.dialogs.ResourceFilterEditDialog;
import org.eclipse.ui.internal.ide.misc.OverlayIcon;
import org.eclipse.ui.internal.ide.misc.ResourceAndContainerGroup;

/**
 * Standard main page for a wizard that creates a folder resource.
 * <p>
 * This page may be used by clients as-is; it may be also be subclassed to suit.
 * </p>
 * <p>
 * Subclasses may extend
 * </p>
 * <ul>
 * <li><code>handleEvent</code></li>
 * </ul>
 */
public class WizardNewFolderMainPage extends WizardPage implements Listener {
	private static final int SIZING_CONTAINER_GROUP_HEIGHT = 250;

	private IStructuredSelection currentSelection;

	private IFolder newFolder;

	// link target location
	private URI linkTargetPath;

	// widgets
	private ResourceAndContainerGroup resourceGroup;

	private Button advancedButton;
	private Button useDefaultLocation;
	private Button useVirtualFolder;
	private Button useLinkedResource;

	private Button filterButton;

	private CreateLinkedResourceGroup linkedResourceGroup;

	private Composite advancedComposite;

	private Composite linkedResourceComposite;
	private Composite linkedGroupComposite;

	private UIResourceFilterDescription[] filterList = null;

	/**
	 * Height of the "advanced" linked resource group. Set when the advanced group
	 * is first made visible.
	 */
	private int linkedResourceGroupHeight = -1;

	/**
	 * First time the advanced group is validated.
	 */
	private boolean firstLinkCheck = true;

	/**
	 * Creates a new folder creation wizard page. If the initial resource selection
	 * contains exactly one container resource then it will be used as the default
	 * container resource.
	 *
	 * @param pageName  the name of the page
	 * @param selection the current resource selection
	 */
	public WizardNewFolderMainPage(String pageName, IStructuredSelection selection) {
		super("newFolderPage1");//$NON-NLS-1$
		setTitle(pageName);
		setDescription(IDEWorkbenchMessages.WizardNewFolderMainPage_description);
		this.currentSelection = selection;
	}

	/**
	 * Creates the widget for advanced options.
	 *
	 * @param parent the parent composite
	 */
	protected void createAdvancedControls(Composite parent) {
		Preferences preferences = ResourcesPlugin.getPlugin().getPluginPreferences();

		if (preferences.getBoolean(ResourcesPlugin.PREF_DISABLE_LINKING) == false) {
			advancedComposite = new Composite(parent, SWT.NONE);
			advancedComposite.setFont(parent.getFont());
			advancedComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			GridLayout layout = new GridLayout();
			layout.marginHeight = 0;
			layout.marginWidth = 0;
			advancedComposite.setLayout(layout);

			advancedButton = new Button(advancedComposite, SWT.PUSH);
			advancedButton.setFont(advancedComposite.getFont());
			advancedButton.setText(IDEWorkbenchMessages.showAdvanced);
			GridData data = setButtonLayoutData(advancedButton);
			data.horizontalAlignment = GridData.BEGINNING;
			advancedButton.setLayoutData(data);
			advancedButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					handleAdvancedButtonSelect();
				}
			});
		}
		linkedResourceGroup = new CreateLinkedResourceGroup(IResource.FOLDER, e -> {
			setPageComplete(validatePage());
			firstLinkCheck = false;
		}, new CreateLinkedResourceGroup.IStringValue() {
			@Override
			public String getValue() {
				return resourceGroup.getResource();
			}

			@Override
			public void setValue(String string) {
				resourceGroup.setResource(string);
			}

			@Override
			public IResource getResource() {
				IPath path = resourceGroup.getContainerFullPath();
				if (path != null) {
					IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
					IResource resource = root.findMember(path);
					if (resource != null && resource instanceof IContainer) {
						String resourceName = resourceGroup.getResource();
						if (resourceName.length() > 0) {
							try {
								return ((IContainer) resource).getFolder(Path.fromOSString(resourceName));
							} catch (IllegalArgumentException e) {
								// continue below.
							}
						}
						return resource;
					}
					return resource;
				}
				return null;
			}
		});
	}

	boolean setupLinkedResourceTargetRecursiveFlag = false;

	private void setupLinkedResourceTarget() {
		if (!setupLinkedResourceTargetRecursiveFlag) {
			setupLinkedResourceTargetRecursiveFlag = true;
			try {
				if (isFilteredByParent()) {
					URI existingLink = linkedResourceGroup.getLinkTargetURI();
					boolean setDefaultLinkValue = false;
					if (existingLink == null)
						setDefaultLinkValue = true;
					else {
						IPath path = URIUtil.toPath(existingLink);
						if (path != null)
							setDefaultLinkValue = path.toPortableString().length() > 0;
					}

					if (setDefaultLinkValue) {
						IPath containerPath = resourceGroup.getContainerFullPath();
						IPath newFilePath = containerPath.append(resourceGroup.getResource());
						IFolder newFolderHandle = createFolderHandle(newFilePath);
						try {
							URI uri = newFolderHandle.getPathVariableManager()
									.convertToRelative(newFolderHandle.getLocationURI(), false, null);
							linkedResourceGroup.setLinkTarget(URIUtil.toPath(uri).toPortableString());
						} catch (CoreException e) {
							// nothing
						}
					}
				}
			} finally {
				setupLinkedResourceTargetRecursiveFlag = false;
			}
		}
	}

	@Override
	public void createControl(Composite parent) {
		initializeDialogUnits(parent);
		// top level group
		Composite composite = new Composite(parent, SWT.NONE);
		composite.setFont(parent.getFont());
		composite.setLayout(new GridLayout());
		composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));

		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IIDEHelpContextIds.NEW_FOLDER_WIZARD_PAGE);

		resourceGroup = new ResourceAndContainerGroup(composite, this,
				IDEWorkbenchMessages.WizardNewFolderMainPage_folderName,
				IDEWorkbenchMessages.WizardNewFolderMainPage_folderLabel, false, SIZING_CONTAINER_GROUP_HEIGHT);
		resourceGroup.setAllowExistingResources(false);
		createAdvancedControls(composite);
		initializePage();
		validatePage();
		// Show description on opening
		setErrorMessage(null);
		setMessage(null);
		setControl(composite);
	}

	/**
	 * Creates a folder resource given the folder handle.
	 *
	 * @param folderHandle the folder handle to create a folder resource for
	 * @param monitor      the progress monitor to show visual progress with
	 * @exception CoreException              if the operation fails
	 * @exception OperationCanceledException if the operation is canceled
	 *
	 * @deprecated As of 3.3, use {@link #createNewFolder()} which uses the undoable
	 *             operation support.
	 */
	@Deprecated
	protected void createFolder(IFolder folderHandle, IProgressMonitor monitor) throws CoreException {
		SubMonitor subMonitor = SubMonitor.convert(monitor, 100);

		try {
			// Create the folder resource in the workspace
			// Update: Recursive to create any folders which do not exist
			// already
			if (!folderHandle.exists()) {
				if (linkTargetPath != null) {
					folderHandle.createLink(linkTargetPath, IResource.ALLOW_MISSING_LOCAL, subMonitor.split(100));
				} else {
					IPath path = folderHandle.getFullPath();
					IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
					int numSegments = path.segmentCount();
					if (numSegments > 2 && !root.getFolder(path.removeLastSegments(1)).exists()) {

						SubMonitor loopProgress = subMonitor.split(90).setWorkRemaining(numSegments - 3);
						// If the direct parent of the path doesn't exist, try
						// to create the
						// necessary directories.
						for (int i = numSegments - 2; i > 0; i--) {
							IFolder folder = root.getFolder(path.removeLastSegments(i));
							if (!folder.exists()) {
								folder.create(false, true, loopProgress.split(1));
							}
						}
					}
					subMonitor.setWorkRemaining(10);
					folderHandle.create(false, true, subMonitor.split(10));
				}
			}
		} catch (CoreException e) {
			// If the folder already existed locally, just refresh to get
			// contents
			if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) {
				folderHandle.refreshLocal(IResource.DEPTH_INFINITE, subMonitor.setWorkRemaining(1).split(1));
			} else {
				throw e;
			}
		}
	}

	/**
	 * Creates a folder resource handle for the folder with the given workspace
	 * path. This method does not create the folder resource; this is the
	 * responsibility of <code>createFolder</code>.
	 *
	 * @param folderPath the path of the folder resource to create a handle for
	 * @return the new folder resource handle
	 * @see #createFolder
	 */
	protected IFolder createFolderHandle(IPath folderPath) {
		return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getFolder(folderPath);
	}

	/**
	 * Creates a container resource handle for the container with the given
	 * workspace path. This method does not create the resource.
	 *
	 * @param containerPath the path of the container resource to create a handle
	 *                      for
	 * @return the new container resource handle
	 * @see #createFolder
	 * @since 3.6
	 */
	protected IContainer createContainerHandle(IPath containerPath) {
		if (containerPath.segmentCount() == 1)
			return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getProject(containerPath.segment(0));
		return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getFolder(containerPath);
	}

	/**
	 * Creates the link target path if a link target has been specified.
	 */
	protected void createLinkTarget() {
		linkTargetPath = linkedResourceGroup.getLinkTargetURI();
	}

	/**
	 * Creates a new folder resource in the selected container and with the selected
	 * name. Creates any missing resource containers along the path; does nothing if
	 * the container resources already exist.
	 * <p>
	 * In normal usage, this method is invoked after the user has pressed Finish on
	 * the wizard; the enablement of the Finish button implies that all controls on
	 * this page currently contain valid values.
	 * </p>
	 * <p>
	 * Note that this page caches the new folder once it has been successfully
	 * created; subsequent invocations of this method will answer the same folder
	 * resource without attempting to create it again.
	 * </p>
	 * <p>
	 * This method should be called within a workspace modify operation since it
	 * creates resources.
	 * </p>
	 *
	 * @return the created folder resource, or <code>null</code> if the folder was
	 *         not created
	 */
	public IFolder createNewFolder() {
		if (newFolder != null) {
			return newFolder;
		}

		// create the new folder and cache it if successful
		final IPath containerPath = resourceGroup.getContainerFullPath();
		IPath newFolderPath = containerPath.append(resourceGroup.getResource());
		final IFolder newFolderHandle = createFolderHandle(newFolderPath);

		final boolean createVirtualFolder = useVirtualFolder != null && useVirtualFolder.getSelection();
		createLinkTarget();
		if (linkTargetPath != null) {
			URI resolvedPath = newFolderHandle.getPathVariableManager().resolveURI(linkTargetPath);
			try {
				IFileStore store = EFS.getStore(resolvedPath);
				if (!store.fetchInfo().exists()) {
					MessageDialog dlg = new MessageDialog(getContainer().getShell(),
							IDEWorkbenchMessages.WizardNewFolderCreationPage_createLinkLocationTitle, null,
							NLS.bind(IDEWorkbenchMessages.WizardNewFolderCreationPage_createLinkLocationQuestion,
									linkTargetPath),
							MessageDialog.QUESTION_WITH_CANCEL, 0, IDialogConstants.YES_LABEL,
							IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL);
					int result = dlg.open();
					if (result == Window.OK) {
						store.mkdir(0, new NullProgressMonitor());
					}
					if (result == 2)
						return null;
				}
			} catch (CoreException e) {
				MessageDialog.open(MessageDialog.ERROR, getContainer().getShell(),
						IDEWorkbenchMessages.WizardNewFileCreationPage_internalErrorTitle,
						NLS.bind(IDEWorkbenchMessages.WizardNewFileCreationPage_internalErrorMessage, e.getMessage()),
						SWT.SHEET);

				return null;
			}
		}
		IRunnableWithProgress op = monitor -> {
			AbstractOperation op1;
			op1 = new CreateFolderOperation(newFolderHandle, linkTargetPath, createVirtualFolder, filterList,
					IDEWorkbenchMessages.WizardNewFolderCreationPage_title);
			try {
				// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=219901
				// directly execute the operation so that the undo state is
				// not preserved. Making this undoable can result in accidental
				// folder (and file) deletions.
				op1.execute(monitor, WorkspaceUndoUtil.getUIInfoAdapter(getShell()));
			} catch (final ExecutionException e) {
				getContainer().getShell().getDisplay().syncExec(() -> {
					if (e.getCause() instanceof CoreException) {
						ErrorDialog.openError(getContainer().getShell(), // Was Utilities.getFocusShell()
								IDEWorkbenchMessages.WizardNewFolderCreationPage_errorTitle, null, // no special message
								((CoreException) e.getCause()).getStatus());
					} else {
						IDEWorkbenchPlugin.log(getClass(), "createNewFolder()", e.getCause()); //$NON-NLS-1$
						MessageDialog.openError(getContainer().getShell(),
								IDEWorkbenchMessages.WizardNewFolderCreationPage_internalErrorTitle, NLS.bind(
										IDEWorkbenchMessages.WizardNewFolder_internalError, e.getCause().getMessage()));
					}
				});
			}
		};

		try {
			getContainer().run(true, true, op);
		} catch (InterruptedException e) {
			return null;
		} catch (InvocationTargetException e) {
			// ExecutionExceptions are handled above, but unexpected runtime
			// exceptions and errors may still occur.
			IDEWorkbenchPlugin.log(getClass(), "createNewFolder()", e.getTargetException()); //$NON-NLS-1$
			MessageDialog.open(MessageDialog.ERROR, getContainer().getShell(),
					IDEWorkbenchMessages.WizardNewFolderCreationPage_internalErrorTitle,
					NLS.bind(IDEWorkbenchMessages.WizardNewFolder_internalError, e.getTargetException().getMessage()),
					SWT.SHEET);
			return null;
		}

		newFolder = newFolderHandle;

		return newFolder;
	}

	/**
	 * Shows/hides the advanced option widgets.
	 */
	protected void handleAdvancedButtonSelect() {
		Shell shell = getShell();
		Point shellSize = shell.getSize();
		Composite composite = (Composite) getControl();

		if (linkedResourceComposite != null) {
			linkedResourceComposite.dispose();
			linkedResourceComposite = null;
			filterButton.dispose();
			useDefaultLocation.dispose();
			useVirtualFolder.dispose();
			useLinkedResource.dispose();
			linkedGroupComposite.dispose();
			filterButton = null;
			useDefaultLocation = null;
			useVirtualFolder = null;
			useLinkedResource = null;
			linkedGroupComposite = null;
			composite.layout();
			shell.setSize(shellSize.x, shellSize.y - linkedResourceGroupHeight);
			advancedButton.setText(IDEWorkbenchMessages.showAdvanced);
		} else {
			Point oldCompositeSize = advancedComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);

			ImageDescriptor folderDescriptor = PlatformUI.getWorkbench().getSharedImages()
					.getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER);

			ImageDescriptor[][] linkedResourceOverlayMap = new ImageDescriptor[4][1];
			linkedResourceOverlayMap[1] = new ImageDescriptor[] { ResourceLocator
					.imageDescriptorFromBundle(IDEWorkbenchPlugin.IDE_WORKBENCH, "$nl$/icons/full/ovr16/link_ovr.png") //$NON-NLS-1$
					.orElse(null) };

			CompositeImageDescriptor linkedFolderDescriptor = new OverlayIcon(folderDescriptor,
					linkedResourceOverlayMap, new Point(16, 16));

			ImageDescriptor[][] virtualFolderOverlayMap = new ImageDescriptor[4][1];
			virtualFolderOverlayMap[1] = new ImageDescriptor[] { ResourceLocator
					.imageDescriptorFromBundle(IDEWorkbenchPlugin.IDE_WORKBENCH, "$nl$/icons/full/ovr16/virt_ovr.png") //$NON-NLS-1$
					.orElse(null) };

			CompositeImageDescriptor virtualFolderDescriptor = new OverlayIcon(folderDescriptor,
					virtualFolderOverlayMap, new Point(16, 16));

			Image folderImage = folderDescriptor.createImage();
			useDefaultLocation = new Button(advancedComposite, SWT.RADIO);

			int indent = useDefaultLocation.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;

			useDefaultLocation.setFont(advancedComposite.getFont());
			useDefaultLocation.setText(IDEWorkbenchMessages.useDefaultLocation);
			useDefaultLocation.setImage(folderImage);
			GridData data = setButtonLayoutData(useDefaultLocation);
			data.horizontalAlignment = GridData.BEGINNING;
			data.horizontalIndent = indent;
			useDefaultLocation.setLayoutData(data);

			Image virtualFolderImage = virtualFolderDescriptor.createImage();

			useVirtualFolder = new Button(advancedComposite, SWT.RADIO);
			useVirtualFolder.setFont(advancedComposite.getFont());
			useVirtualFolder.setImage(virtualFolderImage);
			useVirtualFolder.setText(IDEWorkbenchMessages.createVirtualFolder);
			data = setButtonLayoutData(useVirtualFolder);
			data.horizontalAlignment = GridData.BEGINNING;
			data.horizontalIndent = indent;
			useVirtualFolder.setLayoutData(data);

			Image linkedFolderImage = linkedFolderDescriptor.createImage();

			useLinkedResource = new Button(advancedComposite, SWT.RADIO);
			useLinkedResource.setFont(advancedComposite.getFont());
			useLinkedResource.setText(IDEWorkbenchMessages.createLinkedFolder);
			useLinkedResource.setImage(linkedFolderImage);
			data = setButtonLayoutData(useLinkedResource);
			data.horizontalAlignment = GridData.BEGINNING;
			data.horizontalIndent = indent;
			useLinkedResource.setLayoutData(data);

			SelectionAdapter radioListener = new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					handleRadioSelect();
				}
			};

			useLinkedResource.addSelectionListener(radioListener);
			useVirtualFolder.addSelectionListener(radioListener);
			useDefaultLocation.addSelectionListener(radioListener);

			useDefaultLocation.setSelection(true);

			linkedGroupComposite = new Composite(advancedComposite, 0);
			data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
			data.horizontalIndent = indent;
			linkedGroupComposite.setFont(advancedComposite.getFont());
			linkedGroupComposite.setLayoutData(data);

			GridLayout layout = new GridLayout();
			layout.marginHeight = 0;
			layout.marginWidth = 0;
			linkedGroupComposite.setLayout(layout);

			linkedResourceComposite = linkedResourceGroup.createTextOnlyContents(linkedGroupComposite);
			if (linkedResourceGroupHeight == -1) {
				Point groupSize = linkedResourceComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
				linkedResourceGroupHeight = groupSize.y;
			}
			linkedResourceGroup.setEnabled(false);

			filterButton = new Button(advancedComposite, SWT.PUSH);
			filterButton.setFont(advancedComposite.getFont());
			filterButton.setText(IDEWorkbenchMessages.editfilters);
			data = setButtonLayoutData(filterButton);
			data.horizontalAlignment = GridData.BEGINNING;
			data.horizontalIndent = indent;
			filterButton.setLayoutData(data);
			filterButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					handleEditFilterSelect();
				}
			});

			setupLinkedResourceTarget();
			advancedButton.setText(IDEWorkbenchMessages.hideAdvanced);

			Point newCompositeSize = advancedComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			linkedResourceGroupHeight = newCompositeSize.y - oldCompositeSize.y;
			getShell().setSize(shellSize.x, shellSize.y + linkedResourceGroupHeight);
			composite.layout(true);
		}
	}

	private void handleRadioSelect() {
		linkedResourceGroup.setEnabled(useLinkedResource.getSelection());
	}

	/**
	 * Show the Resource Filter dialog.
	 */
	private void handleEditFilterSelect() {
		ResourceFilterEditDialog dialog = new ResourceFilterEditDialog(getShell());
		dialog.setFilters(filterList);
		if (dialog.open() == Window.OK)
			filterList = dialog.getFilters();
	}

	/**
	 * The <code>WizardNewFolderCreationPage</code> implementation of this
	 * <code>Listener</code> method handles all events and enablements for controls
	 * on this page. Subclasses may extend.
	 */
	@Override
	public void handleEvent(Event ev) {
		setPageComplete(validatePage());
	}

	/**
	 * Initializes this page's controls.
	 */
	protected void initializePage() {
		Iterator<?> it = currentSelection.iterator();
		if (it.hasNext()) {
			Object next = it.next();
			IResource selectedResource = Adapters.adapt(next, IResource.class);
			if (selectedResource != null) {
				if (selectedResource.getType() == IResource.FILE) {
					selectedResource = selectedResource.getParent();
				}
				if (selectedResource.isAccessible()) {
					resourceGroup.setContainerFullPath(selectedResource.getFullPath());
				}
			}
		}

		setPageComplete(false);
	}

	/*
	 * @see DialogPage.setVisible(boolean)
	 */
	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible) {
			resourceGroup.setFocus();
		}
	}

	/**
	 * Checks whether the linked resource target is valid. Sets the error message
	 * accordingly and returns the status.
	 *
	 * @return IStatus validation result from the CreateLinkedResourceGroup
	 */
	protected IStatus validateLinkedResource() {
		IPath containerPath = resourceGroup.getContainerFullPath();
		IPath newFolderPath = containerPath.append(resourceGroup.getResource());
		IFolder newFolderHandle = createFolderHandle(newFolderPath);
		IStatus status = linkedResourceGroup.validateLinkLocation(newFolderHandle);

		if (status.getSeverity() == IStatus.ERROR) {
			if (firstLinkCheck) {
				setMessage(status.getMessage());
			} else {
				setErrorMessage(status.getMessage());
			}
		} else if (status.getSeverity() == IStatus.WARNING) {
			setMessage(status.getMessage(), WARNING);
			setErrorMessage(null);
		}
		return status;
	}

	/**
	 * Returns whether this page's controls currently all contain valid values.
	 *
	 * @return <code>true</code> if all controls are valid, and <code>false</code>
	 *         if at least one is invalid
	 */
	protected boolean validatePage() {
		boolean valid = true;

		if (!resourceGroup.areAllValuesValid()) {
			setErrorMessage(resourceGroup.getProblemMessage());
			valid = false;
		}

		if (valid && (useDefaultLocation == null || useDefaultLocation.getSelection())) {
			IPath containerPath = resourceGroup.getContainerFullPath();
			if (containerPath != null && createContainerHandle(containerPath).isVirtual()) {
				valid = false;
				setErrorMessage(IDEWorkbenchMessages.CreateLinkedResourceGroup_linkRequiredUnderAGroup);
			}
		}

		IStatus linkedResourceStatus = null;
		if (valid) {
			linkedResourceStatus = validateLinkedResource();
			if (linkedResourceStatus.getSeverity() == IStatus.ERROR) {
				valid = false;
			}
		}
		// validateLinkedResource sets messages itself
		if (valid && (linkedResourceStatus == null || linkedResourceStatus.isOK())) {
			setMessage(null);
			setErrorMessage(null);
		}

		if (isFilteredByParent()) {
			setMessage(IDEWorkbenchMessages.WizardNewFolderCreationPage_resourceWillBeFilteredWarning,
					IMessageProvider.ERROR);
			setupLinkedResourceTarget();
			valid = false;
		}

		return valid;
	}

	private boolean isFilteredByParent() {
		boolean createVirtualFolder = useVirtualFolder != null && useVirtualFolder.getSelection();
		if (createVirtualFolder)
			return false;
		if ((linkedResourceGroup == null) || linkedResourceGroup.isEnabled())
			return false;
		IPath containerPath = resourceGroup.getContainerFullPath();
		if (containerPath == null)
			return false;
		String resourceName = resourceGroup.getResource();
		if (resourceName == null)
			return false;
		if (resourceName.length() > 0) {
			IPath newFolderPath = containerPath.append(resourceName);
			if (newFolderPath.segmentCount() < 2)
				return false;
			IFolder newFolderHandle = createFolderHandle(newFolderPath);
			IWorkspace workspace = newFolderHandle.getWorkspace();
			return !workspace.validateFiltered(newFolderHandle).isOK();
		}
		return false;
	}
}
