/*******************************************************************************
 *  Copyright (c) 2000, 2017 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
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 487943
 *     Martin Karpisek <martin.karpisek@gmail.com> - Bug 351356
 *******************************************************************************/
package org.eclipse.pde.internal.ui.editor.plugin;

import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;

import java.util.ArrayList;
import java.util.HashSet;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.Window;
import org.eclipse.pde.core.*;
import org.eclipse.pde.core.build.*;
import org.eclipse.pde.core.plugin.*;
import org.eclipse.pde.internal.build.IBuildPropertiesConstants;
import org.eclipse.pde.internal.core.ClasspathUtilCore;
import org.eclipse.pde.internal.core.bundle.BundlePluginBase;
import org.eclipse.pde.internal.core.plugin.PluginLibrary;
import org.eclipse.pde.internal.core.project.PDEProject;
import org.eclipse.pde.internal.ui.*;
import org.eclipse.pde.internal.ui.editor.*;
import org.eclipse.pde.internal.ui.editor.build.*;
import org.eclipse.pde.internal.ui.editor.context.InputContextManager;
import org.eclipse.pde.internal.ui.parts.EditableTablePart;
import org.eclipse.pde.internal.ui.parts.TablePart;
import org.eclipse.pde.internal.ui.util.SWTUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.forms.editor.IFormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceComparator;

public class LibrarySection extends TableSection implements IBuildPropertiesConstants {

	private static final int NEW_INDEX = 0;
	private static final int ADD_INDEX = 1;
	private static final int REMOVE_INDEX = 2;
	private static final int UP_INDEX = 3;
	private static final int DOWN_INDEX = 4;

	private Action fRenameAction;
	private Action fRemoveAction;
	private Action fNewAction;

	private TableViewer fLibraryTable;

	class LibraryFilter extends JARFileFilter {
		public LibraryFilter(HashSet<IPath> set) {
			super(set);
		}

		@Override
		public boolean select(Viewer viewer, Object parent, Object element) {
			if (element instanceof IFolder)
				return isPathValid(((IFolder) element).getProjectRelativePath());
			if (element instanceof IFile)
				return isFileValid(((IFile) element).getProjectRelativePath());
			return false;
		}
	}

	class LibrarySelectionValidator extends JarSelectionValidator {

		public LibrarySelectionValidator(Class<?>[] acceptedTypes, boolean allowMultipleSelection) {
			super(acceptedTypes, allowMultipleSelection);
		}

		@Override
		public boolean isValid(Object element) {
			return (element instanceof IFolder) ? true : super.isValid(element);
		}
	}

	class TableContentProvider implements IStructuredContentProvider {
		@Override
		public Object[] getElements(Object parent) {
			return getModel().getPluginBase().getLibraries();
		}
	}

	public LibrarySection(PDEFormPage page, Composite parent) {
		super(page, parent, Section.DESCRIPTION, new String[] {PDEUIMessages.NewManifestEditor_LibrarySection_new, PDEUIMessages.NewManifestEditor_LibrarySection_add, PDEUIMessages.NewManifestEditor_LibrarySection_remove, PDEUIMessages.ManifestEditor_LibrarySection_up, PDEUIMessages.ManifestEditor_LibrarySection_down});
	}

	private String getSectionDescription() {
		IPluginModelBase model = getModel();
		if (isBundle()) {
			return (model.isFragmentModel()) ? PDEUIMessages.ClasspathSection_fragment : PDEUIMessages.ClasspathSection_plugin;
		}
		return (model.isFragmentModel()) ? PDEUIMessages.ManifestEditor_LibrarySection_fdesc : PDEUIMessages.ManifestEditor_LibrarySection_desc;
	}

	protected boolean isBundle() {
		return getBundleContext() != null;
	}

	private BundleInputContext getBundleContext() {
		InputContextManager manager = getPage().getPDEEditor().getContextManager();
		return (BundleInputContext) manager.findContext(BundleInputContext.CONTEXT_ID);
	}

