/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.wizards.buildpaths;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import org.eclipse.equinox.bidi.StructuredTextTypeHandlerFactory;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IPathVariableManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.util.BidiUtils;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;

import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.ui.ide.dialogs.PathVariableSelectionDialog;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceComparator;

import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModelStatus;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaConventions;

import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.wizards.NewElementWizardPage;

import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField;


public class AddSourceFolderWizardPage extends NewElementWizardPage {

	private final class LinkFields implements IStringButtonAdapter, IDialogFieldListener{
		private StringButtonDialogField fLinkLocation;

		private final String DIALOGSTORE_LAST_EXTERNAL_LOC= JavaUI.ID_PLUGIN + ".last.external.project"; //$NON-NLS-1$

		private RootFieldAdapter fAdapter;

		private SelectionButtonDialogField fVariables;

		public LinkFields() {
			fLinkLocation= new StringButtonDialogField(this);

			fLinkLocation.setLabelText(NewWizardMessages.LinkFolderDialog_dependenciesGroup_locationLabel_desc);
			fLinkLocation.setButtonLabel(NewWizardMessages.LinkFolderDialog_dependenciesGroup_browseButton_desc);
			fLinkLocation.setDialogFieldListener(this);

			fVariables= new SelectionButtonDialogField(SWT.PUSH);
			fVariables.setLabelText(NewWizardMessages.LinkFolderDialog_dependenciesGroup_variables_desc);
			fVariables.setDialogFieldListener(field -> handleVariablesButtonPressed());
		}

		public void setDialogFieldListener(RootFieldAdapter adapter) {
			fAdapter= adapter;
		}

		private void doFillIntoGrid(Composite parent, int numColumns) {
			fLinkLocation.doFillIntoGrid(parent, numColumns);

			LayoutUtil.setHorizontalSpan(fLinkLocation.getLabelControl(null), numColumns);
			LayoutUtil.setHorizontalGrabbing(fLinkLocation.getTextControl(null));
			BidiUtils.applyBidiProcessing(fLinkLocation.getTextControl(null), StructuredTextTypeHandlerFactory.FILE);

			fVariables.doFillIntoGrid(parent, 1);
		}

		public IPath getLinkTarget() {
			return Path.fromOSString(fLinkLocation.getText());
		}

		public void setLinkTarget(IPath path) {
			fLinkLocation.setText(path.toOSString());
		}

		@Override
		public void changeControlPressed(DialogField field) {
			final DirectoryDialog dialog= new DirectoryDialog(getShell(), SWT.SHEET);
			dialog.setText(NewWizardMessages.AddSourceFolderWizardPage_dialog_title);
			dialog.setMessage(NewWizardMessages.AddSourceFolderWizardPage_directory_message);
			String directoryName = fLinkLocation.getText().trim();
			if (directoryName.length() == 0) {
				String prevLocation= JavaPlugin.getDefault().getDialogSettings().get(DIALOGSTORE_LAST_EXTERNAL_LOC);
				if (prevLocation != null) {
					directoryName= prevLocation;
				}
			}

			if (directoryName.length() > 0) {
				final File path = new File(directoryName);
				if (path.exists())
					dialog.setFilterPath(directoryName);
			}
			final String selectedDirectory = dialog.open();
			if (selectedDirectory != null) {
				fLinkLocation.setText(selectedDirectory);
				fRootDialogField.setText(selectedDirectory.substring(selectedDirectory.lastIndexOf(File.separatorChar) + 1));
				JavaPlugin.getDefault().getDialogSettings().put(DIALOGSTORE_LAST_EXTERNAL_LOC, selectedDirectory);
				if (fAdapter != null) {
					fAdapter.dialogFieldChanged(fRootDialogField);
				}
			}
		}

