/*******************************************************************************
 * 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
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.wizards.buildpaths;

import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

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.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Widget;

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.SubProgressMonitor;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
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.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.preference.IPreferenceStore;
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.ISelectionStatusValidator;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
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.core.JavaCore;

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

import org.eclipse.jdt.launching.JavaRuntime;

import org.eclipse.jdt.ui.PreferenceConstants;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
import org.eclipse.jdt.internal.ui.util.CoreUtility;
import org.eclipse.jdt.internal.ui.viewsupport.ImageDisposer;
import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
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.buildpaths.newsourcepage.NewSourceContainerWorkbookPage;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.CheckedListDialogField;
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.IListAdapter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;

public class BuildPathsBlock {

	public interface IRemoveOldBinariesQuery {

		/**
		 * Do the callback. Returns <code>true</code> if .class files should be removed from the
		 * old output location.
		 * @param removeLocation true if the folder at oldOutputLocation should be removed, false if only its content
		 * @param oldOutputLocation The old output location
		 * @return Returns true if .class files should be removed.
		 * @throws OperationCanceledException if the operation was canceled
		 */
		boolean doQuery(boolean removeLocation, IPath oldOutputLocation) throws OperationCanceledException;

	}


	private IWorkspaceRoot fWorkspaceRoot;

	private CheckedListDialogField<CPListElement> fClassPathList;
	private StringButtonDialogField fBuildPathDialogField;

	private StatusInfo fClassPathStatus;
	private StatusInfo fOutputFolderStatus;
	private StatusInfo fBuildPathStatus;

	private IJavaProject fCurrJProject;

	private IPath fOutputLocationPath;

	private IStatusChangeListener fContext;
	private Control fSWTWidget;
	private TabFolder fTabFolder;

	private int fPageIndex;

	private BuildPathBasePage fSourceContainerPage;
	private ProjectsWorkbookPage fProjectsPage;
	private LibrariesWorkbookPage fLibrariesPage;
	private ModuleDependenciesPage fModulesPage;

	private BuildPathBasePage fCurrPage;

	private String fUserSettingsTimeStamp;
	private long fFileTimeStamp;

    private IRunnableContext fRunnableContext;

	private boolean fUseNewPage;

	private boolean fIs9OrHigher;

	private final IWorkbenchPreferenceContainer fPageContainer; // null when invoked from a non-property page context

	private final static int IDX_UP= 0;
	private final static int IDX_DOWN= 1;
	private final static int IDX_TOP= 3;
	private final static int IDX_BOTTOM= 4;
	private final static int IDX_SELECT_ALL= 6;
	private final static int IDX_UNSELECT_ALL= 7;

	public BuildPathsBlock(IRunnableContext runnableContext, IStatusChangeListener context, int pageToShow, boolean useNewPage, IWorkbenchPreferenceContainer pageContainer) {
		fPageContainer= pageContainer;
		fWorkspaceRoot= JavaPlugin.getWorkspace().getRoot();
		fContext= context;
		fUseNewPage= useNewPage;

		fPageIndex= pageToShow;

		fSourceContainerPage= null;
		fLibrariesPage= null;
		fProjectsPage= null;
		fCurrPage= null;
        fRunnableContext= runnableContext;

		BuildPathAdapter adapter= new BuildPathAdapter();

		String[] buttonLabels= new String[] {
			/* IDX_UP */ NewWizardMessages.BuildPathsBlock_classpath_up_button,
			/* IDX_DOWN */ NewWizardMessages.BuildPathsBlock_classpath_down_button,
			/* 2 */ null,
			/* IDX_TOP */ NewWizardMessages.BuildPathsBlock_classpath_top_button,
			/* IDX_BOTTOM */ NewWizardMessages.BuildPathsBlock_classpath_bottom_button,
			/* 5 */ null,
			/* IDX_SELECT_ALL */ NewWizardMessages.BuildPathsBlock_classpath_checkall_button,
			/* IDX_UNSELECT_ALL */ NewWizardMessages.BuildPathsBlock_classpath_uncheckall_button

		};

		fClassPathList= new CheckedListDialogField<>(adapter, buttonLabels, new CPListLabelProvider());
		fClassPathList.setDialogFieldListener(adapter);
		fClassPathList.setLabelText(NewWizardMessages.BuildPathsBlock_classpath_label);
		fClassPathList.setUpButtonIndex(IDX_UP);
		fClassPathList.setDownButtonIndex(IDX_DOWN);
		fClassPathList.setCheckAllButtonIndex(IDX_SELECT_ALL);
		fClassPathList.setUncheckAllButtonIndex(IDX_UNSELECT_ALL);

		fBuildPathDialogField= new StringButtonDialogField(adapter);
		fBuildPathDialogField.setButtonLabel(NewWizardMessages.BuildPathsBlock_buildpath_button);
		fBuildPathDialogField.setDialogFieldListener(adapter);
		fBuildPathDialogField.setLabelText(NewWizardMessages.BuildPathsBlock_buildpath_label);

		fBuildPathStatus= new StatusInfo();
		fClassPathStatus= new StatusInfo();
		fOutputFolderStatus= new StatusInfo();

		fCurrJProject= null;
	}

	// -------- UI creation ---------

	public Control createControl(Composite parent) {
		fSWTWidget= parent;

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

		GridLayout layout= new GridLayout();
		layout.marginWidth= 0;
		layout.marginHeight= 0;
		layout.numColumns= 1;
		composite.setLayout(layout);

		TabFolder folder= new TabFolder(composite, SWT.NONE);
		folder.setLayoutData(new GridData(GridData.FILL_BOTH));
		folder.setFont(composite.getFont());

		TabItem item;
        item= new TabItem(folder, SWT.NONE);
        item.setText(NewWizardMessages.BuildPathsBlock_tab_source);
        item.setImage(JavaPluginImages.get(JavaPluginImages.IMG_OBJS_PACKFRAG_ROOT));

        if (fUseNewPage) {
			fSourceContainerPage= new NewSourceContainerWorkbookPage(fClassPathList, fBuildPathDialogField, fRunnableContext, this);
        } else {
			fSourceContainerPage= new SourceContainerWorkbookPage(fClassPathList, fBuildPathDialogField);
        }
        item.setData(fSourceContainerPage);
        item.setControl(fSourceContainerPage.getControl(folder));

		Image projectImage= PlatformUI.getWorkbench().getSharedImages().getImage(IDE.SharedImages.IMG_OBJ_PROJECT);

		fProjectsPage= new ProjectsWorkbookPage(fClassPathList, fPageContainer);
		item= new TabItem(folder, SWT.NONE);
		item.setText(NewWizardMessages.BuildPathsBlock_tab_projects);
		item.setImage(projectImage);
		item.setData(fProjectsPage);
		item.setControl(fProjectsPage.getControl(folder));

		fLibrariesPage= new LibrariesWorkbookPage(fClassPathList, fPageContainer);
		item= new TabItem(folder, SWT.NONE);
		item.setText(NewWizardMessages.BuildPathsBlock_tab_libraries);
		item.setImage(JavaPluginImages.get(JavaPluginImages.IMG_OBJS_LIBRARY));
		item.setData(fLibrariesPage);
		item.setControl(fLibrariesPage.getControl(folder));

		// a non shared image
		Image cpoImage= JavaPluginImages.DESC_TOOL_CLASSPATH_ORDER.createImage();
		composite.addDisposeListener(new ImageDisposer(cpoImage));

		ClasspathOrderingWorkbookPage ordpage= new ClasspathOrderingWorkbookPage(fClassPathList);
		item= new TabItem(folder, SWT.NONE);
		item.setText(NewWizardMessages.BuildPathsBlock_tab_order);
		item.setImage(cpoImage);
		item.setData(ordpage);
		item.setControl(ordpage.getControl(folder));

		fModulesPage= new ModuleDependenciesPage(fContext, fClassPathList);
		item= new TabItem(folder, SWT.NONE);
		item.setText(NewWizardMessages.BuildPathsBlock_tab_modules);
		item.setImage(JavaPluginImages.get(JavaPluginImages.IMG_OBJS_MODULE));
		item.setData(fModulesPage);
		item.setControl(fModulesPage.getControl(folder));

		if (fCurrJProject != null) {
			fSourceContainerPage.init(fCurrJProject);
			fLibrariesPage.init(fCurrJProject);
			fProjectsPage.init(fCurrJProject);
			fModulesPage.init(fCurrJProject);
			fIs9OrHigher= JavaModelUtil.is9OrHigher(fCurrJProject);
		}

		folder.setSelection(fPageIndex);
		fCurrPage= (BuildPathBasePage) folder.getItem(fPageIndex).getData();
		folder.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				tabChanged(e.item);
			}
		});
		fTabFolder= folder;

		Dialog.applyDialogFont(composite);
		return composite;
	}

	private Shell getShell() {
		if (fSWTWidget != null) {
			return fSWTWidget.getShell();
		}
		return JavaPlugin.getActiveWorkbenchShell();
	}

	/**
	 * Initializes the classpath for the given project. Multiple calls to init are allowed,
	 * but all existing settings will be cleared and replace by the given or default paths.
	 * @param jproject The java project to configure. Does not have to exist.
	 * @param outputLocation The output location to be set in the page. If <code>null</code>
	 * is passed, jdt default settings are used, or - if the project is an existing Java project- the
	 * output location of the existing project
	 * @param classpathEntries The classpath entries to be set in the page. If <code>null</code>
	 * is passed, jdt default settings are used, or - if the project is an existing Java project - the
	 * classpath entries of the existing project
	 */
	public void init(IJavaProject jproject, IPath outputLocation, IClasspathEntry[] classpathEntries) {
		fCurrJProject= jproject;
		List<CPListElement> newClassPath= null;
		IProject project= fCurrJProject.getProject();
		boolean projectExists= (project.exists() && project.getFile(".classpath").exists()); //$NON-NLS-1$
		IClasspathEntry[] existingEntries= null;
		if  (projectExists) {
			if (outputLocation == null) {
				outputLocation=  fCurrJProject.readOutputLocation();
			}
			existingEntries= fCurrJProject.readRawClasspath();
			if (classpathEntries == null) {
				classpathEntries= existingEntries;
			}
		}
		if (outputLocation == null) {
			outputLocation= getDefaultOutputLocation(jproject);
		}

		if (classpathEntries != null) {
			newClassPath= getCPListElements(classpathEntries, existingEntries);
		}
		if (newClassPath == null) {
			newClassPath= getDefaultClassPath(jproject);
		}

		List<CPListElement> exportedEntries = new ArrayList<>();
		for (int i= 0; i < newClassPath.size(); i++) {
			CPListElement curr= newClassPath.get(i);
			if (curr.isExported() || curr.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
				exportedEntries.add(curr);
			}
		}

		// inits the dialog field
		fBuildPathDialogField.setText(outputLocation.makeRelative().toString());
		fBuildPathDialogField.enableButton(project.exists());
		fClassPathList.setElements(newClassPath);
		fClassPathList.setCheckedElements(exportedEntries);

		fClassPathList.selectFirstElement();

		if (fSourceContainerPage != null) {
			fSourceContainerPage.init(fCurrJProject);
			fProjectsPage.init(fCurrJProject);
			fLibrariesPage.init(fCurrJProject);
			// fModulesPage will be unconditionally initialized in updateUI() below
			fIs9OrHigher= JavaModelUtil.is9OrHigher(fCurrJProject);
		}

		initializeTimeStamps();
		updateUI();
	}

	protected void updateUI() {
		if (fSWTWidget == null || fSWTWidget.isDisposed()) {
			return;
		}

		if (Display.getCurrent() != null) {
			doUpdateUI();
		} else {
			Display.getDefault().asyncExec(() -> {
				if (fSWTWidget == null || fSWTWidget.isDisposed()) {
					return;
				}
				doUpdateUI();
			});
		}
	}

	protected void doUpdateUI() {
		if (fModulesPage.needReInit()) {
			init(fCurrJProject, null, null); // extent of system modules was changed, re-init fClassPathList
		}
		fBuildPathDialogField.refresh();
		fClassPathList.refresh();
		boolean is9OrHigherAfter= JavaModelUtil.is9OrHigher(fCurrJProject);
		if (is9OrHigherAfter != fIs9OrHigher) {
			// update the library and project page if fis9OrHigher changed
			fLibrariesPage.init(fCurrJProject);
			fProjectsPage.init(fCurrJProject);
			fIs9OrHigher= is9OrHigherAfter;
		}
		fModulesPage.init(fCurrJProject); // always update, Apply might have made more modules visible
		doStatusLineUpdate();
	}

	private String getEncodedSettings() {
		StringBuffer buf= new StringBuffer();
		CPListElement.appendEncodePath(fOutputLocationPath, buf).append(';');

		int nElements= fClassPathList.getSize();
		buf.append('[').append(nElements).append(']');
		for (int i= 0; i < nElements; i++) {
			CPListElement elem= fClassPathList.getElement(i);
			elem.appendEncodedSettings(buf);
		}
		return buf.toString();
	}

	public boolean hasChangesInDialog() {
		String currSettings= getEncodedSettings();
		return !currSettings.equals(fUserSettingsTimeStamp);
	}

	public boolean hasChangesInClasspathFile() {
		IFile file= fCurrJProject.getProject().getFile(".classpath"); //$NON-NLS-1$
		return fFileTimeStamp != file.getModificationStamp();
	}

	public boolean isClassfileMissing() {
		return !fCurrJProject.getProject().getFile(".classpath").exists(); //$NON-NLS-1$
	}

	public void initializeTimeStamps() {
		IFile file= fCurrJProject.getProject().getFile(".classpath"); //$NON-NLS-1$
		fFileTimeStamp= file.getModificationStamp();
		fUserSettingsTimeStamp= getEncodedSettings();
	}

	private ArrayList<CPListElement> getCPListElements(IClasspathEntry[] classpathEntries, IClasspathEntry[] existingEntries) {
		List<IClasspathEntry> existing= existingEntries == null ? Collections.<IClasspathEntry>emptyList() : Arrays.asList(existingEntries);
		ArrayList<CPListElement> newClassPath= new ArrayList<>();
		for (IClasspathEntry curr : classpathEntries) {
			newClassPath.add(CPListElement.create(curr, ! existing.contains(curr), fCurrJProject));
		}
		return newClassPath;
	}

	// -------- public api --------

	/**
	 * @return Returns the Java project. Can return <code>null<code> if the page has not
	 * been initialized.
	 */
	public IJavaProject getJavaProject() {
		return fCurrJProject;
	}

	/**
	 *  @return Returns the current output location. Note that the path returned must not be valid.
	 */
	public IPath getOutputLocation() {
		return new Path(fBuildPathDialogField.getText()).makeAbsolute();
	}

	/**
	 *  @return Returns the current class path (raw). Note that the entries returned must not be valid.
	 */
	public IClasspathEntry[] getRawClassPath() {
		List<CPListElement> elements=  fClassPathList.getElements();
		int nElements= elements.size();
		IClasspathEntry[] entries= new IClasspathEntry[elements.size()];

		for (int i= 0; i < nElements; i++) {
			CPListElement currElement= elements.get(i);
			entries[i]= currElement.getClasspathEntry();
		}
		return entries;
	}

	public int getPageIndex() {
		return fPageIndex;
	}


	// -------- evaluate default settings --------

	private List<CPListElement> getDefaultClassPath(IJavaProject jproj) {
		List<CPListElement> list= new ArrayList<>();
		IResource srcFolder;
		IPreferenceStore store= PreferenceConstants.getPreferenceStore();
		String sourceFolderName= store.getString(PreferenceConstants.SRCBIN_SRCNAME);
		if (store.getBoolean(PreferenceConstants.SRCBIN_FOLDERS_IN_NEWPROJ) && sourceFolderName.length() > 0) {
			srcFolder= jproj.getProject().getFolder(sourceFolderName);
		} else {
			srcFolder= jproj.getProject();
		}

		list.add(new CPListElement(jproj, IClasspathEntry.CPE_SOURCE, srcFolder.getFullPath(), srcFolder));

		IClasspathEntry[] jreEntries= PreferenceConstants.getDefaultJRELibrary();
		list.addAll(getCPListElements(jreEntries, null));
		return list;
	}

	public static IPath getDefaultOutputLocation(IJavaProject jproj) {
		IPreferenceStore store= PreferenceConstants.getPreferenceStore();
		if (store.getBoolean(PreferenceConstants.SRCBIN_FOLDERS_IN_NEWPROJ)) {
			String outputLocationName= store.getString(PreferenceConstants.SRCBIN_BINNAME);
			return jproj.getProject().getFullPath().append(outputLocationName);
		} else {
			return jproj.getProject().getFullPath();
		}
	}

	private class BuildPathAdapter implements IStringButtonAdapter, IDialogFieldListener, IListAdapter<CPListElement> {

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

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

		// ---------- IListAdapter --------
		@Override
		public void customButtonPressed(ListDialogField<CPListElement> field, int index) {
			buildPathCustomButtonPressed(field, index);
		}

		@Override
		public void doubleClicked(ListDialogField<CPListElement> field) {
		}

		@Override
		public void selectionChanged(ListDialogField<CPListElement> field) {
			updateTopButtonEnablement();
		}
	}

	private void buildPathChangeControlPressed(DialogField field) {
		if (field == fBuildPathDialogField) {
			IContainer container= chooseContainer();
			if (container != null) {
				fBuildPathDialogField.setText(container.getFullPath().makeRelative().toString());
			}
		}
	}

	public void updateTopButtonEnablement() {
		fClassPathList.enableButton(IDX_BOTTOM, fClassPathList.canMoveDown());
		fClassPathList.enableButton(IDX_TOP, fClassPathList.canMoveUp());
	}

	public void buildPathCustomButtonPressed(ListDialogField<CPListElement> field, int index) {
		List<CPListElement> elems= field.getSelectedElements();
		field.removeElements(elems);
		if (index == IDX_BOTTOM) {
			field.addElements(elems);
		} else if (index == IDX_TOP) {
			field.addElements(elems, 0);
		}
	}

	private void buildPathDialogFieldChanged(DialogField field) {
		if (field == fClassPathList) {
			updateClassPathStatus();
			updateTopButtonEnablement();
		} else if (field == fBuildPathDialogField) {
			updateOutputLocationStatus();
		}
		doStatusLineUpdate();
	}



	// -------- verification -------------------------------

	private void doStatusLineUpdate() {
		if (Display.getCurrent() != null) {
			IStatus res= findMostSevereStatus();
			fContext.statusChanged(res);
		}
	}

	private IStatus findMostSevereStatus() {
		return StatusUtil.getMostSevere(new IStatus[] { fClassPathStatus, fOutputFolderStatus, fBuildPathStatus });
	}


	/**
	 * Validates the build path.
	 */
	public void updateClassPathStatus() {
		fClassPathStatus.setOK();

		List<CPListElement> elements= fClassPathList.getElements();

		CPListElement entryMissing= null;
		CPListElement entryDeprecated= null;
		int nEntriesMissing= 0;
		IClasspathEntry[] entries= new IClasspathEntry[elements.size()];

		for (int i= elements.size()-1 ; i >= 0 ; i--) {
			CPListElement currElement= elements.get(i);
			boolean isChecked= fClassPathList.isChecked(currElement);
			if (currElement.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
				if (!isChecked) {
					fClassPathList.setCheckedWithoutUpdate(currElement, true);
				}
				if (!fClassPathList.isGrayed(currElement)) {
					fClassPathList.setGrayedWithoutUpdate(currElement, true);
				}
			} else {
				currElement.setExported(isChecked);
			}

			entries[i]= currElement.getClasspathEntry();
			if (currElement.isMissing()) {
				nEntriesMissing++;
				if (entryMissing == null) {
					entryMissing= currElement;
				}
			}
			if (entryDeprecated == null && currElement.isDeprecated()) {
				entryDeprecated= currElement;
			}
		}

		if (nEntriesMissing > 0) {
			if (nEntriesMissing == 1) {
				fClassPathStatus.setWarning(Messages.format(NewWizardMessages.BuildPathsBlock_warning_EntryMissing, BasicElementLabels.getPathLabel(entryMissing.getPath(), false)));
			} else {
				fClassPathStatus.setWarning(Messages.format(NewWizardMessages.BuildPathsBlock_warning_EntriesMissing, String.valueOf(nEntriesMissing)));
			}
		} else if (entryDeprecated != null) {
			fClassPathStatus.setInfo(entryDeprecated.getDeprecationMessage());
		}

/*		if (fCurrJProject.hasClasspathCycle(entries)) {
			fClassPathStatus.setWarning(NewWizardMessages.getString("BuildPathsBlock.warning.CycleInClassPath")); //$NON-NLS-1$
		}
*/
		updateBuildPathStatus();
	}

	/**
	 * Validates output location & build path.
	 */
	private void updateOutputLocationStatus() {
		fOutputLocationPath= null;

		String text= fBuildPathDialogField.getText();
		if ("".equals(text)) { //$NON-NLS-1$
			fOutputFolderStatus.setError(NewWizardMessages.BuildPathsBlock_error_EnterBuildPath);
			return;
		}
		IPath path= getOutputLocation();
		fOutputLocationPath= path;

		IResource res= fWorkspaceRoot.findMember(path);
		if (res != null) {
			// if exists, must be a folder or project
			if (res.getType() == IResource.FILE) {
				fOutputFolderStatus.setError(NewWizardMessages.BuildPathsBlock_error_InvalidBuildPath);
				return;
			}
		}

		fOutputFolderStatus.setOK();

		String pathStr= fBuildPathDialogField.getText();
		Path outputPath= (new Path(pathStr));
		pathStr= outputPath.lastSegment();
		if (pathStr.equals(".settings") && outputPath.segmentCount() == 2) { //$NON-NLS-1$
			fOutputFolderStatus.setWarning(NewWizardMessages.OutputLocation_SettingsAsLocation);
		}

		if (pathStr.charAt(0) == '.' && pathStr.length() > 1) {
			fOutputFolderStatus.setWarning(Messages.format(NewWizardMessages.OutputLocation_DotAsLocation, BasicElementLabels.getResourceName(pathStr)));
		}

		updateBuildPathStatus();
	}

	private void updateBuildPathStatus() {
		List<CPListElement> elements= fClassPathList.getElements();
		IClasspathEntry[] entries= new IClasspathEntry[elements.size()];

		for (int i= elements.size()-1 ; i >= 0 ; i--) {
			CPListElement currElement= elements.get(i);
			entries[i]= currElement.getClasspathEntry();
		}

		IJavaModelStatus status= JavaConventions.validateClasspath(fCurrJProject, entries, fOutputLocationPath);
		if (!status.isOK()) {
			fBuildPathStatus.setError(status.getMessage());
			return;
		}
		fBuildPathStatus.setOK();
	}

	// -------- creation -------------------------------

	public static void createProject(IProject project, URI locationURI, IProgressMonitor monitor) throws CoreException {
		if (monitor == null) {
			monitor= new NullProgressMonitor();
		}
		monitor.beginTask(NewWizardMessages.BuildPathsBlock_operationdesc_project, 10);

		// create the project
		try {
			if (!project.exists()) {
				IProjectDescription desc= project.getWorkspace().newProjectDescription(project.getName());
				if (locationURI != null && ResourcesPlugin.getWorkspace().getRoot().getLocationURI().equals(locationURI)) {
					locationURI= null;
				}
				desc.setLocationURI(locationURI);
				project.create(desc, monitor);
				monitor= null;
			}
			if (!project.isOpen()) {
				project.open(monitor);
				monitor= null;
			}
		} finally {
			if (monitor != null) {
				monitor.done();
			}
		}
	}

	public static void addJavaNature(IProject project, IProgressMonitor monitor) throws CoreException {
		if (monitor != null && monitor.isCanceled()) {
			throw new OperationCanceledException();
		}
		if (!project.hasNature(JavaCore.NATURE_ID)) {
			IProjectDescription description = project.getDescription();
			String[] prevNatures= description.getNatureIds();
			String[] newNatures= new String[prevNatures.length + 1];
			System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
			newNatures[prevNatures.length]= JavaCore.NATURE_ID;
			description.setNatureIds(newNatures);
			project.setDescription(description, monitor);
		} else {
			if (monitor != null) {
				monitor.worked(1);
			}
		}
	}

	public void configureJavaProject(IProgressMonitor monitor) throws CoreException, OperationCanceledException {
		configureJavaProject(null, monitor);
	}

	public void configureJavaProject(String newProjectCompliance, IProgressMonitor monitor) throws CoreException, OperationCanceledException {
		flush(fClassPathList.getElements(), getOutputLocation(), getJavaProject(), newProjectCompliance, monitor);
		initializeTimeStamps();

		updateUI();
	}

	/**
	 * Sets the configured build path and output location to the given Java project.
	 * If the project already exists, only build paths are updated.
	 * <p>
	 * If the classpath contains an Execution Environment entry, the EE's compiler compliance options
	 * are used as project-specific options (unless the classpath already contained the same Execution Environment)
	 *
	 * @param classPathEntries the new classpath entries (list of {@link CPListElement})
	 * @param outputLocation the output location
	 * @param javaProject the Java project
	 * @param newProjectCompliance compliance to set for a new project, can be <code>null</code>
	 * @param monitor a progress monitor, or <code>null</code>
	 * @throws CoreException if flushing failed
	 * @throws OperationCanceledException if flushing has been cancelled
	 */
	public static void flush(List<CPListElement> classPathEntries, IPath outputLocation, IJavaProject javaProject, String newProjectCompliance, IProgressMonitor monitor) throws CoreException, OperationCanceledException {
		if (monitor == null) {
			monitor= new NullProgressMonitor();
		}
		monitor.setTaskName(NewWizardMessages.BuildPathsBlock_operationdesc_java);
		monitor.beginTask("", classPathEntries.size() * 4 + 4); //$NON-NLS-1$
		try {

			IProject project= javaProject.getProject();
			IPath projPath= project.getFullPath();

			IPath oldOutputLocation;
			try {
				oldOutputLocation= javaProject.getOutputLocation();
			} catch (CoreException e) {
				oldOutputLocation= projPath.append(PreferenceConstants.getPreferenceStore().getString(PreferenceConstants.SRCBIN_BINNAME));
			}

			if (oldOutputLocation.equals(projPath) && !outputLocation.equals(projPath)) {
				if (BuildPathsBlock.hasClassfiles(project)) {
					if (BuildPathsBlock.getRemoveOldBinariesQuery(JavaPlugin.getActiveWorkbenchShell()).doQuery(false, projPath)) {
						BuildPathsBlock.removeOldClassfiles(project);
					}
				}
			} else if (!outputLocation.equals(oldOutputLocation)) {
				IFolder folder= ResourcesPlugin.getWorkspace().getRoot().getFolder(oldOutputLocation);
				if (folder.exists()) {
					if (folder.members().length == 0
							|| BuildPathsBlock.getRemoveOldBinariesQuery(JavaPlugin.getActiveWorkbenchShell()).doQuery(folder.isDerived(), oldOutputLocation)) {
						BuildPathsBlock.removeOldClassfiles(folder);
					}
				}
			}

			monitor.worked(1);

			IWorkspaceRoot fWorkspaceRoot= JavaPlugin.getWorkspace().getRoot();

			//create and set the output path first
			if (!fWorkspaceRoot.exists(outputLocation)) {
				IFolder folder= fWorkspaceRoot.getFolder(outputLocation);
				CoreUtility.createDerivedFolder(folder, true, true, new SubProgressMonitor(monitor, 1));
			} else {
				monitor.worked(1);
			}
			if (monitor.isCanceled()) {
				throw new OperationCanceledException();
			}

			int nEntries= classPathEntries.size();
			IClasspathEntry[] classpath= new IClasspathEntry[nEntries];
			int i= 0;

			for (CPListElement entry : classPathEntries) {
				if(entry.isRootNodeForPath()){
					continue;
				}
				classpath[i]= entry.getClasspathEntry();
				i++;

				IResource res= entry.getResource();
				//1 tick
				if (res instanceof IFolder && entry.getLinkTarget() == null && !res.exists()) {
					CoreUtility.createFolder((IFolder)res, true, true, new SubProgressMonitor(monitor, 1));
				} else {
					monitor.worked(1);
				}

				//3 ticks
				if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
					IPath folderOutput= (IPath) entry.getAttribute(CPListElement.OUTPUT);
					if (folderOutput != null && folderOutput.segmentCount() > 1) {
						IFolder folder= fWorkspaceRoot.getFolder(folderOutput);
						CoreUtility.createDerivedFolder(folder, true, true, new SubProgressMonitor(monitor, 1));
					} else {
						monitor.worked(1);
					}

					IPath path= entry.getPath();
					if (projPath.equals(path)) {
						monitor.worked(2);
						continue;
					}

					if (projPath.isPrefixOf(path)) {
						path= path.removeFirstSegments(projPath.segmentCount());
					}
					IFolder folder= project.getFolder(path);
					IPath orginalPath= entry.getOrginalPath();
					if (orginalPath == null) {
						if (!folder.exists()) {
							//New source folder needs to be created
							if (entry.getLinkTarget() == null) {
								CoreUtility.createFolder(folder, true, true, new SubProgressMonitor(monitor, 2));
							} else {
								folder.createLink(entry.getLinkTarget(), IResource.ALLOW_MISSING_LOCAL, new SubProgressMonitor(monitor, 2));
							}
						}
					} else {
						if (projPath.isPrefixOf(orginalPath)) {
							orginalPath= orginalPath.removeFirstSegments(projPath.segmentCount());
						}
						IFolder orginalFolder= project.getFolder(orginalPath);
						if (entry.getLinkTarget() == null) {
							if (!folder.exists()) {
								//Source folder was edited, move to new location
								IPath parentPath= entry.getPath().removeLastSegments(1);
								if (projPath.isPrefixOf(parentPath)) {
									parentPath= parentPath.removeFirstSegments(projPath.segmentCount());
								}
								if (parentPath.segmentCount() > 0) {
									IFolder parentFolder= project.getFolder(parentPath);
									if (!parentFolder.exists()) {
										CoreUtility.createFolder(parentFolder, true, true, new SubProgressMonitor(monitor, 1));
									} else {
										monitor.worked(1);
									}
								} else {
									monitor.worked(1);
								}
								orginalFolder.move(entry.getPath(), true, true, new SubProgressMonitor(monitor, 1));
							}
						} else {
							if (!folder.exists() || !entry.getLinkTarget().equals(entry.getOrginalLinkTarget())) {
								orginalFolder.delete(true, new SubProgressMonitor(monitor, 1));
								folder.createLink(entry.getLinkTarget(), IResource.ALLOW_MISSING_LOCAL, new SubProgressMonitor(monitor, 1));
							}
						}
					}
				} else {
					if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
						IPath path= entry.getPath();
						if (! path.equals(entry.getOrginalPath())) {
							String eeID= JavaRuntime.getExecutionEnvironmentId(path);
							if (eeID != null) {
								BuildPathSupport.setEEComplianceOptions(javaProject, eeID, newProjectCompliance);
								newProjectCompliance= null; // don't set it again below
							}
						}
						if (newProjectCompliance != null) {
							Map<String, String> options= javaProject.getOptions(false);
							JavaModelUtil.setComplianceOptions(options, newProjectCompliance);
							JavaModelUtil.setDefaultClassfileOptions(options, newProjectCompliance); // complete compliance options
							javaProject.setOptions(options);
						}
					}
					monitor.worked(3);
				}
				if (monitor.isCanceled()) {
					throw new OperationCanceledException();
				}
			}

			javaProject.setRawClasspath(classpath, outputLocation, new SubProgressMonitor(monitor, 2));
		} finally {
			monitor.done();
		}
	}

	public static boolean hasClassfiles(IResource resource) throws CoreException {
		if (resource.isDerived()) {
			return true;
		}
		if (resource instanceof IContainer) {
			for (IResource member : ((IContainer) resource).members()) {
				if (hasClassfiles(member)) {
					return true;
				}
			}
		}
		return false;
	}


	public static void removeOldClassfiles(IResource resource) throws CoreException {
		if (resource.isDerived()) {
			resource.delete(false, null);
		} else if (resource instanceof IContainer) {
			for (IResource member : ((IContainer) resource).members()) {
				removeOldClassfiles(member);
			}
		}
	}

	public static IRemoveOldBinariesQuery getRemoveOldBinariesQuery(final Shell shell) {
		return (removeFolder, oldOutputLocation) -> {
			final int[] res= new int[] { 1 };
			Display.getDefault().syncExec(() -> {
				Shell sh= shell != null ? shell : JavaPlugin.getActiveWorkbenchShell();
				String title= NewWizardMessages.BuildPathsBlock_RemoveBinariesDialog_title;
				String message;
				String pathLabel= BasicElementLabels.getPathLabel(oldOutputLocation, false);
				if (removeFolder) {
					message= Messages.format(NewWizardMessages.BuildPathsBlock_RemoveOldOutputFolder_description, pathLabel);
				} else {
					message= Messages.format(NewWizardMessages.BuildPathsBlock_RemoveBinariesDialog_description, pathLabel);
				}
				MessageDialog dialog= new MessageDialog(sh, title, null, message, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }, 0);
				res[0]= dialog.open();
			});
			if (res[0] == 0) {
				return true;
			} else if (res[0] == 1) {
				return false;
			}
			throw new OperationCanceledException();
		};
	}


	// ---------- util method ------------

	private IContainer chooseContainer() {
		Class<?>[] acceptedClasses= new Class[] { IProject.class, IFolder.class };
		ISelectionStatusValidator validator= new TypedElementSelectionValidator(acceptedClasses, false);
		IProject[] allProjects= fWorkspaceRoot.getProjects();
		ArrayList<IProject> rejectedElements= new ArrayList<>(allProjects.length);
		IProject currProject= fCurrJProject.getProject();
		for (IProject project : allProjects) {
			if (!project.equals(currProject)) {
				rejectedElements.add(project);
			}
		}
		ViewerFilter filter= new TypedViewerFilter(acceptedClasses, rejectedElements.toArray());

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

		IResource initSelection= null;
		if (fOutputLocationPath != null) {
			initSelection= fWorkspaceRoot.findMember(fOutputLocationPath);
		}

		FolderSelectionDialog dialog= new FolderSelectionDialog(getShell(), lp, cp);
		dialog.setTitle(NewWizardMessages.BuildPathsBlock_ChooseOutputFolderDialog_title);
		dialog.setValidator(validator);
		dialog.setMessage(NewWizardMessages.BuildPathsBlock_ChooseOutputFolderDialog_description);
		dialog.addFilter(filter);
		dialog.setInput(fWorkspaceRoot);
		dialog.setInitialSelection(initSelection);
		dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));

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

	// -------- tab switching ----------

	private void tabChanged(Widget widget) {
		if (widget instanceof TabItem) {
			TabItem tabItem= (TabItem) widget;
			BuildPathBasePage newPage= (BuildPathBasePage) tabItem.getData();
			if (fCurrPage != null) {
				List<?> selection= fCurrPage.getSelection();
				if (!selection.isEmpty()) {
					newPage.setSelection(selection, false);
				}
			}
			fCurrPage= newPage;
			fPageIndex= tabItem.getParent().getSelectionIndex();
		}
	}

	private int getPageIndex(int entryKind) {
		switch (entryKind) {
			case IClasspathEntry.CPE_CONTAINER:
			case IClasspathEntry.CPE_LIBRARY:
			case IClasspathEntry.CPE_VARIABLE:
				return 2;
			case IClasspathEntry.CPE_PROJECT:
				return 1;
			case IClasspathEntry.CPE_SOURCE:
				return 0;
		}
		return 0;
	}

	private CPListElement findElement(IClasspathEntry entry) {
		CPListElement prefixMatch= null;
		int entryKind= entry.getEntryKind();
		for (int i= 0, len= fClassPathList.getSize(); i < len; i++) {
			CPListElement curr= fClassPathList.getElement(i);
			if (curr.getEntryKind() == entryKind) {
				IPath entryPath= entry.getPath();
				IPath currPath= curr.getPath();
				if (currPath.equals(entryPath)) {
					return curr;
				}
				// in case there's no full match, look for a similar container (same ID segment):
				if (prefixMatch == null && entryKind == IClasspathEntry.CPE_CONTAINER) {
					int n= entryPath.segmentCount();
					if (n > 0) {
						IPath genericContainerPath= n == 1 ? entryPath : entryPath.removeLastSegments(n - 1);
						if (n > 1 && genericContainerPath.isPrefixOf(currPath)) {
							prefixMatch= curr;
						}
					}
				}
			}
		}
		return prefixMatch;
	}

	public void setElementToReveal(IClasspathEntry entry, String attributeKey) {
		int pageIndex= getPageIndex(entry.getEntryKind());
		if (fTabFolder == null) {
			fPageIndex= pageIndex;
		} else {
			fTabFolder.setSelection(pageIndex);
			CPListElement element= findElement(entry);
			if (element != null) {
				Object elementToSelect= element;

				if (attributeKey != null) {
					Object attrib= element.findAttributeElement(attributeKey);
					if (attrib != null) {
						elementToSelect= attrib;
					}
				}
				BuildPathBasePage page= (BuildPathBasePage) fTabFolder.getItem(pageIndex).getData();
				List<Object> selection= new ArrayList<>(1);
				selection.add(elementToSelect);
				page.setSelection(selection, true);
			}
		}
	}

	public void addElement(IClasspathEntry entry) {
		int pageIndex= getPageIndex(entry.getEntryKind());
		if (fTabFolder == null) {
			fPageIndex= pageIndex;
		} else {
			fTabFolder.setSelection(pageIndex);

			Object page=  fTabFolder.getItem(pageIndex).getData();
			if (page instanceof LibrariesWorkbookPage) {
				CPListElement element= CPListElement.create(entry, true, fCurrJProject);
				((LibrariesWorkbookPage) page).addElement(element);
			}
		}
	}

	public void dispose() {
		if (fSourceContainerPage instanceof NewSourceContainerWorkbookPage) {
			((NewSourceContainerWorkbookPage)fSourceContainerPage).dispose();
			fSourceContainerPage= null;
		}
    }

	public boolean isOKStatus() {
	    return findMostSevereStatus().isOK();
    }

	public void setFocus() {
		fSourceContainerPage.setFocus();
    }

	public BuildPathBasePage getSourceContainerPage() {
		return fSourceContainerPage;
	}
}