	@Override
	public void createClient(Section section, FormToolkit toolkit) {
		section.setText(PDEUIMessages.ManifestEditor_LibrarySection_title);
		section.setDescription(getSectionDescription());

		Composite container = createClientContainer(section, 2, toolkit);
		EditableTablePart tablePart = getTablePart();
		tablePart.setEditable(isEditable());

		createViewerPartControl(container, SWT.MULTI, 2, toolkit);
		fLibraryTable = tablePart.getTableViewer();
		fLibraryTable.setContentProvider(new TableContentProvider());
		fLibraryTable.setLabelProvider(PDEPlugin.getDefault().getLabelProvider());
		toolkit.paintBordersFor(container);

		makeActions();
		updateButtons();
		section.setLayout(FormLayoutFactory.createClearGridLayout(false, 1));
		section.setLayoutData(new GridData(GridData.FILL_BOTH));
		section.setClient(container);

		IPluginModelBase model = getModel();
		fLibraryTable.setInput(model.getPluginBase());
		model.addModelChangedListener(this);
	}

	private void updateButtons() {
		Table table = fLibraryTable.getTable();
		boolean hasSelection = table.getSelection().length > 0;
		boolean singleSelection = table.getSelection().length == 1;
		int count = table.getItemCount();
		int index = table.getSelectionIndex();
		boolean canMoveUp = singleSelection && index > 0;
		boolean canMoveDown = singleSelection && index < count - 1;

		TablePart tablePart = getTablePart();
		tablePart.setButtonEnabled(ADD_INDEX, isEditable());
		tablePart.setButtonEnabled(NEW_INDEX, isEditable());
		tablePart.setButtonEnabled(REMOVE_INDEX, isEditable() && hasSelection);
		tablePart.setButtonEnabled(UP_INDEX, isEditable() && canMoveUp);
		tablePart.setButtonEnabled(DOWN_INDEX, isEditable() && canMoveDown);
	}

	private void makeActions() {
		fNewAction = new Action(PDEUIMessages.ManifestEditor_LibrarySection_newLibrary) {
			@Override
			public void run() {
				handleNew();
			}
		};
		fNewAction.setEnabled(isEditable());

		fRenameAction = new Action(PDEUIMessages.EditableTablePart_renameAction) {
			@Override
			public void run() {
				getRenameAction().run();
			}
		};
		fRenameAction.setEnabled(isEditable());

		fRemoveAction = new Action(PDEUIMessages.NewManifestEditor_LibrarySection_remove) {
			@Override
			public void run() {
				handleRemove();
			}
		};
		fRemoveAction.setEnabled(isEditable());
	}

	@Override
	protected void selectionChanged(IStructuredSelection selection) {
		getPage().getPDEEditor().setSelection(selection);
		if (getPage().getModel().isEditable())
			updateButtons();
	}

	@Override
	protected void buttonSelected(int index) {
		switch (index) {
			case NEW_INDEX :
				handleNew();
				break;
			case ADD_INDEX :
				handleAdd();
				break;
			case REMOVE_INDEX :
				handleRemove();
				break;
			case UP_INDEX :
				handleUp();
				break;
			case DOWN_INDEX :
				handleDown();
				break;
		}
	}

	@Override
	public void dispose() {
		IPluginModelBase model = getModel();
		if (model != null)
			model.removeModelChangedListener(this);
		super.dispose();
	}

	@Override
	public boolean doGlobalAction(String actionId) {

		if (!isEditable()) {
			return false;
		}

		if (actionId.equals(ActionFactory.DELETE.getId())) {
			handleRemove();
			return true;
		}
		if (actionId.equals(ActionFactory.CUT.getId())) {
			// delete here and let the editor transfer
			// the selection to the clipboard
			handleRemove();
			return false;
		}
		if (actionId.equals(ActionFactory.PASTE.getId())) {
			doPaste();
			return true;
		}
		return super.doGlobalAction(actionId);
	}

	@Override
	public boolean setFormInput(Object object) {
		if (object instanceof IPluginLibrary) {
			fLibraryTable.setSelection(new StructuredSelection(object), true);
			return true;
		}
		return false;
	}

	@Override
	protected void fillContextMenu(IMenuManager manager) {
		manager.add(fNewAction);
		if (!fLibraryTable.getStructuredSelection().isEmpty()) {
			manager.add(new Separator());
			manager.add(fRenameAction);
			manager.add(fRemoveAction);
		}
		// Copy, cut, and paste operations not supported for plug-ins that do
		// not have a MANIFEST.MF (not a Bundle)
		getPage().getPDEEditor().getContributor().contextMenuAboutToShow(manager, isBundle());
	}