		/**
		 * Opens a path variable selection dialog
		 */
		private void handleVariablesButtonPressed() {
			int variableTypes = IResource.FOLDER;
			PathVariableSelectionDialog dialog = new PathVariableSelectionDialog(getShell(), variableTypes);
			dialog.setResource(fParent);
			if (dialog.open() == IDialogConstants.OK_ID) {
				String[] variableNames = (String[]) dialog.getResult();
				if (variableNames != null && variableNames.length == 1) {
					fLinkLocation.setText(variableNames[0]);
					fRootDialogField.setText(new Path(variableNames[0]).lastSegment());
					if (fAdapter != null) {
						fAdapter.dialogFieldChanged(fRootDialogField);
					}
				}
			}
		}

		@Override
		public void dialogFieldChanged(DialogField field) {
			if (fAdapter != null) {
				fAdapter.dialogFieldChanged(fLinkLocation);
			}
		}
	}

	private static final String PAGE_NAME= "NewSourceFolderWizardPage"; //$NON-NLS-1$

	private final StringDialogField fRootDialogField;
	private final SelectionButtonDialogField fAddExclusionPatterns, fRemoveProjectFolder, fIgnoreConflicts;
	private final LinkFields fLinkFields;

	private final CPListElement fNewElement;
	private final List<CPListElement> fExistingEntries;
	private final Hashtable<CPListElement, IPath[]> fOrginalExlusionFilters, fOrginalInclusionFilters, fOrginalExlusionFiltersCopy, fOrginalInclusionFiltersCopy;
	private final IPath fOrginalPath;
	private final boolean fLinkedMode;

	private IPath fOutputLocation;
	private IPath fNewOutputLocation;
	private CPListElement fOldProjectSourceFolder;

	private List<CPListElement> fModifiedElements;
	private List<CPListElement> fRemovedElements;

	private final boolean fAllowConflict;
	private final boolean fAllowRemoveProjectFolder;
	private final boolean fAllowAddExclusionPatterns;
	private final boolean fCanCommitConflictingBuildpath;
	private final IContainer fParent;

