/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     James Blackburn (Broadcom Corp.) Bug 86973 Allow path pattern matching
 *     Anton Leherbauer (Wind River Systems, Inc.) - Bug 415099 Terminating with "<" or " " (space) does not work for extensions
 *     Mickael Istria (Red Hat Inc.) - Bug 460749: filter resources with same location
 *******************************************************************************/
package org.eclipse.ui.dialogs;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
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.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ResourceWorkingSetFilter;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.actions.WorkingSetFilterActionGroup;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
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.model.ResourceFactory;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.statushandlers.StatusManager;

import com.ibm.icu.text.Collator;

/**
 * Shows a list of resources to the user with a text entry field for a string
 * pattern used to filter the list of resources.
 *
 * @since 3.3
 */
public class FilteredResourcesSelectionDialog extends
		FilteredItemsSelectionDialog {

	private static final String DIALOG_SETTINGS = "org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog"; //$NON-NLS-1$

	private static final String WORKINGS_SET_SETTINGS = "WorkingSet"; //$NON-NLS-1$

	private static final String SHOW_DERIVED = "ShowDerived"; //$NON-NLS-1$
	private static final String FILTER_BY_LOCATION = "FilterByLocation"; //$NON-NLS-1$

	private ShowDerivedResourcesAction showDerivedResourcesAction;

	private ResourceItemLabelProvider resourceItemLabelProvider;

	private ResourceItemDetailsLabelProvider resourceItemDetailsLabelProvider;

	private WorkingSetFilterActionGroup workingSetFilterActionGroup;

	private CustomWorkingSetFilter workingSetFilter = new CustomWorkingSetFilter();

	private FilterResourcesByLocation filterResourceByLocation = new FilterResourcesByLocation();
	private GroupResourcesByLocationAction groupResourcesByLocationAction;

	private String title;

	/**
	 * The base outer-container which will be used to search for resources. This
	 * is the root of the tree that spans the search space. Often, this is the
	 * workspace root.
	 */
	private IContainer container;

	/**
	 * The container to use as starting point for relative search, or
	 * <code>null</code> if none.
	 * @since 3.6
	 */
	private IContainer searchContainer;

	private int typeMask;

	private boolean isDerived;

	/**
	 * Creates a new instance of the class
	 *
	 * @param shell
	 *            the parent shell
	 * @param multi
	 *            the multi selection flag
	 * @param container
	 *            the container to select resources from, e.g. the workspace root
	 * @param typesMask
	 *            a mask specifying which resource types should be shown in the dialog.
	 *            The mask should contain one or more of the resource type bit masks
	 *            defined in {@link IResource#getType()}
	 */
	public FilteredResourcesSelectionDialog(Shell shell, boolean multi,
			IContainer container, int typesMask) {
		super(shell, multi);

		setSelectionHistory(new ResourceSelectionHistory());

		setTitle(IDEWorkbenchMessages.OpenResourceDialog_title);
		setMessage(IDEWorkbenchMessages.OpenResourceDialog_message);

		/*
		 * Allow location of paths relative to a searchContainer, which is
		 * initialized from the active editor or the selected element.
		 */
		IWorkbenchWindow ww = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		if (ww != null) {
			IWorkbenchPage activePage = ww.getActivePage();
			if (activePage != null) {
				IResource resource = null;
				IEditorPart activeEditor = activePage.getActiveEditor();
				if (activeEditor != null && activeEditor == activePage.getActivePart()) {
					IEditorInput editorInput = activeEditor.getEditorInput();
					resource = ResourceUtil.getResource(editorInput);
				} else {
					ISelection selection = ww.getSelectionService().getSelection();
					if (selection instanceof IStructuredSelection) {
						IStructuredSelection structuredSelection = (IStructuredSelection) selection;
						if (structuredSelection.size() == 1) {
							resource = ResourceUtil.getResource(structuredSelection.getFirstElement());
						}
					}
				}
				if (resource != null) {
					if (!(resource instanceof IContainer)) {
						resource = resource.getParent();
					}
					searchContainer = (IContainer) resource;
				}
			}
		}

		this.container = container;
		this.typeMask = typesMask;

		resourceItemLabelProvider = new ResourceItemLabelProvider();

		resourceItemDetailsLabelProvider = new ResourceItemDetailsLabelProvider();

		setListLabelProvider(resourceItemLabelProvider);
		setDetailsLabelProvider(resourceItemDetailsLabelProvider);
	}

	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IIDEHelpContextIds.OPEN_RESOURCE_DIALOG);
	}

	@Override
	public void setTitle(String title) {
		super.setTitle(title);
		this.title = title;
	}

	/**
	 * Adds or replaces subtitle of the dialog
	 *
	 * @param text
	 *            the new subtitle
	 */
	private void setSubtitle(String text) {
		if (text == null || text.length() == 0) {
			getShell().setText(title);
		} else {
			getShell().setText(title + " - " + text); //$NON-NLS-1$
		}
	}

	@Override
	protected IDialogSettings getDialogSettings() {
		IDialogSettings settings = IDEWorkbenchPlugin.getDefault()
				.getDialogSettings().getSection(DIALOG_SETTINGS);

		if (settings == null) {
			settings = IDEWorkbenchPlugin.getDefault().getDialogSettings()
					.addNewSection(DIALOG_SETTINGS);
		}

		return settings;
	}

	@Override
	protected void storeDialog(IDialogSettings settings) {
		super.storeDialog(settings);

		settings.put(SHOW_DERIVED, showDerivedResourcesAction.isChecked());
		settings.put(FILTER_BY_LOCATION, this.groupResourcesByLocationAction.isChecked());

		XMLMemento memento = XMLMemento.createWriteRoot("workingSet"); //$NON-NLS-1$
		workingSetFilterActionGroup.saveState(memento);
		workingSetFilterActionGroup.dispose();
		StringWriter writer = new StringWriter();
		try {
			memento.save(writer);
			settings.put(WORKINGS_SET_SETTINGS, writer.getBuffer().toString());
		} catch (IOException e) {
			StatusManager.getManager().handle(
					new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH,
							IStatus.ERROR, "", e)); //$NON-NLS-1$
			// don't do anything. Simply don't store the settings
		}
	}

	@Override
	protected void restoreDialog(IDialogSettings settings) {
		super.restoreDialog(settings);

		boolean showDerived = settings.getBoolean(SHOW_DERIVED);
		showDerivedResourcesAction.setChecked(showDerived);
		this.isDerived = showDerived;

		boolean groupByLoation = settings.getBoolean(FILTER_BY_LOCATION);
		this.groupResourcesByLocationAction.setChecked(groupByLoation);
		this.filterResourceByLocation.setEnabled(groupByLoation);
		addListFilter(this.filterResourceByLocation);

		String setting = settings.get(WORKINGS_SET_SETTINGS);
		if (setting != null) {
			try {
				IMemento memento = XMLMemento.createReadRoot(new StringReader(
						setting));
				workingSetFilterActionGroup.restoreState(memento);
			} catch (WorkbenchException e) {
				StatusManager.getManager().handle(
						new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH,
								IStatus.ERROR, "", e)); //$NON-NLS-1$
				// don't do anything. Simply don't restore the settings
			}
		}

		addListFilter(workingSetFilter);

		applyFilter();
	}

	@Override
	protected void fillViewMenu(IMenuManager menuManager) {
		super.fillViewMenu(menuManager);

		showDerivedResourcesAction = new ShowDerivedResourcesAction();
		menuManager.add(showDerivedResourcesAction);
		this.groupResourcesByLocationAction = new GroupResourcesByLocationAction();
		menuManager.add(this.groupResourcesByLocationAction);

		workingSetFilterActionGroup = new WorkingSetFilterActionGroup(
				getShell(), event -> {
					String property = event.getProperty();

					if (WorkingSetFilterActionGroup.CHANGE_WORKING_SET
							.equals(property)) {

						IWorkingSet workingSet = (IWorkingSet) event
								.getNewValue();

						if (workingSet != null
								&& !(workingSet.isAggregateWorkingSet() && workingSet
										.isEmpty())) {
							workingSetFilter.setWorkingSet(workingSet);
							setSubtitle(workingSet.getLabel());
						} else {
							IWorkbenchWindow window = PlatformUI
									.getWorkbench()
									.getActiveWorkbenchWindow();

							if (window != null) {
								IWorkbenchPage page = window
										.getActivePage();
								workingSet = page.getAggregateWorkingSet();

								if (workingSet.isAggregateWorkingSet()
										&& workingSet.isEmpty()) {
									workingSet = null;
								}
							}

							workingSetFilter.setWorkingSet(workingSet);
							setSubtitle(null);
						}

						scheduleRefresh();
					}
				});

		menuManager.add(new Separator());
		workingSetFilterActionGroup.fillContextMenu(menuManager);
	}

	@Override
	protected Control createExtendedContentArea(Composite parent) {
		return null;
	}

	@Override
	public Object[] getResult() {
		Object[] result = super.getResult();

		if (result == null)
			return null;

		List resultToReturn = new ArrayList();

		for (Object element : result) {
			if (element instanceof IResource) {
				resultToReturn.add((element));
			}
		}

		return resultToReturn.toArray();
	}

	@Override
	public int open() {
		if (getInitialPattern() == null) {
			IWorkbenchWindow window = PlatformUI.getWorkbench()
					.getActiveWorkbenchWindow();
			if (window != null) {
				ISelection selection = window.getSelectionService()
						.getSelection();
				if (selection instanceof ITextSelection) {
					String text = ((ITextSelection) selection).getText();
					if (text != null) {
						text = text.trim();
						if (text.length() > 0) {
							IWorkspace workspace = ResourcesPlugin
									.getWorkspace();
							IStatus result = workspace.validateName(text,
									IResource.FILE);
							if (result.isOK()) {
								setInitialPattern(text);
							}
						}
					}
				}
			}
		}
		return super.open();
	}

	@Override
	public String getElementName(Object item) {
		IResource resource = (IResource) item;
		return resource.getName();
	}

	@Override
	protected IStatus validateItem(Object item) {
		return new Status(IStatus.OK, WorkbenchPlugin.PI_WORKBENCH, 0, "", null); //$NON-NLS-1$
	}

	@Override
	protected ItemsFilter createFilter() {
		return new ResourceFilter(container, searchContainer, isDerived, typeMask);
	}

	@Override
	protected void applyFilter() {
		super.applyFilter();
	}

	@Override
	protected Comparator getItemsComparator() {
		return (o1, o2) -> {
			Collator collator = Collator.getInstance();
			IResource resource1 = (IResource) o1;
			IResource resource2 = (IResource) o2;
			String s1 = resource1.getName();
			String s2 = resource2.getName();

			// Compare names without extension first
			int s1Dot = s1.lastIndexOf('.');
			int s2Dot = s2.lastIndexOf('.');
			String n1 = s1Dot == -1 ? s1 : s1.substring(0, s1Dot);
			String n2 = s2Dot == -1 ? s2 : s2.substring(0, s2Dot);
			int comparability = collator.compare(n1, n2);
			if (comparability != 0)
				return comparability;

			// Compare full names
			if (s1Dot != -1 || s2Dot != -1) {
				comparability = collator.compare(s1, s2);
				if (comparability != 0)
					return comparability;
			}

			// Search for resource relative paths
			if (searchContainer != null) {
				IContainer c11 = resource1.getParent();
				IContainer c21 = resource2.getParent();

				// Return paths 'closer' to the searchContainer first
				comparability = pathDistance(c11) - pathDistance(c21);
				if (comparability != 0)
					return comparability;
			}

			// Finally compare full path segments
			IPath p1 = resource1.getFullPath();
			IPath p2 = resource2.getFullPath();
			// Don't compare file names again, so subtract 1
			int c12 = p1.segmentCount() - 1;
			int c22 = p2.segmentCount() - 1;
			for (int i= 0; i < c12 && i < c22; i++) {
				comparability = collator.compare(p1.segment(i), p2.segment(i));
				if (comparability != 0)
					return comparability;
			}
			comparability = c12 - c22;

			return comparability;
		};
	}

	/**
	 * Return the "distance" of the item from the root of the relative search
	 * container. Distances can be compared (smaller numbers are better).
	 * <br>
	 * - Closest distance is if the item is the same folder as the search container.<br>
	 * - Next are folders inside the search container.<br>
	 * - After all those, distance increases with decreasing matching prefix folder count.<br>
	 *
	 * @param item
	 *            parent of the resource being examined
	 * @return the "distance" of the passed in IResource from the search
	 *         container
	 * @since 3.6
	 */
	private int pathDistance(IContainer item) {
		// Container search path: e.g. /a/b/c
		IPath containerPath = searchContainer.getFullPath();
		// itemPath:          distance:
		// /a/b/c         ==> 0
		// /a/b/c/d/e     ==> 2
		// /a/b           ==> Integer.MAX_VALUE/4 + 1
		// /a/x/e/f       ==> Integer.MAX_VALUE/4 + 2
		// /g/h           ==> Integer.MAX_VALUE/2
		IPath itemPath = item.getFullPath();
		if (itemPath.equals(containerPath))
			return 0;

		int matching = containerPath.matchingFirstSegments(itemPath);
		if (matching == 0)
			return Integer.MAX_VALUE / 2;

		int containerSegmentCount = containerPath.segmentCount();
		if (matching == containerSegmentCount) {
			// inside searchContainer:
			return itemPath.segmentCount() - matching;
		}

		//outside searchContainer:
		return Integer.MAX_VALUE / 4 + containerSegmentCount - matching;
	}

	@Override
	protected void fillContentProvider(AbstractContentProvider contentProvider,
			ItemsFilter itemsFilter, IProgressMonitor progressMonitor)
			throws CoreException {
		if (itemsFilter instanceof ResourceFilter) {
			IResource[] members = container.members();
			progressMonitor
					.beginTask(
							WorkbenchMessages.FilteredItemsSelectionDialog_searchJob_taskName,
							members.length);

			ResourceProxyVisitor visitor = new ResourceProxyVisitor(
					contentProvider, (ResourceFilter) itemsFilter,
					progressMonitor);

			if (visitor.visit(container.createProxy())) {
				for (IResource member : members) {
					if (member.isAccessible())
						member.accept(visitor, IResource.NONE);
					progressMonitor.worked(1);
					if (progressMonitor.isCanceled())
						break;
				}
			}

		}
		progressMonitor.done();
	}

	/**
	 * Sets the derived flag on the ResourceFilter instance
	 */
	private class ShowDerivedResourcesAction extends Action {

		/**
		 * Creates a new instance of the action.
		 */
		public ShowDerivedResourcesAction() {
			super(
					IDEWorkbenchMessages.FilteredResourcesSelectionDialog_showDerivedResourcesAction,
					IAction.AS_CHECK_BOX);
		}

		@Override
		public void run() {
			FilteredResourcesSelectionDialog.this.isDerived = isChecked();
			applyFilter();
		}
	}

	/**
	 * Sets the groupByLocation flag on the FilterResourceByLocation instance
	 */
	private class GroupResourcesByLocationAction extends Action {

		/**
		 * Creates a new instance of the action.
		 */
		public GroupResourcesByLocationAction() {
			super(IDEWorkbenchMessages.FilteredResourcesSelectionDialog_groupResourcesWithSameUndelyingLocation,
					IAction.AS_CHECK_BOX);
		}

		@Override
		public void run() {
			FilteredResourcesSelectionDialog.this.filterResourceByLocation.setEnabled(isChecked());
			scheduleRefresh();
			applyFilter();
		}
	}

	/**
	 * A label provider for ResourceDecorator objects. It creates labels with a
	 * resource full path for duplicates. It uses the Platform UI label
	 * decorator for providing extra resource info.
	 */
	private class ResourceItemLabelProvider extends LabelProvider implements
			ILabelProviderListener, IStyledLabelProvider {

		// Need to keep our own list of listeners
		private ListenerList listeners = new ListenerList();

		WorkbenchLabelProvider provider = new WorkbenchLabelProvider();

		/**
		 * Creates a new instance of the class
		 */
		public ResourceItemLabelProvider() {
			super();
			provider.addListener(this);
		}

		@Override
		public Image getImage(Object element) {
			if (!(element instanceof IResource)) {
				return super.getImage(element);
			}

			IResource res = (IResource) element;

			return provider.getImage(res);
		}

		@Override
		public String getText(Object element) {
			if (!(element instanceof IResource)) {
				return super.getText(element);
			}

			IResource res = (IResource) element;

			String str = res.getName();

			// extra info for duplicates
			if (isDuplicateElement(element))
				str = str
						+ " - " + res.getParent().getFullPath().makeRelative().toString(); //$NON-NLS-1$

			return str;
		}

		@Override
		public StyledString getStyledText(Object element) {
			if (!(element instanceof IResource)) {
				return new StyledString(super.getText(element));
			}

			IResource res = (IResource) element;

			StyledString str = new StyledString(res.getName());

			// extra info for duplicates
			if (isDuplicateElement(element)) {
				str.append(" - ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
				str.append(res.getParent().getFullPath().makeRelative().toString(), StyledString.QUALIFIER_STYLER);
			}

//Debugging:
//			int pathDistance = pathDistance(res.getParent());
//			if (pathDistance != Integer.MAX_VALUE / 2) {
//				if (pathDistance > Integer.MAX_VALUE / 4)
//					str.append(" (" + (pathDistance - Integer.MAX_VALUE / 4) + " folders up from current selection)", StyledString.QUALIFIER_STYLER);
//				else
//					str.append(" (" + pathDistance + " folders down from current selection)", StyledString.QUALIFIER_STYLER);
//			}

			return str;
		}

		@Override
		public void dispose() {
			provider.removeListener(this);
			provider.dispose();

			super.dispose();
		}

		@Override
		public void addListener(ILabelProviderListener listener) {
			listeners.add(listener);
		}

		@Override
		public void removeListener(ILabelProviderListener listener) {
			listeners.remove(listener);
		}

		@Override
		public void labelProviderChanged(LabelProviderChangedEvent event) {
			Object[] l = listeners.getListeners();
			for (int i = 0; i < listeners.size(); i++) {
				((ILabelProviderListener) l[i]).labelProviderChanged(event);
			}
		}

	}

	/**
	 * A label provider for details of ResourceItem objects.
	 */
	private class ResourceItemDetailsLabelProvider extends
			ResourceItemLabelProvider {
		@Override
		public Image getImage(Object element) {
			if (!(element instanceof IResource)) {
				return super.getImage(element);
			}

			IResource parent = ((IResource) element).getParent();
			return provider.getImage(parent);
		}

		@Override
		public String getText(Object element) {
			if (!(element instanceof IResource)) {
				return super.getText(element);
			}

			IResource parent = ((IResource) element).getParent();

			if (parent.getType() == IResource.ROOT) {
				// Get readable name for workspace root ("Workspace"), without
				// duplicating language-specific string here.
				return null;
			}

			return parent.getFullPath()	.makeRelative().toString();
		}

		@Override
		public void labelProviderChanged(LabelProviderChangedEvent event) {
			Object[] l = super.listeners.getListeners();
			for (int i = 0; i < super.listeners.size(); i++) {
				((ILabelProviderListener) l[i]).labelProviderChanged(event);
			}
		}
	}

	/**
	 * Viewer filter which filters resources due to current working set
	 */
	private class CustomWorkingSetFilter extends ViewerFilter {
		private ResourceWorkingSetFilter resourceWorkingSetFilter = new ResourceWorkingSetFilter();

		/**
		 * Sets the active working set.
		 *
		 * @param workingSet
		 *            the working set the filter should work with
		 */
		public void setWorkingSet(IWorkingSet workingSet) {
			resourceWorkingSetFilter.setWorkingSet(workingSet);
		}

		@Override
		public boolean select(Viewer viewer, Object parentElement,
				Object element) {
			return resourceWorkingSetFilter.select(viewer, parentElement,
						element);
		}
	}

	/**
	 * ResourceProxyVisitor to visit resource tree and get matched resources.
	 * During visit resources it updates progress monitor and adds matched
	 * resources to ContentProvider instance.
	 */
	private class ResourceProxyVisitor implements IResourceProxyVisitor {

		private AbstractContentProvider proxyContentProvider;

		private ResourceFilter resourceFilter;

		private IProgressMonitor progressMonitor;

		/**
		 * Creates new ResourceProxyVisitor instance.
		 *
		 * @param contentProvider
		 * @param resourceFilter
		 * @param progressMonitor
		 * @throws CoreException
		 */
		public ResourceProxyVisitor(AbstractContentProvider contentProvider,
				ResourceFilter resourceFilter, IProgressMonitor progressMonitor)
				throws CoreException {
			super();
			this.proxyContentProvider = contentProvider;
			this.resourceFilter = resourceFilter;
			this.progressMonitor = progressMonitor;
		}

		@Override
		public boolean visit(IResourceProxy proxy) {

			if (progressMonitor.isCanceled())
				return false;

			IResource resource = proxy.requestResource();

			proxyContentProvider.add(resource, resourceFilter);

			if (resource.getType() == IResource.FOLDER && resource.isDerived()
					&& !resourceFilter.isShowDerived()) {

				return false;
			}

			if (resource.getType() == IResource.FILE) {
				return false;
			}

			return true;
		}
	}

	/**
	 * Filters resources using pattern and showDerived flag. It overrides
	 * ItemsFilter.
	 */
	protected class ResourceFilter extends ItemsFilter {

		private boolean showDerived = false;

		private IContainer filterContainer;

		/**
		 * Container path pattern. Is <code>null</code> when only a file name pattern is used.
		 * @since 3.6
		 */
		private SearchPattern containerPattern;
		/**
		 * Container path pattern, relative to the current searchContainer. Is <code>null</code> if there's no search container.
		 * @since 3.6
		 */
		private SearchPattern relativeContainerPattern;

		/**
		 * Camel case pattern for the name part of the file name (without extension). Is <code>null</code> if there's no extension.
		 * @since 3.6
		 */
		SearchPattern namePattern;
		/**
		 * Camel case pattern for the file extension. Is <code>null</code> if there's no extension.
		 * @since 3.6
		 */
		SearchPattern extensionPattern;

		private int filterTypeMask;

		/**
		 * Creates new ResourceFilter instance
		 *
		 * @param container
		 * @param showDerived
		 *            flag which determine showing derived elements
		 * @param typeMask
		 */
		public ResourceFilter(IContainer container, boolean showDerived,
				int typeMask) {
			super();
			this.filterContainer = container;
			this.showDerived = showDerived;
			this.filterTypeMask = typeMask;
		}

		/**
		 * Creates new ResourceFilter instance
		 *
		 * @param container
		 * @param searchContainer
		 *            IContainer to use for performing relative search
		 * @param showDerived
		 *            flag which determine showing derived elements
		 * @param typeMask
		 * @since 3.6
		 */
		private ResourceFilter(IContainer container, IContainer searchContainer, boolean showDerived, int typeMask) {
			this(container, showDerived, typeMask);

			String stringPattern = getPattern();
			int matchRule = getMatchRule();
			String filenamePattern;

			int sep = stringPattern.lastIndexOf(IPath.SEPARATOR);
			if (sep != -1) {
				filenamePattern = stringPattern.substring(sep + 1, stringPattern.length());
				if ("*".equals(filenamePattern)) //$NON-NLS-1$
					filenamePattern= "**"; //$NON-NLS-1$

				if (sep > 0) {
					if (filenamePattern.length() == 0) // relative patterns don't need a file name
						filenamePattern= "**"; //$NON-NLS-1$

					String containerPattern = stringPattern.substring(0, sep);

					if (searchContainer != null) {
						relativeContainerPattern = new SearchPattern(SearchPattern.RULE_EXACT_MATCH | SearchPattern.RULE_PATTERN_MATCH);
						relativeContainerPattern.setPattern(searchContainer.getFullPath().append(containerPattern).toString());
					}

					if (!containerPattern.startsWith("" + IPath.SEPARATOR)) //$NON-NLS-1$
						containerPattern = IPath.SEPARATOR + containerPattern;
					this.containerPattern= new SearchPattern(SearchPattern.RULE_EXACT_MATCH | SearchPattern.RULE_PREFIX_MATCH | SearchPattern.RULE_PATTERN_MATCH);
					this.containerPattern.setPattern(containerPattern);
				}
				boolean isPrefixPattern = matchRule == SearchPattern.RULE_PREFIX_MATCH
						|| (matchRule == SearchPattern.RULE_PATTERN_MATCH && filenamePattern.endsWith("*")); //$NON-NLS-1$
				if (!isPrefixPattern)
					// Add '<' again as it was removed by SearchPattern
					filenamePattern += '<';
				else if (filenamePattern.endsWith("*") && !filenamePattern.equals("**")) //$NON-NLS-1$ //$NON-NLS-2$
					// Remove added '*' as the filename pattern might be a camel case pattern
					filenamePattern = filenamePattern.substring(0, filenamePattern.length() - 1);
				patternMatcher.setPattern(filenamePattern);
				// Update filenamePattern and matchRule as they might have changed
				filenamePattern = getPattern();
				matchRule = getMatchRule();
			} else {
				filenamePattern= stringPattern;
			}

			int lastPatternDot = filenamePattern.lastIndexOf('.');
			if (lastPatternDot != -1) {
				if (matchRule != SearchPattern.RULE_EXACT_MATCH) {
					namePattern = new SearchPattern();
					namePattern.setPattern(filenamePattern.substring(0, lastPatternDot));
					String extensionPatternStr = filenamePattern.substring(lastPatternDot + 1);
					// Add a '<' except this is a camel case pattern or a prefix pattern
					if (matchRule != SearchPattern.RULE_CAMELCASE_MATCH
							&& matchRule != SearchPattern.RULE_PREFIX_MATCH
							&& !extensionPatternStr.endsWith("*")) //$NON-NLS-1$
						extensionPatternStr += '<';
					extensionPattern = new SearchPattern();
					extensionPattern.setPattern(extensionPatternStr);
				}
			}

		}

		/**
		 * Creates new ResourceFilter instance
		 */
		public ResourceFilter() {
			this(container, searchContainer, isDerived, typeMask);
		}

		/**
		 * @param item
		 *            Must be instance of IResource, otherwise
		 *            <code>false</code> will be returned.
		 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#isConsistentItem(java.lang.Object)
		 */
		@Override
		public boolean isConsistentItem(Object item) {
			if (!(item instanceof IResource)) {
				return false;
			}
			IResource resource = (IResource) item;
			if (this.filterContainer.findMember(resource.getFullPath()) != null)
				return true;
			return false;
		}

		/**
		 * @param item
		 *            Must be instance of IResource, otherwise
		 *            <code>false</code> will be returned.
		 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog.ItemsFilter#matchItem(java.lang.Object)
		 */
		@Override
		public boolean matchItem(Object item) {
			if (!(item instanceof IResource)) {
				return false;
			}
			IResource resource = (IResource) item;
			return (this.filterTypeMask & resource.getType()) != 0
					&& matchName(resource)
					&& (this.showDerived || !resource.isDerived());
		}

		private boolean matchName(IResource resource) {
			String name = resource.getName();
			if (nameMatches(name)) {
				if (containerPattern != null) {
					// match full container path:
					String containerPath = resource.getParent().getFullPath().toString();
					if (containerPattern.matches(containerPath))
						return true;
					// match path relative to current selection:
					if (relativeContainerPattern != null)
						return relativeContainerPattern.matches(containerPath);
					return false;
				}
				return true;
			}

			return false;
		}

		private boolean nameMatches(String name) {
			if (namePattern != null) {
				// fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212565
				int lastDot = name.lastIndexOf('.');
				if (lastDot != -1
						&& namePattern.matches(name.substring(0, lastDot))
						&& extensionPattern.matches(name.substring(lastDot + 1))) {
					return true;
				}
			}
			return matches(name);
		}

		@Override
		public boolean isSubFilter(ItemsFilter filter) {
			if (!super.isSubFilter(filter))
				return false;
			if (filter instanceof ResourceFilter) {
				ResourceFilter resourceFilter = (ResourceFilter) filter;
				if (this.showDerived == resourceFilter.showDerived) {
					if (containerPattern == null) {
						return resourceFilter.containerPattern == null;
					} else if (resourceFilter.containerPattern == null) {
						return false;
					} else {
						return containerPattern.equals(resourceFilter.containerPattern);
					}
				}
			}
			return false;
		}

		@Override
		public boolean equalsFilter(ItemsFilter iFilter) {
			if (!super.equalsFilter(iFilter))
				return false;
			if (iFilter instanceof ResourceFilter) {
				ResourceFilter resourceFilter = (ResourceFilter) iFilter;
				if (this.showDerived == resourceFilter.showDerived) {
					if (containerPattern == null) {
						return resourceFilter.containerPattern == null;
					} else if (resourceFilter.containerPattern == null) {
						return false;
					} else {
						return containerPattern.equals(resourceFilter.containerPattern);
					}
				}
			}
			return false;
		}

		/**
		 * Check show derived flag for a filter
		 *
		 * @return true if filter allow derived resources false if not
		 */
		public boolean isShowDerived() {
			return showDerived;
		}

	}

	private class FilterResourcesByLocation extends ViewerFilter {

		private boolean enabled;

		public void setEnabled(boolean enabled) {
			this.enabled = enabled;
		}

		@Override
		public Object[] filter(Viewer viewer, Object parent, Object[] elements) {
			if (!this.enabled) {
				return elements;
			}
			Map<IPath, IResource> bestResourceForPath = new LinkedHashMap<>();
			for (Object item : elements) {
				if (item instanceof IResource) {
					IResource currentResource = (IResource) item;
					IResource otherResource = bestResourceForPath.get(currentResource.getLocation());
					if (otherResource == null || otherResource.getFullPath().segmentCount() > currentResource
							.getFullPath().segmentCount()) {
						bestResourceForPath.put(currentResource.getLocation(), currentResource);
					}
				}
			}
			return bestResourceForPath.values().toArray(new IResource[bestResourceForPath.size()]);
		}

		@Override
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			// shouldn't be called, but err on the side of caution
			return true;
		}

	}

	/**
	 * <code>ResourceSelectionHistory</code> provides behavior specific to
	 * resources - storing and restoring <code>IResource</code>s state
	 * to/from XML (memento).
	 */
	private class ResourceSelectionHistory extends SelectionHistory {

		@Override
		protected Object restoreItemFromMemento(IMemento element) {
			ResourceFactory resourceFactory = new ResourceFactory();
			IResource resource = (IResource) resourceFactory
					.createElement(element);
			return resource;
		}

		@Override
		protected void storeItemToMemento(Object item, IMemento element) {
			IResource resource = (IResource) item;
			ResourceFactory resourceFactory = new ResourceFactory(resource);
			resourceFactory.saveState(element);
		}

	}

}