	private void handleRemove() {
		Object[] selection = fLibraryTable.getStructuredSelection().toArray();
		int index = fLibraryTable.getTable().getSelectionIndex();
		int[] indices = fLibraryTable.getTable().getSelectionIndices();
		for (int indice : indices)
			if (indice < index)
				index = indice;

		String[] remove = new String[selection.length];
		for (int i = 0; i < selection.length; i++) {
			if (selection[i] != null && selection[i] instanceof IPluginLibrary) {
				IPluginLibrary ep = (IPluginLibrary) selection[i];
				IPluginBase plugin = ep.getPluginBase();
				try {
					plugin.remove(ep);
				} catch (CoreException e) {
					PDEPlugin.logException(e);
				}
				remove[i] = ep.getName();
			}
		}
		updateBuildProperties(remove, new String[remove.length], true);
		updateJavaClasspathLibs(remove, new String[remove.length]);

		int itemCount = fLibraryTable.getTable().getItemCount();
		if (itemCount > 0) {
			if (index >= itemCount)
				index = itemCount - 1;
			fLibraryTable.getTable().setSelection(index);
			fLibraryTable.getTable().setFocus();
		}
		updateButtons();
	}

	private void handleDown() {
		Table table = getTablePart().getTableViewer().getTable();
		int index = table.getSelectionIndex();
		if (index != table.getItemCount() - 1)
			swap(index, index + 1);
	}

	private void handleUp() {
		int index = getTablePart().getTableViewer().getTable().getSelectionIndex();
		if (index >= 1)
			swap(index, index - 1);
	}

	public void swap(int index1, int index2) {
		Table table = getTablePart().getTableViewer().getTable();
		IPluginLibrary l1 = (IPluginLibrary) table.getItem(index1).getData();
		IPluginLibrary l2 = (IPluginLibrary) table.getItem(index2).getData();

		try {
			IPluginModelBase model = getModel();
			IPluginBase pluginBase = model.getPluginBase();
			pluginBase.swap(l1, l2);
			refresh();
			table.setSelection(index2);
			table.setFocus();
			updateButtons();
		} catch (CoreException e) {
			PDEPlugin.logException(e);
		}
	}

	private void handleNew() {
		IPluginModelBase model = getModel();
		NewRuntimeLibraryDialog dialog = new NewRuntimeLibraryDialog(getPage().getSite().getShell(), model.getPluginBase().getLibraries());
		dialog.create();
		dialog.getShell().setText(PDEUIMessages.ManifestEditor_LibrarySection_newLibraryEntry);
		SWTUtil.setDialogSize(dialog, 250, 175);

		if (dialog.open() == Window.OK) {
			String libName = dialog.getLibraryName();
			if (libName == null || libName.length() == 0)
				return;
			try {
				IPluginLibrary library = model.getPluginFactory().createLibrary();
				library.setName(libName);
				library.setExported(true);
				model.getPluginBase().add(library);
				checkSourceRootEntry();
				updateBuildProperties(new String[] {null}, new String[] {library.getName()}, true);
				fLibraryTable.setSelection(new StructuredSelection(library));
				fLibraryTable.getTable().setFocus();
			} catch (CoreException e) {
				PDEPlugin.logException(e);
			}
		}
	}

	private void checkSourceRootEntry() {
		IPluginModelBase pluginModel = getModel();
		IPluginLibrary[] libraries = pluginModel.getPluginBase().getLibraries();
		for (IPluginLibrary library : libraries)
			if (library.getName().equals(".")) //$NON-NLS-1$
				return;
		IBuildModel model = getBuildModel();
		if (model == null)
			return;

		IBuildEntry[] entires = model.getBuild().getBuildEntries();
		for (IBuildEntry entry : entires) {
			if (entry.getName().equals(PROPERTY_SOURCE_PREFIX + '.')) {
				IPluginLibrary library = pluginModel.getPluginFactory().createLibrary();
				try {
					library.setName("."); //$NON-NLS-1$
					pluginModel.getPluginBase().add(library);
				} catch (CoreException e) {
				}
			}
		}
	}

	private IBuildModel getBuildModel() {
		IFormPage page = getPage().getEditor().findPage(BuildInputContext.CONTEXT_ID);
		IBaseModel model = null;
		if (page instanceof BuildSourcePage)
			model = ((BuildSourcePage) page).getInputContext().getModel();

		if (model != null && model instanceof IBuildModel)
			return (IBuildModel) model;
		return null;
	}