	public AddSourceFolderWizardPage(CPListElement newElement, List<CPListElement> existingEntries, IPath outputLocation,
			boolean linkedMode, boolean canCommitConflictingBuildpath,
			boolean allowIgnoreConflicts, boolean allowRemoveProjectFolder, boolean allowAddExclusionPatterns, IContainer parent) {

		super(PAGE_NAME);

		fLinkedMode= linkedMode;
		fCanCommitConflictingBuildpath= canCommitConflictingBuildpath;
		fAllowConflict= allowIgnoreConflicts;
		fAllowRemoveProjectFolder= allowRemoveProjectFolder;
		fAllowAddExclusionPatterns= allowAddExclusionPatterns;
		fParent= parent;

		fOrginalExlusionFilters= new Hashtable<>();
		fOrginalInclusionFilters= new Hashtable<>();
		fOrginalExlusionFiltersCopy= new Hashtable<>();
		fOrginalInclusionFiltersCopy= new Hashtable<>();
		for (CPListElement existingEntry : existingEntries) {
			IPath[] exlusions= (IPath[])existingEntry.getAttribute(CPListElement.EXCLUSION);
			if (exlusions != null) {
				IPath[] save= new IPath[exlusions.length];
				System.arraycopy(exlusions, 0, save, 0, save.length);
				fOrginalExlusionFiltersCopy.put(existingEntry, save);
				fOrginalExlusionFilters.put(existingEntry, exlusions);
			}
			IPath[] inclusions= (IPath[])existingEntry.getAttribute(CPListElement.INCLUSION);
			if (inclusions != null) {
				IPath[] save= new IPath[inclusions.length];
				System.arraycopy(inclusions, 0, save, 0, save.length);
				fOrginalInclusionFiltersCopy.put(existingEntry, save);
				fOrginalInclusionFilters.put(existingEntry, inclusions);
			}
		}

		setTitle(NewWizardMessages.NewSourceFolderWizardPage_title);
		fOrginalPath= newElement.getPath();
		if (fOrginalPath == null) {
			if (linkedMode) {
				setDescription(Messages.format(NewWizardMessages.NewFolderDialog_createIn, BasicElementLabels.getJavaElementName(newElement.getJavaProject().getElementName())));
			} else {
				setDescription(Messages.format(NewWizardMessages.AddSourceFolderWizardPage_description, BasicElementLabels.getPathLabel(fParent.getFullPath(), false)));
			}
		} else {
			setDescription(NewWizardMessages.NewSourceFolderWizardPage_edit_description);
		}

		fNewElement= newElement;
		fExistingEntries= existingEntries;
		fModifiedElements= new ArrayList<>();
		fRemovedElements= new ArrayList<>();
		fOutputLocation= outputLocation;

		RootFieldAdapter adapter= new RootFieldAdapter();

		fRootDialogField= new StringDialogField();
		fRootDialogField.setLabelText(NewWizardMessages.NewSourceFolderWizardPage_root_label);
		if (fNewElement.getPath() == null) {
			fRootDialogField.setText(""); //$NON-NLS-1$
		} else {
			setFolderDialogText(fNewElement.getPath());
		}
		fRootDialogField.setEnabled(fNewElement.getJavaProject() != null);

		int buttonStyle= SWT.CHECK;
		if ((fAllowConflict && fAllowAddExclusionPatterns) ||
			(fAllowConflict && fAllowRemoveProjectFolder) ||
			(fAllowAddExclusionPatterns && fAllowRemoveProjectFolder)) {
			buttonStyle= SWT.RADIO;
		}

		fAddExclusionPatterns= new SelectionButtonDialogField(buttonStyle);
		fAddExclusionPatterns.setLabelText(NewWizardMessages.NewSourceFolderWizardPage_exclude_label);
		fAddExclusionPatterns.setSelection(!fCanCommitConflictingBuildpath && !fAllowRemoveProjectFolder);

		fRemoveProjectFolder= new SelectionButtonDialogField(buttonStyle);
		fRemoveProjectFolder.setLabelText(NewWizardMessages.NewSourceFolderWizardPage_ReplaceExistingSourceFolder_label);
		fRemoveProjectFolder.setSelection(!fCanCommitConflictingBuildpath && fAllowRemoveProjectFolder);

		fIgnoreConflicts= new SelectionButtonDialogField(buttonStyle);
		fIgnoreConflicts.setLabelText(NewWizardMessages.AddSourceFolderWizardPage_ignoreNestingConflicts);
		fIgnoreConflicts.setSelection(fCanCommitConflictingBuildpath);

		fLinkFields= new LinkFields();
		if (fNewElement.getLinkTarget() != null) {
			fLinkFields.setLinkTarget(fNewElement.getLinkTarget());
		}

		fRemoveProjectFolder.setDialogFieldListener(adapter);
		fAddExclusionPatterns.setDialogFieldListener(adapter);
		fIgnoreConflicts.setDialogFieldListener(adapter);
		fRootDialogField.setDialogFieldListener(adapter);
		fLinkFields.setDialogFieldListener(adapter);

		packRootDialogFieldChanged();
	}

	// -------- UI Creation ---------

	/*
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	public void createControl(Composite parent) {
		initializeDialogUnits(parent);

		Composite composite= new Composite(parent, SWT.NONE);

		GridLayout layout= new GridLayout();
		layout.numColumns= 4;
		composite.setLayout(layout);

		if (fLinkedMode) {
			fLinkFields.doFillIntoGrid(composite, layout.numColumns);
			fRootDialogField.doFillIntoGrid(composite, layout.numColumns - 1);
		} else {
			fRootDialogField.doFillIntoGrid(composite, layout.numColumns - 1);
		}

		if (fAllowRemoveProjectFolder)
			fRemoveProjectFolder.doFillIntoGrid(composite, layout.numColumns);

		if (fAllowAddExclusionPatterns)
			fAddExclusionPatterns.doFillIntoGrid(composite, layout.numColumns);

		if (fAllowConflict)
			fIgnoreConflicts.doFillIntoGrid(composite, layout.numColumns);

		LayoutUtil.setHorizontalSpan(fRootDialogField.getLabelControl(null), layout.numColumns);
		LayoutUtil.setHorizontalGrabbing(fRootDialogField.getTextControl(null));

		setControl(composite);
		Dialog.applyDialogFont(composite);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.NEW_PACKAGEROOT_WIZARD_PAGE);
	}

	/*
	 * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean)
	 */
	@Override
	public void setVisible(boolean visible) {
		super.setVisible(visible);
		if (visible) {
			fRootDialogField.setFocus();
		}
	}

