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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

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.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.StringConverter;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;

import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;

import org.eclipse.jdt.core.ClasspathContainerInitializer;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess;

import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.IUIConstants;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.AccessRulesDialog;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathSupport;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElementAttribute;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElementSorter;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListLabelProvider;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPUserLibraryElement;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.NativeLibrariesDialog;
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.ITreeListAdapter;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.TreeListDialogField;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class UserLibraryPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {

	public static final String ID= "org.eclipse.jdt.ui.preferences.UserLibraryPreferencePage"; //$NON-NLS-1$
	public static final String DATA_DO_CREATE= "do_create"; //$NON-NLS-1$
	public static final String DATA_LIBRARY_TO_SELECT= "select_library"; //$NON-NLS-1$
	
	public static class LibraryNameDialog extends StatusDialog implements IDialogFieldListener {

		private StringDialogField fNameField;
		private SelectionButtonDialogField fIsSystemField;

		private CPUserLibraryElement fElementToEdit;
		private List fExistingLibraries;

		public LibraryNameDialog(Shell parent, CPUserLibraryElement elementToEdit, List existingLibraries) {
			super(parent);
			if (elementToEdit == null) { 
				setTitle(PreferencesMessages.UserLibraryPreferencePage_LibraryNameDialog_new_title); 
			} else {
				setTitle(PreferencesMessages.UserLibraryPreferencePage_LibraryNameDialog_edit_title); 
			}
			
			fElementToEdit= elementToEdit;
			fExistingLibraries= existingLibraries;
			
			fNameField= new StringDialogField();
			fNameField.setDialogFieldListener(this);
			fNameField.setLabelText(PreferencesMessages.UserLibraryPreferencePage_LibraryNameDialog_name_label); 
			
			fIsSystemField= new SelectionButtonDialogField(SWT.CHECK);
			fIsSystemField.setLabelText(PreferencesMessages.UserLibraryPreferencePage_LibraryNameDialog_issystem_label); 
			
			if (elementToEdit != null) {
				fNameField.setText(elementToEdit.getName());
				fIsSystemField.setSelection(elementToEdit.isSystemLibrary());
			} else {
				fNameField.setText(""); //$NON-NLS-1$
				fIsSystemField.setSelection(false);
			}
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
		 */
		protected Control createDialogArea(Composite parent) {
			Composite composite= (Composite) super.createDialogArea(parent);
			LayoutUtil.doDefaultLayout(composite, new DialogField[] { fNameField, fIsSystemField }, true, SWT.DEFAULT, SWT.DEFAULT);
			fNameField.postSetFocusOnDialogField(parent.getDisplay());
			
			Dialog.applyDialogFont(composite);
			
			PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.CP_EDIT_USER_LIBRARY);
			
			return composite;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener#dialogFieldChanged(org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField)
		 */
		public void dialogFieldChanged(DialogField field) {
			if (field == fNameField) {
				updateStatus(validateSettings());
			}
		}
		
		private IStatus validateSettings() {
			String name= fNameField.getText();
			if (name.length() == 0) {
				return new StatusInfo(IStatus.ERROR, PreferencesMessages.UserLibraryPreferencePage_LibraryNameDialog_name_error_entername); 
			}
			for (int i= 0; i < fExistingLibraries.size(); i++) {
				CPUserLibraryElement curr= (CPUserLibraryElement) fExistingLibraries.get(i);
				if (curr != fElementToEdit && name.equals(curr.getName())) {
					return new StatusInfo(IStatus.ERROR, Messages.format(PreferencesMessages.UserLibraryPreferencePage_LibraryNameDialog_name_error_exists, name)); 
				}
			}
			IStatus status= ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
			if (status.matches(IStatus.ERROR)) {
				return new StatusInfo(IStatus.ERROR, "Name contains invalid characters."); //$NON-NLS-1$
			}
			return StatusInfo.OK_STATUS;
		}
		
		public CPUserLibraryElement getNewLibrary() {
			CPListElement[] entries= null;
			if (fElementToEdit != null) {
				entries= fElementToEdit.getChildren();
			}
			return new CPUserLibraryElement(fNameField.getText(), fIsSystemField.isSelected(), entries);
		}
		
	}
	
	public static class LoadSaveDialog extends StatusDialog implements IStringButtonAdapter, IDialogFieldListener, IListAdapter {
		
		
		private static final String VERSION1= "1"; //$NON-NLS-1$ // using OS strings for archive path and source attachment
		private static final String CURRENT_VERSION= "2"; //$NON-NLS-1$

		private static final String TAG_ROOT= "eclipse-userlibraries"; //$NON-NLS-1$
		private static final String TAG_VERSION= "version"; //$NON-NLS-1$
		private static final String TAG_LIBRARY= "library"; //$NON-NLS-1$
		private static final String TAG_SOURCEATTACHMENT= "source"; //$NON-NLS-1$
		private static final String TAG_ARCHIVE_PATH= "path"; //$NON-NLS-1$
		private static final String TAG_ARCHIVE= "archive"; //$NON-NLS-1$
		private static final String TAG_SYSTEMLIBRARY= "systemlibrary"; //$NON-NLS-1$
		private static final String TAG_NAME= "name"; //$NON-NLS-1$
		private static final String TAG_JAVADOC= "javadoc"; //$NON-NLS-1$
		private static final String TAG_NATIVELIB_PATHS= "nativelibpaths"; //$NON-NLS-1$
		private static final String TAG_ACCESSRULES= "accessrules"; //$NON-NLS-1$
		private static final String TAG_ACCESSRULE= "accessrule"; //$NON-NLS-1$
		private static final String TAG_RULE_KIND= "kind"; //$NON-NLS-1$
		private static final String TAG_RULE_PATTERN= "pattern"; //$NON-NLS-1$

		private static final String PREF_LASTPATH= JavaUI.ID_PLUGIN + ".lastuserlibrary"; //$NON-NLS-1$
		private static final String PREF_USER_LIBRARY_LOADSAVE_SIZE= "UserLibraryLoadSaveDialog.size"; //$NON-NLS-1$
		
		private List fExistingLibraries;
		private IDialogSettings fSettings;
		
		private File fLastFile;
		
		private StringButtonDialogField fLocationField;
		private CheckedListDialogField fExportImportList;
		private Point fInitialSize;
		private final boolean fIsSave;

		public LoadSaveDialog(Shell shell, boolean isSave, List existingLibraries, IDialogSettings dialogSettings) {
			super(shell);
			initializeDialogUnits(shell);
			
			setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE);
			
			fExistingLibraries= existingLibraries;
			fSettings= dialogSettings;
			fLastFile= null;
			fIsSave= isSave;
			
			int defaultWidth= convertWidthInCharsToPixels(80);
			int defaultHeigth= convertHeightInCharsToPixels(34);
			String lastSize= fSettings.get(PREF_USER_LIBRARY_LOADSAVE_SIZE);
			if (lastSize != null) {
				fInitialSize= StringConverter.asPoint(lastSize, new Point(defaultWidth, defaultHeigth));
			} else {
				fInitialSize= new Point(defaultWidth, defaultHeigth);
			}
		
			if (isSave()) {
				setTitle(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_save_title); 
			} else {
				setTitle(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_load_title);				 
			}
			
			fLocationField= new StringButtonDialogField(this);
			fLocationField.setLabelText(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_location_label); 
			fLocationField.setButtonLabel(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_location_button); 
			fLocationField.setDialogFieldListener(this);
			
			String[] buttonNames= new String[] {
					PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_list_selectall_button, 
					PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_list_deselectall_button
			};
			fExportImportList= new CheckedListDialogField(this, buttonNames, new CPListLabelProvider());
			fExportImportList.setCheckAllButtonIndex(0);
			fExportImportList.setUncheckAllButtonIndex(1);
			fExportImportList.setViewerSorter(new CPListElementSorter());
			fExportImportList.setDialogFieldListener(this);
			if (isSave()) {
				fExportImportList.setLabelText(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_list_save_label); 
				fExportImportList.setElements(fExistingLibraries);
				fExportImportList.checkAll(true);
			} else {
				fExportImportList.setLabelText(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_list_load_label); 
			}
			String lastPath= fSettings.get(PREF_LASTPATH);
			if (lastPath != null) {
				fLocationField.setText(lastPath);
			} else {
				fLocationField.setText(""); //$NON-NLS-1$
			}
		}
				
		protected Point getInitialSize() {
			return fInitialSize;
		}
		
		private boolean isSave() {
			return fIsSave;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
		 */
		protected Control createDialogArea(Composite parent) {
			Composite composite= (Composite) super.createDialogArea(parent);
			DialogField[] fields;
			if (isSave()) {
				fields= new DialogField[] { fExportImportList, fLocationField };
			} else {
				fields= new DialogField[] { fLocationField, fExportImportList };
			}
			LayoutUtil.doDefaultLayout(composite, fields, true, SWT.DEFAULT, SWT.DEFAULT);
			fExportImportList.getListControl(null).setLayoutData(new GridData(GridData.FILL_BOTH));
			
			fLocationField.postSetFocusOnDialogField(parent.getDisplay());
			
			Dialog.applyDialogFont(composite);
			
			if (isSave()) {
				PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.CP_EXPORT_USER_LIBRARY);
			} else {
				PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.CP_IMPORT_USER_LIBRARY);
			}
			
			return composite;
		}
		

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter#changeControlPressed(org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField)
		 */
		public void changeControlPressed(DialogField field) {
			String label= isSave() ? PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_filedialog_save_title : PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_filedialog_load_title; 
			FileDialog dialog= new FileDialog(getShell(), isSave() ? SWT.SAVE : SWT.OPEN);
			dialog.setText(label);
			dialog.setFilterExtensions(new String[] {"*.userlibraries", "*.*"}); //$NON-NLS-1$ //$NON-NLS-2$
			String lastPath= fLocationField.getText();
			if (lastPath.length() == 0 || !new File(lastPath).exists()) {
				lastPath= fSettings.get(PREF_LASTPATH);
			}
			if (lastPath != null) {
				dialog.setFileName(lastPath);
			}
			String fileName= dialog.open();
			if (fileName != null) {
				fSettings.put(PREF_LASTPATH, fileName);
				fLocationField.setText(fileName);
			}
		}

		private IStatus updateShownLibraries(IStatus status) {
			if (!status.isOK()) {
				fExportImportList.removeAllElements();
				fExportImportList.setEnabled(false);
				fLastFile= null;
			} else {
				File file= new File(fLocationField.getText());
				if (!file.equals(fLastFile)) {
					fLastFile= file;
					try {
						List elements= loadLibraries(file);
						fExportImportList.setElements(elements);
						fExportImportList.checkAll(true);
						fExportImportList.setEnabled(true);
						if (elements.isEmpty()) {
							return new StatusInfo(IStatus.ERROR, PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_error_empty); 
						}
					} catch (IOException e) {
						fExportImportList.removeAllElements();
						fExportImportList.setEnabled(false);
						return new StatusInfo(IStatus.ERROR, PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_error_invalidfile); 
					}
				}
			}
			return status;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener#dialogFieldChanged(org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField)
		 */
		public void dialogFieldChanged(DialogField field) {
			if (field == fLocationField) {
				IStatus status= validateSettings();
				if (!isSave()) {
					status= updateShownLibraries(status);
				}
				updateStatus(status);
			} else if (field == fExportImportList) {
				updateStatus(validateSettings());
			}
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter#customButtonPressed(org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField, int)
		 */
		public void customButtonPressed(ListDialogField field, int index) {
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter#selectionChanged(org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField)
		 */
		public void selectionChanged(ListDialogField field) {
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter#doubleClicked(org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField)
		 */
		public void doubleClicked(ListDialogField field) {
			List selectedElements= fExportImportList.getSelectedElements();
			if (selectedElements.size() == 1) {
				Object elem= selectedElements.get(0);
				fExportImportList.setChecked(elem, !fExportImportList.isChecked(elem));
			}
		}
	
		/* (non-Javadoc)
		 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
		 */
		protected void okPressed() {
			if (isSave()) {
				final File file= new File(fLocationField.getText());
				if (file.exists()) {
					String title= PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_overwrite_title; 
					String message= PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_overwrite_message; 
					if (!MessageDialog.openQuestion(getShell(), title, message)) {
						return;
					}
				}
				final List elements= fExportImportList.getCheckedElements();

				IRunnableContext context= PlatformUI.getWorkbench().getProgressService();
				try {
					context.run(true, true, new IRunnableWithProgress() {
						public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
							try {
								saveLibraries(elements, file, monitor);
							} catch (IOException e) {
								throw new InvocationTargetException(e);
							}
						}
					});
					fSettings.put(PREF_LASTPATH, file.getPath());
				} catch (InvocationTargetException e) {
					String errorTitle= PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_save_errordialog_title; 
					String errorMessage= Messages.format(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_save_errordialog_message, e.getMessage()); 
					ExceptionHandler.handle(e, getShell(), errorTitle, errorMessage);
					return;
				} catch (InterruptedException e) {
					// cancelled
					return;
				}
				String savedTitle= PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_save_ok_title; 
				String savedMessage= PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_save_ok_message; 
				MessageDialog.openInformation(getShell(), savedTitle, savedMessage);
			} else {
				HashSet map= new HashSet(fExistingLibraries.size());
				for (int k= 0; k < fExistingLibraries.size(); k++) {
					CPUserLibraryElement elem= (CPUserLibraryElement) fExistingLibraries.get(k);
					map.add(elem.getName());
				}
				int nReplaced= 0;
				List elements= getLoadedLibraries();
				for (int i= 0; i < elements.size(); i++) {
					CPUserLibraryElement curr= (CPUserLibraryElement) elements.get(i);
					if (map.contains(curr.getName())) {
						nReplaced++;
					}
				}
				if (nReplaced > 0) {
					String replaceTitle= PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_load_replace_title; 
					String replaceMessage;
					if (nReplaced == 1) {
						replaceMessage= PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_load_replace_message; 
					} else {
						replaceMessage= Messages.format(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_load_replace_multiple_message, String.valueOf(nReplaced)); 
					}
					if (!MessageDialog.openConfirm(getShell(), replaceTitle, replaceMessage)) {
						return;
					}
				}
			}
			super.okPressed();
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.jface.dialogs.Dialog#close()
		 */
		public boolean close() {
			Point point= getShell().getSize();
			fSettings.put(PREF_USER_LIBRARY_LOADSAVE_SIZE, StringConverter.asString(point));
			return super.close();
		}
		
		private IStatus validateSettings() {
			String name= fLocationField.getText();
			fLastFile= null;
			if (isSave()) {
				if (name.length() == 0) {
					return new StatusInfo(IStatus.ERROR, PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_location_error_save_enterlocation); 
				}
				File file= new File(name);
				if (file.isDirectory()) {
					return new StatusInfo(IStatus.ERROR, PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_location_error_save_invalid); 
				}
				if (fExportImportList.getCheckedSize() == 0) {
					return new StatusInfo(IStatus.ERROR, PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_list_error_save_nothingselected); 
				}
				fLastFile= file;
			} else {
				if (name.length() == 0) {
					return new StatusInfo(IStatus.ERROR, PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_location_error_load_enterlocation); 
				}
				if (!new File(name).isFile()) {
					return new StatusInfo(IStatus.ERROR, PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_location_error_load_invalid); 
				}
				if (fExportImportList.getSize() > 0 && fExportImportList.getCheckedSize() == 0) {
					return new StatusInfo(IStatus.ERROR, PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_list_error_load_nothingselected); 
				}
			}
			return new StatusInfo();
		}
		
		protected static void saveLibraries(List libraries, File file, IProgressMonitor monitor) throws IOException {
			OutputStream stream= new FileOutputStream(file);
			try {
				DocumentBuilder docBuilder= null;
				DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
				factory.setValidating(false);
				docBuilder= factory.newDocumentBuilder();
				Document document= docBuilder.newDocument();
	
				// Create the document
				Element rootElement= document.createElement(TAG_ROOT);
				document.appendChild(rootElement);
	
				rootElement.setAttribute(TAG_VERSION, CURRENT_VERSION); 
				
				for (int i= 0; i < libraries.size(); i++) {
					Element libraryElement= document.createElement(TAG_LIBRARY);
					rootElement.appendChild(libraryElement);
					
					CPUserLibraryElement curr= (CPUserLibraryElement) libraries.get(i);
					libraryElement.setAttribute(TAG_NAME, curr.getName());
					libraryElement.setAttribute(TAG_SYSTEMLIBRARY, String.valueOf(curr.isSystemLibrary()));
					
					CPListElement[] children= curr.getChildren();
					for (int k= 0; k < children.length; k++) {
						CPListElement child= children[k];
						
						Element childElement= document.createElement(TAG_ARCHIVE); 
						libraryElement.appendChild(childElement);
						
						childElement.setAttribute(TAG_ARCHIVE_PATH, child.getPath().toPortableString());
						IPath sourceAttachment= (IPath) child.getAttribute(CPListElement.SOURCEATTACHMENT);
						if (sourceAttachment != null) {
							childElement.setAttribute(TAG_SOURCEATTACHMENT, sourceAttachment.toPortableString());
	
						}
						String javadocLocation= (String) child.getAttribute(CPListElement.JAVADOC);
						if (javadocLocation != null) {
							childElement.setAttribute(TAG_JAVADOC, javadocLocation);
						}
						String nativeLibPath= (String) child.getAttribute(CPListElement.NATIVE_LIB_PATH);
						if (nativeLibPath != null) {
							childElement.setAttribute(TAG_NATIVELIB_PATHS, nativeLibPath);
						}
						IAccessRule[] accessRules= (IAccessRule[]) child.getAttribute(CPListElement.ACCESSRULES);
						if (accessRules != null && accessRules.length > 0) {
							Element rulesElement= document.createElement(TAG_ACCESSRULES); 
							childElement.appendChild(rulesElement);
							for (int n= 0; n < accessRules.length; n++) {
								IAccessRule rule= accessRules[n];
								Element ruleElement= document.createElement(TAG_ACCESSRULE); 
								rulesElement.appendChild(ruleElement);
								ruleElement.setAttribute(TAG_RULE_KIND, String.valueOf(rule.getKind()));
								ruleElement.setAttribute(TAG_RULE_PATTERN, rule.getPattern().toPortableString());
							}
						}
					}
				}
	
				// Write the document to the stream
				Transformer transformer=TransformerFactory.newInstance().newTransformer();
				transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
				transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
				transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
				transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4"); //$NON-NLS-1$ //$NON-NLS-2$

				DOMSource source = new DOMSource(document);
				StreamResult result = new StreamResult(stream);
				transformer.transform(source, result);	
			} catch (ParserConfigurationException e) {
				throw new IOException(e.getMessage());
			} catch (TransformerException e) {
				throw new IOException(e.getMessage());			
			} finally {
				try {
					stream.close();
				} catch (IOException e) {
					// ignore
				}
				if (monitor != null) {
					monitor.done();
				}
			}
		}
				
		private static List loadLibraries(File file) throws IOException {
			InputStream stream= new FileInputStream(file);
			Element cpElement;
			try {
				DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
				cpElement = parser.parse(new InputSource(stream)).getDocumentElement();
			} catch (SAXException e) {
				throw new IOException(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_load_badformat); 
			} catch (ParserConfigurationException e) {
				throw new IOException(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_load_badformat); 
			} finally {
				stream.close();
			}
			
			if (!cpElement.getNodeName().equalsIgnoreCase(TAG_ROOT)) {
				throw new IOException(PreferencesMessages.UserLibraryPreferencePage_LoadSaveDialog_load_badformat); 
			}
			
			String version= cpElement.getAttribute(TAG_VERSION); 
			
			NodeList libList= cpElement.getElementsByTagName(TAG_LIBRARY);
			int length = libList.getLength();
			
			ArrayList result= new ArrayList(length);
			for (int i= 0; i < length; i++) {
				Node lib= libList.item(i);
				if (!(lib instanceof Element)) {
					continue;
				}
				Element libElement= (Element) lib;
				String name= libElement.getAttribute(TAG_NAME);
				boolean isSystem= Boolean.valueOf(libElement.getAttribute(TAG_SYSTEMLIBRARY)).booleanValue();
				
				CPUserLibraryElement newLibrary= new CPUserLibraryElement(name, isSystem, null);
				result.add(newLibrary);
				
				NodeList archiveList= libElement.getElementsByTagName(TAG_ARCHIVE);
				for (int k= 0; k < archiveList.getLength(); k++) {
					Node archiveNode= archiveList.item(k);
					if (!(archiveNode instanceof Element)) {
						continue;
					}
					Element archiveElement= (Element) archiveNode;
					
					String pathString= archiveElement.getAttribute(TAG_ARCHIVE_PATH);
					IPath path= version.equals(VERSION1) ? Path.fromOSString(pathString) : Path.fromPortableString(pathString);
					CPListElement newArchive= new CPListElement(newLibrary, null, IClasspathEntry.CPE_LIBRARY, path, null);
					newLibrary.add(newArchive);
					
					if (archiveElement.hasAttribute(TAG_SOURCEATTACHMENT)) {
						String sourceAttachString= archiveElement.getAttribute(TAG_SOURCEATTACHMENT);
						IPath sourceAttach= version.equals(VERSION1) ? Path.fromOSString(sourceAttachString) : Path.fromPortableString(sourceAttachString);
						newArchive.setAttribute(CPListElement.SOURCEATTACHMENT, sourceAttach);
					}
					if (archiveElement.hasAttribute(TAG_JAVADOC)) {
						String javadoc= archiveElement.getAttribute(TAG_JAVADOC);
						newArchive.setAttribute(CPListElement.JAVADOC, javadoc);
					}
					if (archiveElement.hasAttribute(TAG_NATIVELIB_PATHS)) {
						String nativeLibPath= archiveElement.getAttribute(TAG_NATIVELIB_PATHS);
						newArchive.setAttribute(CPListElement.NATIVE_LIB_PATH, nativeLibPath);
					}
					NodeList rulesParentNodes= archiveElement.getElementsByTagName(TAG_ACCESSRULES);
					if (rulesParentNodes.getLength() > 0 && rulesParentNodes.item(0) instanceof Element) {
						Element ruleParentElement= (Element) rulesParentNodes.item(0); // take first, ignore others
						NodeList ruleElements= ruleParentElement.getElementsByTagName(TAG_ACCESSRULE);
						int nRuleElements= ruleElements.getLength();
						if (nRuleElements > 0) {
							ArrayList resultingRules= new ArrayList(nRuleElements);
							for (int n= 0; n < nRuleElements; n++) {
								Node node= ruleElements.item(n);
								if (node instanceof Element) {
									Element ruleElement= (Element) node;
									try {
										int kind= Integer.parseInt(ruleElement.getAttribute(TAG_RULE_KIND));
										IPath pattern= Path.fromPortableString(ruleElement.getAttribute(TAG_RULE_PATTERN));
										resultingRules.add(JavaCore.newAccessRule(pattern, kind));
									} catch (NumberFormatException e) {
										// ignore
									}
								}
							}
							newArchive.setAttribute(CPListElement.ACCESSRULES, resultingRules.toArray(new IAccessRule[resultingRules.size()]));
						}
					}					
				}
			}
			return result;
		}

		public List getLoadedLibraries() {
			return fExportImportList.getCheckedElements();
		}
	}
	
	private IDialogSettings fDialogSettings;
	private TreeListDialogField fLibraryList;
	private IJavaProject fDummyProject;
		
	private static final int IDX_NEW= 0;
	private static final int IDX_EDIT= 1;
	private static final int IDX_ADD= 2;
	private static final int IDX_REMOVE= 3;
	private static final int IDX_UP= 5;
	private static final int IDX_DOWN= 6;
	private static final int IDX_LOAD= 8;
	private static final int IDX_SAVE= 9;
	
	/**
	 * Constructor for ClasspathVariablesPreferencePage
	 */
	public UserLibraryPreferencePage() {
		setPreferenceStore(JavaPlugin.getDefault().getPreferenceStore());
		fDummyProject= getPlaceholderProject();
	
		// title only used when page is shown programatically
		setTitle(PreferencesMessages.UserLibraryPreferencePage_title); 
		setDescription(PreferencesMessages.UserLibraryPreferencePage_description); 
		noDefaultAndApplyButton();

		fDialogSettings= JavaPlugin.getDefault().getDialogSettings();
		
		UserLibraryAdapter adapter= new UserLibraryAdapter();
		String[] buttonLabels= new String[] {
				PreferencesMessages.UserLibraryPreferencePage_libraries_new_button, 
				PreferencesMessages.UserLibraryPreferencePage_libraries_edit_button, 
				PreferencesMessages.UserLibraryPreferencePage_libraries_addjar_button, 
				PreferencesMessages.UserLibraryPreferencePage_libraries_remove_button, 
				null,
				PreferencesMessages.UserLibraryPreferencePage_UserLibraryPreferencePage_libraries_up_button, 
				PreferencesMessages.UserLibraryPreferencePage_UserLibraryPreferencePage_libraries_down_button, 
				null,
				
				PreferencesMessages.UserLibraryPreferencePage_libraries_load_button, 
				PreferencesMessages.UserLibraryPreferencePage_libraries_save_button
		};
		
		fLibraryList= new TreeListDialogField(adapter, buttonLabels, new CPListLabelProvider());
		fLibraryList.setLabelText(PreferencesMessages.UserLibraryPreferencePage_libraries_label);
		
		String[] names= JavaCore.getUserLibraryNames();
		ArrayList elements= new ArrayList();
		
		for (int i= 0; i < names.length; i++) {
			IPath path= new Path(JavaCore.USER_LIBRARY_CONTAINER_ID).append(names[i]);
			try {
				IClasspathContainer container= JavaCore.getClasspathContainer(path, fDummyProject);
				elements.add(new CPUserLibraryElement(names[i], container, fDummyProject));
			} catch (JavaModelException e) {
				JavaPlugin.log(e);
				// ignore
			}
		}
		fLibraryList.setElements(elements);
		fLibraryList.setViewerSorter(new CPListElementSorter());
		
		doSelectionChanged(fLibraryList); //update button enable state 
	}
	
	public static IJavaProject getPlaceholderProject() {
		String name= "####internal"; //$NON-NLS-1$
		IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
		while (true) {
			IProject project= root.getProject(name);
			if (!project.exists()) {
				return JavaCore.create(project);
			}
			name += '1';
		}		
	}
	

	/* (non-Javadoc)
	 * @see org.eclipse.jface.preference.PreferencePage#applyData(java.lang.Object)
	 */
	public void applyData(Object data) {
		if (data instanceof Map) {
			Map map= (Map) data;
			Object selectedLibrary= map.get(DATA_LIBRARY_TO_SELECT);
			boolean createIfNotExists= Boolean.TRUE.equals(map.get(DATA_DO_CREATE));
			if (selectedLibrary instanceof String) {
				int nElements= fLibraryList.getSize();
				for (int i= 0; i < nElements; i++) {
					CPUserLibraryElement curr= (CPUserLibraryElement) fLibraryList.getElement(i);
					if (curr.getName().equals(selectedLibrary)) {
						fLibraryList.selectElements(new StructuredSelection(curr));
						fLibraryList.expandElement(curr, 1);
						break;
					}
				}
				if (createIfNotExists) {
					CPUserLibraryElement elem= new CPUserLibraryElement((String) selectedLibrary, null, getPlaceholderProject());
					fLibraryList.addElement(elem);
					fLibraryList.selectElements(new StructuredSelection(elem));
				}
			}
		}
	}
	
	
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createControl(Composite parent) {
		super.createControl(parent);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaHelpContextIds.CP_USERLIBRARIES_PREFERENCE_PAGE);
	}	

	/*
	 * @see PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createContents(Composite parent) {
		Composite composite= new Composite(parent, SWT.NONE);
		composite.setFont(parent.getFont());
		LayoutUtil.doDefaultLayout(composite, new DialogField[] { fLibraryList }, true);
		LayoutUtil.setHorizontalGrabbing(fLibraryList.getTreeControl(null));
		Dialog.applyDialogFont(composite);
		return composite;
	}
	
	/*
	 * @see IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
	 */
	public void init(IWorkbench workbench) {
	}
	
	/*
	 * @see PreferencePage#performDefaults()
	 */
	protected void performDefaults() {
		super.performDefaults();
	}

	/*
	 * @see PreferencePage#performOk()
	 */
	public boolean performOk() {
		try {
			PlatformUI.getWorkbench().getProgressService().run(true, true, new IRunnableWithProgress() { 
				public void run(IProgressMonitor monitor) throws InvocationTargetException {
					try {
						if (monitor != null) {
							monitor= new NullProgressMonitor();
						}
						
						updateUserLibararies(monitor);
					} catch (CoreException e) {
						throw new InvocationTargetException(e);
					} finally {
						monitor.done();
					}
				}
			});
		} catch (InterruptedException e) {
			// cancelled by user
		} catch (InvocationTargetException e) {
			String title= PreferencesMessages.UserLibraryPreferencePage_config_error_title; 
			String message= PreferencesMessages.UserLibraryPreferencePage_config_error_message; 
			ExceptionHandler.handle(e, getShell(), title, message);
		}
		return true;
	}
	
	
	private void updateUserLibararies(IProgressMonitor monitor) throws CoreException {
		List list= fLibraryList.getElements();
		HashSet oldNames= new HashSet(Arrays.asList(JavaCore.getUserLibraryNames()));
		int nExisting= list.size();
		
		HashSet newEntries= new HashSet(list.size());
		for (int i= 0; i < nExisting; i++) {
			CPUserLibraryElement element= (CPUserLibraryElement) list.get(i);
			boolean contained= oldNames.remove(element.getName());
			if (!contained) {
				newEntries.add(element);
			}
		}	
		
		int len= nExisting + oldNames.size();
		monitor.beginTask(PreferencesMessages.UserLibraryPreferencePage_operation, len); 
		MultiStatus multiStatus= new MultiStatus(JavaUI.ID_PLUGIN, IStatus.OK, PreferencesMessages.UserLibraryPreferencePage_operation_error, null); 
		
		ClasspathContainerInitializer initializer= JavaCore.getClasspathContainerInitializer(JavaCore.USER_LIBRARY_CONTAINER_ID);
		IJavaProject jproject= fDummyProject;
		
		IJavaProject[] projectInit= new IJavaProject[] { jproject };
		IClasspathContainer[] containerInit= new IClasspathContainer[] { null };
				
		for (int i= 0; i < nExisting; i++) {
			CPUserLibraryElement element= (CPUserLibraryElement) list.get(i);
			IPath path= element.getPath();
			if (newEntries.contains(element) || element.hasChanges(JavaCore.getClasspathContainer(path, jproject))) {
				IClasspathContainer updatedContainer= element.getUpdatedContainer();
				try {
					initializer.requestClasspathContainerUpdate(path, jproject, updatedContainer);
					containerInit[0]= updatedContainer;
					JavaCore.setClasspathContainer(path, projectInit, containerInit, null); // force updating of containers, bug 62250 
				} catch (CoreException e) {
					multiStatus.add(e.getStatus());
				}
			}
			monitor.worked(1);
		}
		
		containerInit[0]= null;
		Iterator iter= oldNames.iterator();
		while (iter.hasNext()) {
			String name= (String) iter.next();
			
			IPath path= new Path(JavaCore.USER_LIBRARY_CONTAINER_ID).append(name);
			try {
				initializer.requestClasspathContainerUpdate(path, jproject, null);
				JavaCore.setClasspathContainer(path, projectInit, containerInit, null); // force updating of containers, bug 62250 
			} catch (CoreException e) {
				multiStatus.add(e.getStatus());
			}
			monitor.worked(1);
		}
		
		if (!multiStatus.isOK()) {
			throw new CoreException(multiStatus);
		}
	}
	
	private CPUserLibraryElement getSingleSelectedLibrary(List selected) {
		if (selected.size() == 1 && selected.get(0) instanceof CPUserLibraryElement) {
			return (CPUserLibraryElement) selected.get(0);
		}
		return null;
	}
	
	private void editAttributeEntry(CPListElementAttribute elem) {
		String key= elem.getKey();
		CPListElement selElement= elem.getParent();
		if (key.equals(CPListElement.SOURCEATTACHMENT)) {
			IClasspathEntry result= BuildPathDialogAccess.configureSourceAttachment(getShell(), selElement.getClasspathEntry());
			if (result != null) {
				selElement.setAttribute(CPListElement.SOURCEATTACHMENT, result.getSourceAttachmentPath());
				fLibraryList.refresh(elem);
				fLibraryList.update(selElement);
			}
		} else if (key.equals(CPListElement.JAVADOC)) {
			String initialLocation= (String) selElement.getAttribute(CPListElement.JAVADOC);
			String elementName= new CPListLabelProvider().getText(selElement);
			try {
				URL locationURL= initialLocation != null ? new URL(initialLocation) : null;
				URL[] result= BuildPathDialogAccess.configureJavadocLocation(getShell(), elementName, locationURL);
				if (result != null) {
					URL newURL= result[0];
					selElement.setAttribute(CPListElement.JAVADOC, newURL != null ? newURL.toExternalForm() : null);
					fLibraryList.refresh(elem);
				}
			} catch (MalformedURLException e) {
				// todo
			}
		} else if (key.equals(CPListElement.ACCESSRULES)) {
			AccessRulesDialog dialog= new AccessRulesDialog(getShell(), selElement, null, false);
			if (dialog.open() == Window.OK) {
				selElement.setAttribute(CPListElement.ACCESSRULES, dialog.getAccessRules());
				fLibraryList.refresh(elem);
			}
		} else if (key.equals(CPListElement.NATIVE_LIB_PATH)) {
			NativeLibrariesDialog dialog= new NativeLibrariesDialog(getShell(), selElement);
			if (dialog.open() == Window.OK) {
				selElement.setAttribute(CPListElement.NATIVE_LIB_PATH, dialog.getNativeLibraryPath());
				fLibraryList.refresh(elem);
			}
		}
	}
	
	protected void doSelectionChanged(TreeListDialogField field) {
		List list= field.getSelectedElements();
		field.enableButton(IDX_REMOVE, canRemove(list));
		field.enableButton(IDX_EDIT, canEdit(list));
		field.enableButton(IDX_ADD, canAdd(list));
		field.enableButton(IDX_UP, canMoveUp(list));
		field.enableButton(IDX_DOWN, canMoveDown(list));
		field.enableButton(IDX_SAVE, field.getSize() > 0);	
	}
	
	protected void doCustomButtonPressed(TreeListDialogField field, int index) {
		if (index == IDX_NEW) {
			editUserLibraryElement(null);
		} else if (index == IDX_ADD) {
			doAdd(field.getSelectedElements());
		} else if (index == IDX_REMOVE) {
			doRemove(field.getSelectedElements());
		} else if (index == IDX_EDIT) {
			doEdit(field.getSelectedElements());
		} else if (index == IDX_SAVE) {
			doSave();
		} else if (index == IDX_LOAD) {
			doLoad();
		} else if (index == IDX_UP) {
			doMoveUp(field.getSelectedElements());
		} else if (index == IDX_DOWN) {
			doMoveDown(field.getSelectedElements());
		}
	}
	
	protected void doDoubleClicked(TreeListDialogField field) {
		List selected= field.getSelectedElements();
		if (canEdit(selected)) {
			doEdit(field.getSelectedElements());
		}
	}
	
	protected void doKeyPressed(TreeListDialogField field, KeyEvent event) {
		if (event.character == SWT.DEL && event.stateMask == 0) {
			List selection= field.getSelectedElements();
			if (canRemove(selection)) {
				doRemove(selection);
			}
		}
	}
	
	private void doEdit(List selected) {
		if (selected.size() == 1) {
			Object curr= selected.get(0);
			if (curr instanceof CPListElementAttribute) {
				editAttributeEntry((CPListElementAttribute) curr);
			} else if (curr instanceof CPUserLibraryElement) {
				editUserLibraryElement((CPUserLibraryElement) curr);
			} else if (curr instanceof CPListElement) {
				CPListElement elem= (CPListElement) curr;				
				editArchiveElement(elem, (CPUserLibraryElement) elem.getParentContainer());
			}
		}
	}

	private void editUserLibraryElement(CPUserLibraryElement element) {
		LibraryNameDialog dialog= new LibraryNameDialog(getShell(), element, fLibraryList.getElements());
		if (dialog.open() == Window.OK) {
			CPUserLibraryElement newLibrary= dialog.getNewLibrary();
			if (element != null) {
				fLibraryList.replaceElement(element, newLibrary);
			} else {
				fLibraryList.addElement(newLibrary);
			}
			fLibraryList.expandElement(newLibrary, AbstractTreeViewer.ALL_LEVELS);
			fLibraryList.selectElements(new StructuredSelection(newLibrary));
		}
	}
	
	private void editArchiveElement(CPListElement existingElement, CPUserLibraryElement parent) {
		CPListElement[] elements= openExtJarFileDialog(existingElement, parent);
		if (elements != null) {
			for (int i= 0; i < elements.length; i++) {
				if (existingElement != null) {
					parent.replace(existingElement, elements[i]);
				} else {
					parent.add(elements[i]);
				}
			}
			fLibraryList.refresh(parent);
			fLibraryList.selectElements(new StructuredSelection(Arrays.asList(elements)));
		}
	}


	private void doRemove(List selected) {
		Object selectionAfter= null;
		for (int i= 0; i < selected.size(); i++) {
			Object curr= selected.get(i);
			if (curr instanceof CPUserLibraryElement) {
				fLibraryList.removeElement(curr);
			} else if (curr instanceof CPListElement) {
				Object parent= ((CPListElement) curr).getParentContainer();
				if (parent instanceof CPUserLibraryElement) {
					CPUserLibraryElement elem= (CPUserLibraryElement) parent;
					elem.remove((CPListElement) curr);
					fLibraryList.refresh(elem);
					selectionAfter= parent;
				}
			} else if (curr instanceof CPListElementAttribute) {
				CPListElementAttribute attrib= (CPListElementAttribute) curr;
				attrib.getParent().setAttribute(attrib.getKey(), null);
				fLibraryList.refresh(attrib);
			}
		}
		if (fLibraryList.getSelectedElements().isEmpty()) {
			if (selectionAfter != null) {
				fLibraryList.selectElements(new StructuredSelection(selectionAfter));
			} else {
				fLibraryList.selectFirstElement();	
			}
		}
	}

	private void doAdd(List list) {
		if (canAdd(list)) {
			CPUserLibraryElement element= getSingleSelectedLibrary(list);
			editArchiveElement(null, element);
		}
	}
	
	private void doLoad() {
		List existing= fLibraryList.getElements();
		LoadSaveDialog dialog= new LoadSaveDialog(getShell(), false, existing, fDialogSettings);
		if (dialog.open() == Window.OK) {
			HashMap map= new HashMap(existing.size());
			for (int k= 0; k < existing.size(); k++) {
				CPUserLibraryElement elem= (CPUserLibraryElement) existing.get(k);
				map.put(elem.getName(), elem);
			}
			
			List list= dialog.getLoadedLibraries();
			for (int i= 0; i < list.size(); i++) {
				CPUserLibraryElement elem= (CPUserLibraryElement) list.get(i);
				CPUserLibraryElement found= (CPUserLibraryElement) map.get(elem.getName());
				if (found == null) {
					existing.add(elem);
					map.put(elem.getName(), elem);
				} else {
					existing.set(existing.indexOf(found), elem); // replace
				}
			}
			fLibraryList.setElements(existing);
			fLibraryList.selectElements(new StructuredSelection(list));
		}
	}
	
	private void doSave() {
		LoadSaveDialog dialog= new LoadSaveDialog(getShell(), true, fLibraryList.getElements(), fDialogSettings);
		dialog.open();
	}
	
	private boolean canAdd(List list) {
		return getSingleSelectedLibrary(list) != null;
	}

	private boolean canEdit(List list) {
		if (list.size() == 1) {
			return true;
		}
		return false;
	}

	private boolean canRemove(List list) { 
		return !list.isEmpty();
	}
	
	private CPUserLibraryElement getCommonParent(List list) {
		CPUserLibraryElement parent= null;
		for (int i= 0, len= list.size(); i < len; i++) {
			Object curr= list.get(i);
			if (curr instanceof CPListElement) {
				Object elemParent= ((CPListElement) curr).getParentContainer();
				if (parent == null) {
					if (elemParent instanceof CPUserLibraryElement) {
						parent= (CPUserLibraryElement) elemParent;
					} else {
						return null;
					}
				} else if (parent != elemParent) {
					return null;
				}
			} else {
				return null;
			}
		}
		return parent;
	}
	
	private void doMoveUp(List list) {
		CPUserLibraryElement parent= getCommonParent(list);
		if (parent != null) {
			parent.moveUp(list);
			fLibraryList.refresh(parent);
			doSelectionChanged(fLibraryList);
		}
	}
	
	private void doMoveDown(List list) {
		CPUserLibraryElement parent= getCommonParent(list);
		if (parent != null) {
			parent.moveDown(list);
			fLibraryList.refresh(parent);
			doSelectionChanged(fLibraryList);
		}
	}
	
	
	private boolean canMoveUp(List list) {
		CPUserLibraryElement parent= getCommonParent(list);
		if (parent != null) {
			CPListElement[] children= parent.getChildren();
			for (int i= 0, len= Math.min(list.size(), children.length); i < len ; i++) {
				if (!list.contains(children[i])) {
					return true;
				}
			}
		}
		return false;
	}
	
	private boolean canMoveDown(List list) {
		CPUserLibraryElement parent= getCommonParent(list);
		if (parent != null) {
			CPListElement[] children= parent.getChildren();
			for (int i= children.length - 1, end= Math.max(0, children.length - list.size()); i >= end; i--) {
				if (!list.contains(children[i])) {
					return true;
				}
			}
		}
		return false;
	}
	

	private CPListElement[] openExtJarFileDialog(CPListElement existing, Object parent) {
		String lastUsedPath;
		if (existing != null) {
			lastUsedPath= existing.getPath().removeLastSegments(1).toOSString();
		} else {
			lastUsedPath= fDialogSettings.get(IUIConstants.DIALOGSTORE_LASTEXTJAR);
			if (lastUsedPath == null) {
				lastUsedPath= ""; //$NON-NLS-1$
			}
		}
		String title= (existing == null) ? PreferencesMessages.UserLibraryPreferencePage_browsejar_new_title : PreferencesMessages.UserLibraryPreferencePage_browsejar_edit_title; 
		
		FileDialog dialog= new FileDialog(getShell(), existing == null ? SWT.MULTI : SWT.SINGLE);
		dialog.setText(title);
		dialog.setFilterExtensions(new String[] {"*.jar;*.zip"}); //$NON-NLS-1$
		dialog.setFilterPath(lastUsedPath);
		if (existing != null) {
			dialog.setFileName(existing.getPath().lastSegment());
		}
		
		String res= dialog.open();
		if (res == null) {
			return null;
		}
		String[] fileNames= dialog.getFileNames();
		int nChosen= fileNames.length;
			
		IPath filterPath= Path.fromOSString(dialog.getFilterPath());
		CPListElement[] elems= new CPListElement[nChosen];
		for (int i= 0; i < nChosen; i++) {
			IPath path= filterPath.append(fileNames[i]).makeAbsolute();	
			CPListElement curr= new CPListElement(parent, null, IClasspathEntry.CPE_LIBRARY, path, null);
			curr.setAttribute(CPListElement.SOURCEATTACHMENT, BuildPathSupport.guessSourceAttachment(curr));
			curr.setAttribute(CPListElement.JAVADOC, BuildPathSupport.guessJavadocLocation(curr));
			elems[i]= curr;
		}
		fDialogSettings.put(IUIConstants.DIALOGSTORE_LASTEXTJAR, dialog.getFilterPath());
		
		return elems;
	}

	
	private class UserLibraryAdapter implements ITreeListAdapter {
		
		private final Object[] EMPTY= new Object[0];

		public void customButtonPressed(TreeListDialogField field, int index) {
			doCustomButtonPressed(field, index);
		}

		public void selectionChanged(TreeListDialogField field) {
			doSelectionChanged(field);
		}
		
		public void doubleClicked(TreeListDialogField field) {
			doDoubleClicked(field);
		}

		public void keyPressed(TreeListDialogField field, KeyEvent event) {
			doKeyPressed(field, event);
		}

		public Object[] getChildren(TreeListDialogField field, Object element) {
			if (element instanceof CPUserLibraryElement) {
				CPUserLibraryElement elem= (CPUserLibraryElement) element;
				return elem.getChildren();
			} else if (element instanceof CPListElement) {
				return ((CPListElement)element).getChildren(false);
			} else if (element instanceof CPListElementAttribute) {
				CPListElementAttribute attribute= (CPListElementAttribute) element;
				if (CPListElement.ACCESSRULES.equals(attribute.getKey())) {
					return (IAccessRule[]) attribute.getValue();
				}
			}
			return EMPTY;
		}

		public Object getParent(TreeListDialogField field, Object element) {
			if (element instanceof CPListElementAttribute) {
				return ((CPListElementAttribute) element).getParent();
			} else if (element instanceof CPListElement) {
				return ((CPListElement) element).getParentContainer();
			} 
			return null;
		}

		public boolean hasChildren(TreeListDialogField field, Object element) {
			return getChildren(field, element).length > 0;
		}
				
	}

	
}