	private void configureSourceBuildEntry(IBuildModel bmodel, String oldPath, String newPath) throws CoreException {
		IBuild build = bmodel.getBuild();
		IBuildEntry entry = build.getEntry(PROPERTY_SOURCE_PREFIX + (oldPath != null ? oldPath : newPath));
		try {
			if (newPath != null) {
				if (entry == null) {
					IProject project = ((IModel) getPage().getModel()).getUnderlyingResource().getProject();
					IJavaProject jproject = JavaCore.create(project);
					ArrayList<String> tokens = new ArrayList<>();
					IClasspathEntry[] entries = jproject.getRawClasspath();
					for (IClasspathEntry cpe : entries)
						if (cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE)
							tokens.add(cpe.getPath().removeFirstSegments(1).addTrailingSeparator().toString());
					if (tokens.size() == 0)
						return;

					entry = bmodel.getFactory().createEntry(PROPERTY_SOURCE_PREFIX + newPath);
					for (int i = 0; i < tokens.size(); i++)
						entry.addToken(tokens.get(i));
					build.add(entry);
				} else
					entry.setName(PROPERTY_SOURCE_PREFIX + newPath);
			} else if (entry != null)
				build.remove(entry);
		} catch (JavaModelException e) {
		}
	}

	private void handleAdd() {
		final boolean[] updateClasspath = new boolean[] {true};
		ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getPage().getSite().getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider()) {
			@Override
			protected Control createDialogArea(Composite parent) {
				Composite comp = (Composite) super.createDialogArea(parent);
				final Button button = new Button(comp, SWT.CHECK);
				button.setText(PDEUIMessages.LibrarySection_addDialogButton);
				button.setSelection(updateClasspath[0]);
				button.addSelectionListener(widgetSelectedAdapter(e -> updateClasspath[0] = button.getSelection()));
				applyDialogFont(button);
				return comp;
			}
		};

		Class<?>[] acceptedClasses = new Class[] {IFile.class};
		dialog.setValidator(new LibrarySelectionValidator(acceptedClasses, true));
		dialog.setTitle(PDEUIMessages.BuildEditor_ClasspathSection_jarsTitle);
		dialog.setMessage(PDEUIMessages.ClasspathSection_jarsMessage);
		IPluginLibrary[] libraries = getModel().getPluginBase().getLibraries();
		IProject project = ((IModel) getPage().getModel()).getUnderlyingResource().getProject();
		HashSet<IPath> set = new HashSet<>();
		for (IPluginLibrary library : libraries) {
			IPath bundlePath = new Path(ClasspathUtilCore.expandLibraryName(library.getName()));
			IPath buildPath = PDEProject.getBundleRoot(project).getProjectRelativePath().append(bundlePath);
			set.add(buildPath);
		}