	// -------- ContainerFieldAdapter --------

	private class RootFieldAdapter implements IStringButtonAdapter, IDialogFieldListener {

		// -------- IStringButtonAdapter
		@Override
		public void changeControlPressed(DialogField field) {
			packRootChangeControlPressed(field);
		}

		// -------- IDialogFieldListener
		@Override
		public void dialogFieldChanged(DialogField field) {
			packRootDialogFieldChanged();
		}
	}

	protected void packRootChangeControlPressed(DialogField field) {
		if (field == fRootDialogField) {
			IPath initialPath= new Path(fRootDialogField.getText());
			String title= NewWizardMessages.NewSourceFolderWizardPage_ChooseExistingRootDialog_title;
			String message= NewWizardMessages.NewSourceFolderWizardPage_ChooseExistingRootDialog_description;
			IFolder folder= chooseFolder(title, message, initialPath);
			if (folder != null) {
				setFolderDialogText(folder.getFullPath());
			}
		}
	}

	private void setFolderDialogText(IPath path) {
		IPath shortPath= path.removeFirstSegments(1);
		fRootDialogField.setText(shortPath.toString());
	}

	protected void packRootDialogFieldChanged() {
		StatusInfo status= updateRootStatus();
		updateStatus(new IStatus[] {status});
	}

	private StatusInfo updateRootStatus() {
		IJavaProject javaProject= fNewElement.getJavaProject();
		IProject project= javaProject.getProject();

		StatusInfo pathNameStatus= validatePathName(fRootDialogField.getText(), fParent);

		if (!pathNameStatus.isOK())
			return pathNameStatus;

		if (fLinkedMode) {
			IStatus linkNameStatus= validateLinkLocation(fRootDialogField.getText());
			if (linkNameStatus.matches(IStatus.ERROR)) {
				StatusInfo result= new StatusInfo();
				result.setError(linkNameStatus.getMessage());
				return result;
			}
		}

		StatusInfo result= new StatusInfo();
		result.setOK();

		IPath projPath= project.getFullPath();
		IPath path= fParent.getFullPath().append(fRootDialogField.getText());

		restoreCPElements();

		int projectEntryIndex= -1;
		boolean createFolderForExisting= false;

		IFolder folder= fParent.getFolder(new Path(fRootDialogField.getText()));
		for (int i= 0; i < fExistingEntries.size(); i++) {
			IClasspathEntry curr= fExistingEntries.get(i).getClasspathEntry();
			if (curr.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
				if (path.equals(curr.getPath()) && fExistingEntries.get(i) != fNewElement) {
					if (folder.exists()) {
						result.setError(NewWizardMessages.NewSourceFolderWizardPage_error_AlreadyExisting);
						return result;
					} else {
						createFolderForExisting= true;
					}
				}
				if (projPath.equals(curr.getPath())) {
					projectEntryIndex= i;
				}
			}
		}

		if (folder.exists() && !folder.getFullPath().equals(fOrginalPath))
			return new StatusInfo(IStatus.ERROR, Messages.format(NewWizardMessages.NewFolderDialog_folderNameEmpty_alreadyExists, BasicElementLabels.getPathLabel(folder.getFullPath(), false)));

		boolean isProjectASourceFolder= projectEntryIndex != -1;

		fModifiedElements.clear();
		updateFilters(fNewElement.getPath(), path);

		fNewElement.setPath(path);
		if (fLinkedMode) {
			fNewElement.setLinkTarget(fLinkFields.getLinkTarget());
		}
		fRemovedElements.clear();
		Set<CPListElement> modified= new HashSet<>();
		boolean isProjectSourceFolderReplaced= false;
		if (fAddExclusionPatterns.isSelected()) {
			if (fOrginalPath == null) {
				addExclusionPatterns(fNewElement, fExistingEntries, modified);
				fModifiedElements.addAll(modified);
				if (!createFolderForExisting)
					CPListElement.insert(fNewElement, fExistingEntries);
			}
		} else {
			if (isProjectASourceFolder) {
				if (fRemoveProjectFolder.isSelected()) {
					fOldProjectSourceFolder= fExistingEntries.get(projectEntryIndex);
					fRemovedElements.add(fOldProjectSourceFolder);
					fExistingEntries.set(projectEntryIndex, fNewElement);
					isProjectSourceFolderReplaced= true;
				} else {
					if (!createFolderForExisting)
					CPListElement.insert(fNewElement, fExistingEntries);
				}
			} else {
				if (!createFolderForExisting)
					CPListElement.insert(fNewElement, fExistingEntries);
			}
		}

		if ((!fAllowConflict && fCanCommitConflictingBuildpath) || createFolderForExisting)
			return new StatusInfo();

		fNewOutputLocation= null;
		IJavaModelStatus status= JavaConventions.validateClasspath(javaProject, CPListElement.convertToClasspathEntries(fExistingEntries), fOutputLocation);
		if (!status.isOK()) {
			if (fOutputLocation.equals(projPath)) {
				//Try to change the output folder
				fNewOutputLocation= projPath.append(PreferenceConstants.getPreferenceStore().getString(PreferenceConstants.SRCBIN_BINNAME));
				IStatus status2= JavaConventions.validateClasspath(javaProject, CPListElement.convertToClasspathEntries(fExistingEntries), fNewOutputLocation);
				if (status2.isOK()) {
					if (isProjectSourceFolderReplaced) {
						result.setInfo(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_warning_ReplaceSFandOL, BasicElementLabels.getPathLabel(fNewOutputLocation, false)));
					} else {
						result.setInfo(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_warning_ReplaceOL, BasicElementLabels.getPathLabel(fNewOutputLocation, false)));
					}
					return result;
				}
			}
			//Don't know what the problem is, report to user
			fNewOutputLocation= null;
			if (fCanCommitConflictingBuildpath) {
				result.setInfo(NewWizardMessages.AddSourceFolderWizardPage_conflictWarning + status.getMessage());
			} else {
				result.setError(status.getMessage());
			}
			return result;
		}
		if (!modified.isEmpty()) {
			//Added exclusion patterns to solve problem
			if (modified.size() == 1) {
				CPListElement elem= (CPListElement)modified.toArray()[0];
				String changed= BasicElementLabels.getPathLabel(elem.getPath(), false);
				String excl= BasicElementLabels.getPathLabel(fNewElement.getPath(), false);
				result.setInfo(Messages.format(NewWizardMessages.AddSourceFolderWizardPage_addSinglePattern, new Object[] {excl, changed}));
			} else {
				result.setInfo(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_warning_AddedExclusions_plural, String.valueOf(modified.size())));
			}
			return result;
		}
		if (isProjectSourceFolderReplaced) {
			result.setInfo(NewWizardMessages.AddSourceFolderWizardPage_replaceSourceFolderInfo);
			return result;
		}

		return result;
	}

	public void restore() {
		for (CPListElement existingEntry : fExistingEntries) {
			if (fOrginalExlusionFilters.containsKey(existingEntry)) {
				existingEntry.setAttribute(CPListElement.EXCLUSION, fOrginalExlusionFiltersCopy.get(existingEntry));
			}
			if (fOrginalInclusionFilters.containsKey(existingEntry)) {
				existingEntry.setAttribute(CPListElement.INCLUSION, fOrginalInclusionFiltersCopy.get(existingEntry));
			}
		}
		fNewElement.setPath(fOrginalPath);
	}

	private void restoreCPElements() {
		if (fNewElement.getPath() != null) {
			for (CPListElement existingEntry : fExistingEntries) {
				if (fOrginalExlusionFilters.containsKey(existingEntry)) {
					existingEntry.setAttribute(CPListElement.EXCLUSION, fOrginalExlusionFilters.get(existingEntry));
				}
				if (fOrginalInclusionFilters.containsKey(existingEntry)) {
					existingEntry.setAttribute(CPListElement.INCLUSION, fOrginalInclusionFilters.get(existingEntry));
				}
			}

			if (fOldProjectSourceFolder != null) {
				fExistingEntries.set(fExistingEntries.indexOf(fNewElement), fOldProjectSourceFolder);
				fOldProjectSourceFolder= null;
			} else if (fExistingEntries.contains(fNewElement)) {
				fExistingEntries.remove(fNewElement);
			}
		}
	}

	private void updateFilters(IPath oldPath, IPath newPath) {
		if (oldPath == null)
			return;

		IPath projPath= fNewElement.getJavaProject().getProject().getFullPath();
		if (projPath.isPrefixOf(oldPath)) {
			oldPath= oldPath.removeFirstSegments(projPath.segmentCount()).addTrailingSeparator();
		}
		if (projPath.isPrefixOf(newPath)) {
			newPath= newPath.removeFirstSegments(projPath.segmentCount()).addTrailingSeparator();
		}

		for (CPListElement existingEntry : fExistingEntries) {
			IPath elementPath= existingEntry.getPath();
			if (projPath.isPrefixOf(elementPath)) {
				elementPath= elementPath.removeFirstSegments(projPath.segmentCount());
				if (elementPath.segmentCount() > 0)
					elementPath= elementPath.addTrailingSeparator();
			}

			IPath[] exlusions= (IPath[])existingEntry.getAttribute(CPListElement.EXCLUSION);
			if (exlusions != null) {
				for (int i= 0; i < exlusions.length; i++) {
					if (elementPath.append(exlusions[i]).equals(oldPath)) {
						fModifiedElements.add(existingEntry);
						exlusions[i]= newPath.removeFirstSegments(elementPath.segmentCount());
					}
				}
				existingEntry.setAttribute(CPListElement.EXCLUSION, exlusions);
			}

			IPath[] inclusion= (IPath[])existingEntry.getAttribute(CPListElement.INCLUSION);
			if (inclusion != null) {
				for (int i= 0; i < inclusion.length; i++) {
					if (elementPath.append(inclusion[i]).equals(oldPath)) {
						fModifiedElements.add(existingEntry);
						inclusion[i]= newPath.removeFirstSegments(elementPath.segmentCount());
					}
				}
				existingEntry.setAttribute(CPListElement.INCLUSION, inclusion);
			}
		}
	}

    /**
	 * Validates this page's controls.
     * @param folderName the folder name
	 *
	 * @return IStatus indicating the validation result. IStatus.OK if the
	 *  specified link target is valid given the linkHandle.
	 */
	private IStatus validateLinkLocation(String folderName) {
		IWorkspace workspace= JavaPlugin.getWorkspace();
		IPath path= Path.fromOSString(fLinkFields.fLinkLocation.getText());

		Path folderLocation= new Path(folderName);
		if (folderLocation.isAbsolute())
			return new StatusInfo(IStatus.ERROR, NewWizardMessages.AddSourceFolderWizardPage_error_NotARelativePathName);

		IProject project= fNewElement.getJavaProject().getProject();
		IFolder folder= project.getFolder(folderLocation);
		IStatus locationStatus= workspace.validateLinkLocation(folder, path);
		if (locationStatus.matches(IStatus.ERROR))
			return locationStatus;

		IPathVariableManager pathVariableManager= project.getPathVariableManager();
		IPath path1= Path.fromOSString(fLinkFields.fLinkLocation.getText());
		IPath resolvedPath= pathVariableManager.resolvePath(path1);
		// use the resolved link target name
		String resolvedLinkTarget= resolvedPath.toOSString();

		File linkTargetFile= new Path(resolvedLinkTarget).toFile();
		if (linkTargetFile.exists()) {
			if (!linkTargetFile.isDirectory())
	            return new StatusInfo(IStatus.ERROR, NewWizardMessages.NewFolderDialog_linkTargetNotFolder);
		} else {
			return new StatusInfo(IStatus.ERROR, NewWizardMessages.NewFolderDialog_linkTargetNonExistent);
		}
		if (locationStatus.isOK()) {
			return new StatusInfo();
		}
		return new StatusInfo(locationStatus.getSeverity(), locationStatus.getMessage());
	}

	private static StatusInfo validatePathName(String str, IContainer parent) {
		StatusInfo result= new StatusInfo();
		result.setOK();

		IPath parentPath= parent.getFullPath();

		if (str.length() == 0) {
			result.setError(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_error_EnterRootName, BasicElementLabels.getPathLabel(parentPath, false)));
			return result;
		}

		IPath path= parentPath.append(str);

		IWorkspaceRoot workspaceRoot= ResourcesPlugin.getWorkspace().getRoot();
		IStatus validate= workspaceRoot.getWorkspace().validatePath(path.toString(), IResource.FOLDER);
		if (validate.matches(IStatus.ERROR)) {
			result.setError(Messages.format(NewWizardMessages.NewSourceFolderWizardPage_error_InvalidRootName, validate.getMessage()));
			return result;
		}

		IResource res= workspaceRoot.findMember(path);
		if (res != null) {
			if (res.getType() != IResource.FOLDER) {
				result.setError(NewWizardMessages.NewSourceFolderWizardPage_error_NotAFolder);
				return result;
			}
		} else {

			URI parentLocation= parent.getLocationURI();
			if (parentLocation != null) {
				try {
					IFileStore store= EFS.getStore(parentLocation).getChild(str);
					if (store.fetchInfo().exists()) {
						result.setError(NewWizardMessages.NewSourceFolderWizardPage_error_AlreadyExistingDifferentCase);
						return result;
					}
				} catch (CoreException e) {
					// we couldn't create the file store. Ignore the exception
					// since we can't check if the file exist. Pretend that it
					// doesn't.
				}
			}
		}

		return result;
	}

	private void addExclusionPatterns(CPListElement newEntry, List<CPListElement> existing, Set<CPListElement> modifiedEntries) {
		IPath entryPath= newEntry.getPath();
		for (CPListElement curr : existing) {
			IPath currPath= curr.getPath();
			if (curr != newEntry && curr.getEntryKind() == IClasspathEntry.CPE_SOURCE && currPath.isPrefixOf(entryPath)) {
				boolean added= curr.addToExclusions(entryPath);
				if (added) {
					modifiedEntries.add(curr);
				}
			}
		}
	}

	public IResource getCorrespondingResource() {
		return fParent.getFolder(new Path(fRootDialogField.getText()));
	}

	public IPath getOutputLocation() {
		if (fNewOutputLocation != null) {
			return fNewOutputLocation;
		}

		return fOutputLocation;
	}

	// ------------- choose dialogs

	private IFolder chooseFolder(String title, String message, IPath initialPath) {
		Class<?>[] acceptedClasses= new Class[] { IFolder.class };
		ISelectionStatusValidator validator= new TypedElementSelectionValidator(acceptedClasses, false);
		ViewerFilter filter= new TypedViewerFilter(acceptedClasses, null);

		ILabelProvider lp= new WorkbenchLabelProvider();
		ITreeContentProvider cp= new WorkbenchContentProvider();

		IProject currProject= fNewElement.getJavaProject().getProject();

		ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getShell(), lp, cp) {
			@Override
			protected Control createDialogArea(Composite parent) {
				Control result= super.createDialogArea(parent);
				PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IJavaHelpContextIds.BP_CHOOSE_EXISTING_FOLDER_TO_MAKE_SOURCE_FOLDER);
				return result;
			}
		};
		dialog.setValidator(validator);
		dialog.setTitle(title);
		dialog.setMessage(message);
		dialog.addFilter(filter);
		dialog.setInput(currProject);
		dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
		IResource res= currProject.findMember(initialPath);
		if (res != null) {
			dialog.setInitialSelection(res);
		}

		if (dialog.open() == Window.OK) {
			return (IFolder) dialog.getFirstResult();
		}
		return null;
	}

	public List<CPListElement> getModifiedElements() {
		if (fOrginalPath != null && !fModifiedElements.contains(fNewElement))
			fModifiedElements.add(fNewElement);

		return fModifiedElements;
	}

	public List<CPListElement> getRemovedElements() {
		return fRemovedElements;
	}

}