		dialog.addFilter(new LibraryFilter(set));
		dialog.setInput(project);
		dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
		dialog.create();
		PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), IHelpContextIds.ADD_LIBRARY);
		if (dialog.open() == Window.OK) {
			Object[] elements = dialog.getResult();
			String[] bundlePaths = new String[elements.length];
			String[] buildPaths = new String[elements.length];
			IPluginModelBase model = getModel();
			ArrayList<IPluginLibrary> list = new ArrayList<>();
			for (int i = 0; i < elements.length; i++) {
				IResource elem = (IResource) elements[i];
				IContainer bundleRoot = PDEProject.getBundleRoot(project);
				IPath rootPath = bundleRoot.getFullPath();
				// make path relative to bundle root
				IPath bundlePath = elem.getFullPath().makeRelativeTo(rootPath);
				IPath buildPath = elem.getProjectRelativePath();
				if (elem instanceof IFolder) {
					bundlePath = bundlePath.addTrailingSeparator();
					buildPath = buildPath.addTrailingSeparator();
				}
				bundlePaths[i] = bundlePath.toString();
				buildPaths[i] = buildPath.toString();
				IPluginLibrary library = model.getPluginFactory().createLibrary();
				try {
					library.setName(bundlePaths[i]);
					library.setExported(true);
					model.getPluginBase().add(library);
					list.add(library);
				} catch (CoreException e) {
					PDEPlugin.logException(e);
				}
			}
			checkSourceRootEntry();
			updateBuildProperties(new String[bundlePaths.length], bundlePaths, false);
			if (updateClasspath[0])
				updateJavaClasspathLibs(new String[buildPaths.length], buildPaths);
			fLibraryTable.setSelection(new StructuredSelection(list.toArray()));
			fLibraryTable.getTable().setFocus();
		}
	}

	private void updateBuildProperties(final String[] oldPaths, final String[] newPaths, boolean modifySourceEntry) {
		IBuildModel bmodel = getBuildModel();
		if (bmodel == null)
			return;

		IBuild build = bmodel.getBuild();

		IBuildEntry entry = build.getEntry(PROPERTY_BIN_INCLUDES);
		if (entry == null)
			entry = bmodel.getFactory().createEntry(PROPERTY_BIN_INCLUDES);

		try {
			// adding new entries
			if (oldPaths[0] == null) {
				for (String newPath : newPaths)
					if (newPath != null) {
						entry.addToken(newPath);
						if (modifySourceEntry)
							configureSourceBuildEntry(bmodel, null, newPath);
					}
				// removing entries
			} else if (newPaths[0] == null) {
				for (String oldPath : oldPaths)
					if (oldPath != null) {
						entry.removeToken(oldPath);
						if (modifySourceEntry)
							configureSourceBuildEntry(bmodel, oldPath, null);
					}
				if (entry.getTokens().length == 0)
					build.remove(entry);
				// rename entries
			} else {
				for (int i = 0; i < oldPaths.length; i++)
					if (newPaths[i] != null && oldPaths[i] != null) {
						entry.renameToken(oldPaths[i], newPaths[i]);
						if (modifySourceEntry)
							configureSourceBuildEntry(bmodel, oldPaths[i], newPaths[i]);
					}
			}
		} catch (CoreException e) {
		}
	}

	private void updateJavaClasspathLibs(String[] oldPaths, String[] newPaths) {
		IProject project = ((IModel) getPage().getModel()).getUnderlyingResource().getProject();
		IJavaProject jproject = JavaCore.create(project);
		try {
			IClasspathEntry[] entries = jproject.getRawClasspath();
			ArrayList<IClasspathEntry> toBeAdded = new ArrayList<>();
			int index = -1;
			entryLoop: for (int i = 0; i < entries.length; i++) {
				if (entries[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
					if (index == -1)
						index = i;
					// do not add the old paths (handling deletion/renaming)
					IPath path = entries[i].getPath().removeFirstSegments(1).removeTrailingSeparator();
					for (int j = 0; j < oldPaths.length; j++)
						if (oldPaths[j] != null && path.equals(new Path(oldPaths[j]).removeTrailingSeparator()))
							continue entryLoop;
				} else if (entries[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER)
					if (index == -1)
						index = i;
				toBeAdded.add(entries[i]);
			}
			if (index == -1)
				index = entries.length;

			// add paths
			for (String newPath : newPaths) {
				if (newPath == null)
					continue;
				IClasspathEntry entry = JavaCore.newLibraryEntry(project.getFullPath().append(newPath), null, null, true);
				if (!toBeAdded.contains(entry))
					toBeAdded.add(index++, entry);
			}

			if (toBeAdded.size() == entries.length)
				return;

			IClasspathEntry[] updated = toBeAdded.toArray(new IClasspathEntry[toBeAdded.size()]);
			jproject.setRawClasspath(updated, null);
		} catch (JavaModelException e) {
		}
	}

	@Override
	public void refresh() {
		if (fLibraryTable.getControl().isDisposed())
			return;
		fLibraryTable.setSelection(null);
		fLibraryTable.refresh();
		super.refresh();
	}

	@Override
	public void modelChanged(IModelChangedEvent event) {
		if (event.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
			markStale();
			return;
		}
		Object changeObject = event.getChangedObjects()[0];
		if (changeObject instanceof IPluginLibrary) {
			if (event.getChangeType() == IModelChangedEvent.INSERT) {
				fLibraryTable.refresh();
			} else if (event.getChangeType() == IModelChangedEvent.REMOVE) {
				fLibraryTable.remove(changeObject);
			} else {
				fLibraryTable.update(changeObject, null);
			}
		} else if (changeObject.equals(fLibraryTable.getInput())) {
			markStale();
		} else if (changeObject instanceof IPluginElement && ((IPluginElement) changeObject).getParent() instanceof IPluginLibrary) {
			fLibraryTable.update(((IPluginElement) changeObject).getParent(), null);
		}
	}

	@Override
	public void setFocus() {
		fLibraryTable.getTable().setFocus();
	}

	@Override
	protected void doPaste(Object targetObject, Object[] sourceObjects) {
		// Get the model
		IPluginModelBase model = getModel();
		IPluginBase plugin = model.getPluginBase();
		try {
			// Paste all source objects
			for (Object sourceObject : sourceObjects) {
				if (sourceObject instanceof PluginLibrary) {
					// Plugin library object
					PluginLibrary library = (PluginLibrary) sourceObject;
					// Adjust all the source object transient field values to
					// acceptable values
					library.reconnect(model, plugin);
					// Add the library to the plug-in
					plugin.add(library);
				}
			}
		} catch (CoreException e) {
			PDEPlugin.logException(e);
		}
	}

	@Override
	protected boolean canPaste(Object targetObject, Object[] sourceObjects) {
		HashSet<Path> librarySet = null;
		// Only source objects that are plugin libraries that have not already
		// been specified can be pasted
		for (Object sourceObject : sourceObjects) {
			// Only plugin libraries are allowed
			if ((sourceObject instanceof IPluginLibrary) == false) {
				return false;
			}
			// We have a plugin library
			// Get the current libraries already specified and store them in
			// a set to assist with searching
			if (librarySet == null) {
				librarySet = createPluginLibrarySet();
			}
			// No duplicate libraries are allowed
			IPluginLibrary library = (IPluginLibrary) sourceObject;
			if (librarySet.contains(new Path(ClasspathUtilCore.expandLibraryName(library.getName())))) {
				return false;
			}
		}
		return true;
	}

	private HashSet<Path> createPluginLibrarySet() {
		// Get the current libraries and add them to a set for easy searching
		IPluginLibrary[] libraries = getModel().getPluginBase().getLibraries();
		HashSet<Path> librarySet = new HashSet<>();
		for (IPluginLibrary library : libraries) {
			librarySet.add(new Path(ClasspathUtilCore.expandLibraryName(library.getName())));
		}
		return librarySet;
	}

	@Override
	protected void entryModified(Object entry, String value) {
		try {
			IPluginModelBase model = getModel();
			IProject project = model.getUnderlyingResource().getProject();
			IPluginLibrary library = (IPluginLibrary) entry;
			model.getPluginBase().remove(library);
			String[] oldValue = {library.getName()};
			String[] newValue = {value};
			library.setName(value);
			boolean memberExists = project.findMember(value) != null;
			updateBuildProperties(oldValue, newValue, !memberExists);
			updateJavaClasspathLibs(oldValue, memberExists ? newValue : new String[] {null});
			model.getPluginBase().add(library);
		} catch (CoreException e) {
			PDEPlugin.logException(e);
		}
	}

	private IPluginModelBase getModel() {
		return (IPluginModelBase) getPage().getModel();
	}

	@Override
	protected boolean isDragAndDropEnabled() {
		return true;
	}

	@Override
	public boolean canDragMove(Object[] sourceObjects) {
		if (validateDragMoveSanity(sourceObjects) == false) {
			return false;
		}
		return true;
	}

	/**
	 * @param sourceObjects
	 */
	private boolean validateDragMoveSanity(Object[] sourceObjects) {
		// Validate source
		if (sourceObjects == null) {
			// No objects
			return false;
		} else if (sourceObjects.length != 1) {
			// Multiple selection not supported
			return false;
		} else if ((sourceObjects[0] instanceof IPluginLibrary) == false) {
			// Must be the right type
			return false;
		}
		return true;
	}

	@Override
	public boolean canDropMove(Object targetObject, Object[] sourceObjects, int targetLocation) {
		// Sanity check
		if (validateDropMoveSanity(targetObject, sourceObjects) == false) {
			return false;
		}
		// Multiple selection not supported
		IPluginLibrary sourcePluginLibrary = (IPluginLibrary) sourceObjects[0];
		IPluginLibrary targetPluginLibrary = (IPluginLibrary) targetObject;
		// Validate model
		if (validateDropMoveModel(sourcePluginLibrary, targetPluginLibrary) == false) {
			return false;
		}
		// Get the bundle plug-in base
		BundlePluginBase bundlePluginBase = (BundlePluginBase) getModel().getPluginBase();
		// Validate move
		if (targetLocation == ViewerDropAdapter.LOCATION_BEFORE) {
			// Get the previous element of the target
			IPluginLibrary previousLibrary = bundlePluginBase.getPreviousLibrary(targetPluginLibrary);
			// Ensure the previous element is not the source
			if (sourcePluginLibrary.equals(previousLibrary)) {
				return false;
			}
			return true;
		} else if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
			// Get the next element of the target
			IPluginLibrary nextLibrary = bundlePluginBase.getNextLibrary(targetPluginLibrary);
			// Ensure the next element is not the source
			if (sourcePluginLibrary.equals(nextLibrary)) {
				return false;
			}
			return true;
		} else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
			// Not supported
			return false;
		}
		return false;
	}

	/**
	 * @param targetObject
	 * @param sourceObjects
	 */
	private boolean validateDropMoveSanity(Object targetObject, Object[] sourceObjects) {
		// Validate target object
		if ((targetObject instanceof IPluginLibrary) == false) {
			return false;
		}
		// Validate source objects
		if (validateDragMoveSanity(sourceObjects) == false) {
			return false;
		}
		return true;
	}

	/**
	 * @param sourcePluginLibrary
	 * @param targetPluginLibrary
	 */
	private boolean validateDropMoveModel(IPluginLibrary sourcePluginLibrary, IPluginLibrary targetPluginLibrary) {
		// Objects have to be from the same model
		ISharedPluginModel sourceModel = sourcePluginLibrary.getModel();
		ISharedPluginModel targetModel = targetPluginLibrary.getModel();
		if (sourceModel.equals(targetModel) == false) {
			return false;
		} else if ((getModel().getPluginBase() instanceof BundlePluginBase) == false) {
			return false;
		}
		return true;
	}

	@Override
	public void doDropMove(Object targetObject, Object[] sourceObjects, int targetLocation) {
		// Sanity check
		if (validateDropMoveSanity(targetObject, sourceObjects) == false) {
			Display.getDefault().beep();
			return;
		}
		// Multiple selection not supported
		IPluginLibrary sourcePluginLibrary = (IPluginLibrary) sourceObjects[0];
		IPluginLibrary targetPluginLibrary = (IPluginLibrary) targetObject;
		// Validate move
		if ((targetLocation == ViewerDropAdapter.LOCATION_BEFORE) || (targetLocation == ViewerDropAdapter.LOCATION_AFTER)) {
			// Do move
			doDropMove(sourcePluginLibrary, targetPluginLibrary, targetLocation);
		} else if (targetLocation == ViewerDropAdapter.LOCATION_ON) {
			// Not supported
		}
	}

	/**
	 * @param sourcePluginLibrary
	 * @param targetPluginLibrary
	 * @param targetLocation
	 */
	private void doDropMove(IPluginLibrary sourcePluginLibrary, IPluginLibrary targetPluginLibrary, int targetLocation) {
		// Remove the original source object
		// Normally we remove the original source object after inserting the
		// serialized source object; however, the libraries are removed via ID
		// and having both objects with the same ID co-existing will confound
		// the remove operation
		doDragRemove();
		// Get the bundle plug-in base
		IPluginModelBase model = getModel();
		BundlePluginBase bundlePluginBase = (BundlePluginBase) model.getPluginBase();
		// Get the index of the target
		int index = bundlePluginBase.getIndexOf(targetPluginLibrary);
		// Ensure the target index was found
		if (index == -1) {
			return;
		}
		// Determine the location index
		int targetIndex = index;
		if (targetLocation == ViewerDropAdapter.LOCATION_AFTER) {
			targetIndex++;
		}
		// Ensure the plugin library is concrete
		if ((sourcePluginLibrary instanceof PluginLibrary) == false) {
			return;
		}
		// Adjust all the source object transient field values to
		// acceptable values
		((PluginLibrary) sourcePluginLibrary).reconnect(model, bundlePluginBase);
		// Add source as sibling of target
		try {
			bundlePluginBase.add(sourcePluginLibrary, targetIndex);
		} catch (CoreException e) {
			// CoreException only if model is not editable, which should never be the case
		}
	}

	/**
	 *
	 */
	private void doDragRemove() {
		// Get the bundle plug-in base
		BundlePluginBase bundlePluginBase = (BundlePluginBase) getModel().getPluginBase();
		// Retrieve the original non-serialized source objects dragged initially
		Object[] sourceObjects = getDragSourceObjects();
		// Validate source objects
		if (validateDragMoveSanity(sourceObjects) == false) {
			return;
		}
		// Remove the library
		IPluginLibrary sourcePluginLibrary = (IPluginLibrary) sourceObjects[0];
		try {
			bundlePluginBase.remove(sourcePluginLibrary);
		} catch (CoreException e) {
			PDEPlugin.logException(e);
		}
	}

}
