/*******************************************************************************
 * Copyright (c) 2005, 2007 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
 *	   David Schneider, david.schneider@unisys.com - [142500] WTP properties pages fonts don't follow Eclipse preferences
 *******************************************************************************/
/*
 * Created on Jan 17, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package org.eclipse.jst.j2ee.internal;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.Manifest;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jst.j2ee.application.internal.operations.ClassPathSelection;
import org.eclipse.jst.j2ee.application.internal.operations.ClasspathElement;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.jst.j2ee.classpathdep.UpdateClasspathAttributeUtil;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifestImpl;
import org.eclipse.jst.j2ee.internal.common.ClasspathModel;
import org.eclipse.jst.j2ee.internal.common.ClasspathModelEvent;
import org.eclipse.jst.j2ee.internal.common.ClasspathModelListener;
import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathUpdater;
import org.eclipse.jst.j2ee.internal.listeners.IValidateEditListener;
import org.eclipse.jst.j2ee.internal.listeners.ValidateEditListener;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.UnresolveableURIException;
import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;
import org.eclipse.wst.common.frameworks.internal.ui.WTPUIPlugin;
import org.eclipse.wst.common.frameworks.internal.ui.WorkspaceModifyComposedOperation;

/**
 * @author jialin
 * 
 * TODO To change the template for this generated type comment go to Window - Preferences - Java -
 * Code Style - Code Templates
 */
public class JARDependencyPropertiesPage implements IJ2EEDependenciesControl, IClasspathTableOwner, Listener, ClasspathModelListener, IElementChangedListener {

	protected final IProject project;
	protected final J2EEDependenciesPage propPage;
	protected IOException caughtManifestException;
	protected boolean isDirty;
	protected Text classPathText;
	protected Text componentNameText;
	protected ClasspathModel model;
	protected CCombo availableAppsCombo;
	protected ClasspathTableManager tableManager;
	protected IValidateEditListener validateEditListener;
	protected Label manifestLabel;
	protected Label enterpriseApplicationLabel;
	protected Label availableDependentJars;
	private final Display display;
	private boolean isDisposed = false;
	
	/**
	 * Constructor for JARDependencyPropertiesControl
	 */
	public JARDependencyPropertiesPage(final IProject project, final J2EEDependenciesPage page) {
		super();
		J2EEComponentClasspathUpdater.getInstance().pauseUpdates();
		this.project = project;
		this.propPage = page;
		this.display = propPage.getShell().getDisplay();
	}

	/**
	 * Returns false if page should not be displayed for the project.
	 */
	protected void initialize() {
		model = createClasspathModel();
		model.setProject(project);
		if (model.getComponent() != null) {
			model.addListener(this);
			updateModelManifest();
			initializeValidateEditListener();
		}
	}

	protected ClasspathModel createClasspathModel(){
		return new ClasspathModel(null, false);
	}

	public void dispose() {
		isDisposed = true;
		JavaCore.removeElementChangedListener(this);
		J2EEComponentClasspathUpdater.getInstance().resumeUpdates();
		if (model.earArtifactEdit != null) {
			model.earArtifactEdit.dispose();
			model.earArtifactEdit = null;
		}
	}

	private void updateModelManifest() {
		if (JemProjectUtilities.isBinaryProject(project) || model.getAvailableEARComponents().length == 0)
			return;
		
		IVirtualComponent component = ComponentCore.createComponent(project);
		if(component != null){
			IVirtualFile vManifest = component.getRootFolder().getFile(new Path(J2EEConstants.MANIFEST_URI));
			if(vManifest.exists()){
				IFile iManifest = vManifest.getUnderlyingFile();
				if(iManifest != null && iManifest.exists()){
					InputStream in = null;
					try {
						in = iManifest.getContents();
						ArchiveManifest mf = new ArchiveManifestImpl(new Manifest(in));
						model.primSetManifest(mf);
					} catch (CoreException e) {
						Logger.getLogger().logError(e);
						model.primSetManifest(new ArchiveManifestImpl());
					} catch (IOException iox) {
						Logger.getLogger().logError(iox);
						model.primSetManifest(new ArchiveManifestImpl());
						caughtManifestException = iox;
					} finally {
						if (in != null) {
							try {
								in.close();
							} catch (IOException weTried) {
								// Ignore
							}
						}
					}
				}
			}
		}
	}


	protected void initializeValidateEditListener() {
		validateEditListener = new ValidateEditListener(null, model);
		validateEditListener.setShell(propPage.getShell());
	}

	public void setVisible(boolean visible) {
		if (visible) {
			if (caughtManifestException != null && !model.isDirty()) {
				ManifestErrorPrompter.showManifestException(propPage.getShell(), ERROR_READING_MANIFEST_DIALOG_MESSAGE_PROP_PAGE, false, caughtManifestException);
			}
		}
	}

	/**
	 * Refreshes the ClasspathModel if the project classpath is changed.
	 */
	public void elementChanged(final ElementChangedEvent event) {
		if (event.getType() == ElementChangedEvent.POST_CHANGE && classpathChanged(event.getDelta())) {
			// trigger a recomputation and refresh for the currently selected EAR
			if (!isDisposed) {
				display.asyncExec (new Runnable () {
					public void run () {
						if (!isDisposed) {
							handleClasspathChange();
						}
					}
				});
			}
		}
	}
	
	/**
	 * Called to refresh the UI when the classpath changes
	 */
	protected void handleClasspathChange() {
		model.resetClassPathSelection();
		refresh();		
	}
	
	private boolean classpathChanged(final IJavaElementDelta delta) {
		final int kind = delta.getKind();
		if (kind == IJavaElementDelta.CHANGED) {
			final int flags = delta.getFlags();
			final IJavaElement element = delta.getElement();
			if (element instanceof IJavaModel) {
				if ((flags & IJavaElementDelta.F_CHILDREN) == IJavaElementDelta.F_CHILDREN) {
					final IJavaElementDelta[] children = delta.getChangedChildren();
					for (int i = 0; i < children.length; i++) {
						// check all of the IJavaProject children
						if (classpathChanged(children[i])) {
							return true;
						}
					}
				}
			} else if (element instanceof IJavaProject) {
				// check if we either have a direct indication of a classpath change or a delta on the
				// .classpath file (changes to classpath entry attributes only give us this...)
				final IJavaProject jproject = (IJavaProject) element;
				final IProject eventProject = jproject.getProject();
				if (eventProject.equals(project)) {
					if ((flags & IJavaElementDelta.F_CLASSPATH_CHANGED) != 0) {
						return true; 	
					}
					final IResourceDelta[] deltas = delta.getResourceDeltas();
					if (deltas != null) {
						for (int i = 0; i < deltas.length; i++) {
							if (deltas[i].getProjectRelativePath().toString().equals(".classpath")) { //$NON-NLS-1$
								return true;
							}
						}
					}
				}
			}
		}
		return false;
	}

	public Composite createContents(Composite parent) {
		initialize();
		Composite composite = createBasicComposite(parent);
		GridLayout layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginWidth = 0;
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		if (model.getComponent() != null) {
			if (!isValidComponent())
				return composite;
			J2EEDependenciesPage.createDescriptionComposite(composite, ManifestUIResourceHandler.J2EE_Modules_Desc);
			createProjectLabelsGroup(composite);
			createListGroup(composite);
			createTextGroup(composite);
			refresh();
		}
	    Dialog.applyDialogFont(parent);
	    postCreateContents();
		return composite;
	}

	/**
	 * Called at the end of createContents().
	 */
	protected void postCreateContents() {
		// register this object as an IElementChangedListener so that it will react to user changes to the Java build path
		JavaCore.addElementChangedListener(this);	
	}
	
	/**
	 * @param comp
	 * @return
	 */
	protected Composite createBasicComposite(Composite comp) {
		Composite composite = new Composite(comp, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginWidth = 0;
		composite.setLayout(layout);
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
		return composite;
	}

	protected boolean isValidComponent() {
		if (J2EEProjectUtilities.isEARProject(project)) {
			propPage.setErrorMessage(ManifestUIResourceHandler.EAR_Module_Dep_Error);
			return false;
		} else if (J2EEProjectUtilities.isStandaloneProject(model.getComponent().getProject())) {
			propPage.setErrorMessage(ClasspathModel.NO_EAR_MESSAGE);
			return false;
		}
		return true;
	}

	protected void createProjectLabelsGroup(Composite parent) {

		Composite labelsGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		labelsGroup.setLayout(layout);
		labelsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		/*
		 * Label label = new Label(labelsGroup, SWT.NONE);
		 * label.setText(ManifestUIResourceHandler.Project_name__UI_);
		 * 
		 * componentNameText = new Text(labelsGroup, SWT.BORDER); GridData data = new
		 * GridData(GridData.FILL_HORIZONTAL); componentNameText.setEditable(false);
		 * componentNameText.setLayoutData(data); componentNameText.setText(project.getName());
		 */

		createEnterpriseAppsControls(labelsGroup);

	}

	private void createEnterpriseAppsControls(Composite labelsGroup) {

		enterpriseApplicationLabel = new Label(labelsGroup, SWT.NONE);
		enterpriseApplicationLabel.setText(ManifestUIResourceHandler.EAR_Project_Name__UI__UI_);

		availableAppsCombo = new CCombo(labelsGroup, SWT.READ_ONLY | SWT.BORDER);
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		availableAppsCombo.setLayoutData(gd);

		availableAppsCombo.addListener(SWT.Selection, this);

	}

	protected void createListGroup(Composite parent) {
		Composite listGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		listGroup.setLayout(layout);
		GridData gData = new GridData(GridData.FILL_BOTH);
		gData.horizontalIndent = 5;
		listGroup.setLayoutData(gData);

		availableDependentJars = new Label(listGroup, SWT.NONE);
		gData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
		availableDependentJars.setText(ManifestUIResourceHandler.Available_dependent_JARs__UI_);
		availableDependentJars.setLayoutData(gData);
		createTableComposite(listGroup);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.etools.j2ee.common.ui.classpath.IClasspathTableOwner#createGroup(org.eclipse.swt.widgets.Composite)
	 */
	public Group createGroup(Composite parent) {
		return new Group(parent, SWT.NULL);
	}

	protected void createTextGroup(Composite parent) {

		Composite textGroup = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		textGroup.setLayout(layout);
		textGroup.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL));

		createClassPathText(textGroup);

	}

	protected void createClassPathText(Composite textGroup) {

		manifestLabel = new Label(textGroup, SWT.NONE);
		manifestLabel.setText(ManifestUIResourceHandler.Manifest_Class_Path__UI_);

		classPathText = new Text(textGroup, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
		GridData gData = new GridData(GridData.FILL_BOTH);
		gData.widthHint = 400;
		gData.heightHint = 100;
		classPathText.setLayoutData(gData);
		classPathText.setEditable(false);
	}

	protected void createTableComposite(Composite parent) {
		Composite composite = new Composite(parent, SWT.NONE);
		GridData gData = new GridData(GridData.FILL_BOTH);
		composite.setLayoutData(gData);
		tableManager = new ClasspathTableManager(this, model, validateEditListener);
		tableManager.setReadOnly(isReadOnly());
		tableManager.fillComposite(composite);
	}

	/**
	 * @see IClasspathTableOwner#createAvailableJARsViewer(Composite)
	 */
	public CheckboxTableViewer createAvailableJARsViewer(Composite parent) {
		int flags = SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI;

		Table table = new Table(parent, flags);
		CheckboxTableViewer availableJARsViewer = new CheckboxTableViewer(table);

		// set up table layout
		TableLayout tableLayout = new org.eclipse.jface.viewers.TableLayout();
		tableLayout.addColumnData(new ColumnWeightData(200, true));
		tableLayout.addColumnData(new ColumnWeightData(200, true));
		table.setLayout(tableLayout);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		
		// do not create sorter otherwise order will go wrong
		//availableJARsViewer.setSorter(new ViewerSorter());
		
		// table columns
		TableColumn fileNameColumn = new TableColumn(table, SWT.NONE, 0);
		fileNameColumn.setText(ManifestUIResourceHandler.JAR_Module_UI_);
		fileNameColumn.setResizable(true);

		TableColumn projectColumn = new TableColumn(table, SWT.NONE, 1);
		projectColumn.setText(ManifestUIResourceHandler.Project_UI_);
		projectColumn.setResizable(true);
		tableLayout.layout(table, true);
		return availableJARsViewer;

	}

	/**
	 * @see IClasspathTableOwner#createButtonColumnComposite(Composite)
	 */
	public Composite createButtonColumnComposite(Composite parent) {
		Composite buttonColumn = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		buttonColumn.setLayout(layout);
		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING);
		buttonColumn.setLayoutData(data);
		return buttonColumn;
	}

	/**
	 * @see IClasspathTableOwner
	 */
	public Button primCreatePushButton(String label, Composite buttonColumn) {
		Button aButton = new Button(buttonColumn, SWT.PUSH);
		aButton.setText(label);
		return aButton;
	}

	/**
	 * @see IClasspathTableOwner
	 */
	public Button primCreateRadioButton(String label, Composite parent) {
		Button aButton = new Button(parent, SWT.RADIO);
		aButton.setText(label);
		return aButton;
	}

	/**
	 * @see Listener#handleEvent(Event)
	 */
	public void handleEvent(Event event) {
		if (event.widget == availableAppsCombo)
			availableAppsSelected(event);
	}

	protected void availableAppsSelected(Event event) {
		int index = availableAppsCombo.getSelectionIndex();
		model.selectEAR(index);
	}

	protected void populateApps() {
		IVirtualComponent[] components = model.getAvailableEARComponents();
		String[] values = new String[components.length];
		for (int i = 0; i < components.length; i++) {
			values[i] = components[i].getProject().getName();
		}
		if (availableAppsCombo != null) {
			availableAppsCombo.setItems(values);
			IVirtualComponent selected = model.getSelectedEARComponent();
			if (selected != null) {
				int index = Arrays.asList(components).indexOf(selected);
				availableAppsCombo.select(index);
			} else
				availableAppsCombo.clearSelection();
		}
	}

	protected void refresh() {
		populateApps();
		if (tableManager != null) {
			tableManager.refresh();
		}
		refreshText();
	}


	public void refreshText() {
		ClassPathSelection sel = model.getClassPathSelection();
		if (sel != null && classPathText != null)
			classPathText.setText(sel == null ? "" : sel.toString()); //$NON-NLS-1$
	}

	/**
	 * @see ClasspathModelListener#modelChanged(ClasspathModelEvent)
	 */
	public void modelChanged(ClasspathModelEvent evt) {
		if (evt.getEventType() == ClasspathModelEvent.CLASS_PATH_CHANGED) {
			isDirty = true;
			refreshText();
		} else if (evt.getEventType() == ClasspathModelEvent.EAR_PROJECT_CHANGED) {			
			tableManager.refresh();
		}
	}

	public void performDefaults() {
		model.resetClassPathSelection();
		refresh();
		isDirty = false;
		model.dispose();
	}

	public boolean performCancel() {
		model.dispose();
		return true;
	}

	/**
	 * @see org.eclipse.jface.preference.IPreferencePage#performOk()
	 */
	public boolean performOk() {
		if (!isDirty)
			return true;
		WorkspaceModifyComposedOperation composed = new WorkspaceModifyComposedOperation(createManifestOperation());
		createClasspathAttributeUpdateOperation(composed, model.getClassPathSelection(), false);
		try {
			new ProgressMonitorDialog(propPage.getShell()).run(true, true, composed);
		} catch (InvocationTargetException ex) {
			String title = ManifestUIResourceHandler.An_internal_error_occurred_ERROR_;
			String msg = title;
			if (ex.getTargetException() != null && ex.getTargetException().getMessage() != null)
				msg = ex.getTargetException().getMessage();
			MessageDialog.openError(propPage.getShell(), title, msg);
			org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ex);
			return false;
		} catch (InterruptedException e) {
			// cancelled
			return false;
		} finally {
			model.dispose();
		}
		isDirty = false;
		return true;
	}

	// private boolean runWLPOp(WorkspaceModifyComposedOperation composed) {
	// try {
	// if (composed != null)
	// new ProgressMonitorDialog(getShell()).run(true, true, composed);
	// } catch (InvocationTargetException ex) {
	// String title = ManifestUIResourceHandler.getString("An_internal_error_occurred_ERROR_");
	// //$NON-NLS-1$
	// String msg = title;
	// if (ex.getTargetException() != null && ex.getTargetException().getMessage() != null)
	// msg = ex.getTargetException().getMessage();
	// MessageDialog.openError(this.getShell(), title, msg);
	// org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ex);
	// return false;
	// } catch (InterruptedException e) {
	// // cancelled
	// return false;
	// }
	// return true;
	// }


	List getUnSelectedClassPathElementsForJ2EEDependency() {
		List unselectedForJ2EE = getUnSelectedClassPathSelection().getClasspathElements();

		List unselected = new ArrayList();
		if (model != null && model.getClassPathSelectionForWLPs() != null) {
			List wlpSelected = model.getClassPathSelectionForWLPs().getSelectedClasspathElements();

			java.util.Iterator it = unselectedForJ2EE.iterator();

			while (it.hasNext()) {
				ClasspathElement element = (ClasspathElement) it.next();
				java.util.Iterator wlpIterator = wlpSelected.iterator();
				boolean found = false;
				while (wlpIterator.hasNext()) {
					ClasspathElement wlpElement = (ClasspathElement) wlpIterator.next();
					String text = element.getText();
					int index = text.indexOf(".jar");
					if (index != -1) {
						text = text.substring(0, index);
						if (text.equals(wlpElement.getText())) {
							found = true;
							break;
						}
					}
				}
				if (!found) {
					if (!unselected.contains(element))
						unselected.add(element);
				}

			}
		}
		return unselected;
	}


	/**
	 * @deprecated don't use this method it will be deleted
	 * @return
	 */
	List getUnSelectedClassPathElementsForWebDependency() {
		List unselectedForWLP = getUnSelectedClassPathSelectionForWLPs().getClasspathElements();
		List unselected = new ArrayList();
		if (model != null && model.getClassPathSelection() != null) {
			List j2eeSelected = model.getClassPathSelection().getSelectedClasspathElements();
			java.util.Iterator it = unselectedForWLP.iterator();

			while (it.hasNext()) {
				ClasspathElement element = (ClasspathElement) it.next();
				java.util.Iterator j2eeIterator = j2eeSelected.iterator();
				boolean found = false;
				while (j2eeIterator.hasNext()) {
					ClasspathElement j2eeElement = (ClasspathElement) j2eeIterator.next();
					String text = j2eeElement.getText();
					int index = text.indexOf(".jar");
					if( index != -1 ){
						text = text.substring(0, index);
						if (element.getText().equals(text)) {
							found = true;
							break;
						}
					}
				}
				if (!found) {
					if (!unselected.contains(element))
						unselected.add(element);
				}

			}
		} else {
			unselected = unselectedForWLP;
		}
		return unselected;
	}

	/**
	 * DoNotUseMeThisWillBeDeletedPost15
	 * @return
	 */
	protected WorkspaceModifyComposedOperation createJ2EEComponentDependencyOperations() {
		WorkspaceModifyComposedOperation composedOp = null;
		List selected = getSelectedClassPathSelection().getClasspathElements();
		List unselected = getUnSelectedClassPathElementsForJ2EEDependency();

		List targetComponentsHandles = new ArrayList();
		for (int i = 0; i < selected.size(); i++) {
			ClasspathElement element = (ClasspathElement) selected.get(i);
			IVirtualComponent component = element.getComponent();
			if (null != component) {
				targetComponentsHandles.add(component);
			}
		}
		if (!targetComponentsHandles.isEmpty()) {
			composedOp = new WorkspaceModifyComposedOperation();
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(ComponentUtilities.createReferenceComponentOperation(model.getComponent(), targetComponentsHandles)));
		}
		targetComponentsHandles = new ArrayList();
		for (int i = 0; i < unselected.size(); i++) {
			ClasspathElement element = (ClasspathElement) unselected.get(i);
			IProject elementProject = element.getProject();
			if (elementProject != null) {
				if (ModuleCoreNature.isFlexibleProject(elementProject)) {
					IVirtualComponent targetComp = ComponentCore.createComponent(elementProject);
					targetComponentsHandles.add(targetComp);
				}
			} else {
				URI archiveURI = element.getArchiveURI();
				if (archiveURI != null && !archiveURI.equals("")) { //$NON-NLS-1$
					String name = ""; //$NON-NLS-1$
					try {
						String type = ModuleURIUtil.getArchiveType(archiveURI);
						String tmpname = ModuleURIUtil.getArchiveName(archiveURI);
						name = type + IPath.SEPARATOR + tmpname;
					} catch (UnresolveableURIException e) {
						Logger.getLogger().logError(e.getMessage());
					}
					if (!name.equals("")) { //$NON-NLS-1$
						IVirtualReference ref = model.getComponent().getReference(name);
						if (ref != null) {
							IVirtualComponent referenced = ref.getReferencedComponent();
							targetComponentsHandles.add(referenced);
						}
					}
				}
			}
		}
		if (!targetComponentsHandles.isEmpty()) {
			if (composedOp == null)
				composedOp = new WorkspaceModifyComposedOperation();
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(ComponentUtilities.removeReferenceComponentOperation(model.getComponent(), targetComponentsHandles)));
		}
		return composedOp;
	}


	/**
	 * This should be moved to the {@link WebLibDependencyPropertiesPage} because it is only used there.
	 * @return
	 */
	protected WorkspaceModifyComposedOperation createComponentDependencyOperations() {
		WorkspaceModifyComposedOperation composedOp = null;
		final ClassPathSelection selectedWLPs = getSelectedClassPathSelectionForWLPs();
		List selected = selectedWLPs.getClasspathElements();
		List unselected = getUnSelectedClassPathSelectionForWLPs().getClasspathElements();

		List targetComponentsHandles = new ArrayList();
		for (int i = 0; i < selected.size(); i++) {
			ClasspathElement element = (ClasspathElement) selected.get(i);
			if (element.isClasspathDependency() || element.isClasspathEntry()) {
				continue;
			}
			IProject elementProject = element.getProject();
			if (elementProject != null) {
				IVirtualComponent targetComp = ComponentCore.createComponent(elementProject);
				targetComponentsHandles.add(targetComp);
			}
		}
		if (!targetComponentsHandles.isEmpty()) {
			composedOp = new WorkspaceModifyComposedOperation();
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(ComponentUtilities.createWLPReferenceComponentOperation(model.getComponent(), targetComponentsHandles)));
		}
		targetComponentsHandles = new ArrayList();
		for (int i = 0; i < unselected.size(); i++) {
			ClasspathElement element = (ClasspathElement) unselected.get(i);
			if (element.isClasspathDependency() || element.isClasspathEntry()) {
				continue;
			}
			IProject elementProject = element.getProject();
			if (elementProject != null) {
				if (ModuleCoreNature.isFlexibleProject(elementProject)) {
					IVirtualComponent targetComp = ComponentCore.createComponent(elementProject);
					targetComponentsHandles.add(targetComp);
				}
			} else {
				URI archiveURI = element.getArchiveURI();
				if (archiveURI != null && !archiveURI.equals("")) { //$NON-NLS-1$
					String name = ""; //$NON-NLS-1$
					try {
						String type = ModuleURIUtil.getArchiveType(archiveURI);
						String tmpname = ModuleURIUtil.getArchiveName(archiveURI);
						name = type + IPath.SEPARATOR + tmpname;
					} catch (UnresolveableURIException e) {
						Logger.getLogger().logError(e.getMessage());
					}
					if (!name.equals("")) { //$NON-NLS-1$
						IVirtualReference ref = model.getComponent().getReference(name);
						IVirtualComponent referenced = ref.getReferencedComponent();
						targetComponentsHandles.add(referenced);
					}
				}
			}
		}
		if (!targetComponentsHandles.isEmpty()) {
			if (composedOp == null) {
				composedOp = new WorkspaceModifyComposedOperation();
			}
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(ComponentUtilities.removeWLPReferenceComponentOperation(model.getComponent(), targetComponentsHandles)));
		}

		if (composedOp == null) {
			composedOp = new WorkspaceModifyComposedOperation();
		}
		createClasspathAttributeUpdateOperation(composedOp, model.getClassPathSelectionForWLPs(), true);
		
		return composedOp;
	}

	protected WorkspaceModifyComposedOperation createFlexProjectOperations() {
		WorkspaceModifyComposedOperation composedOp = null;
		try {
			Object[] elements = tableManager.availableJARsViewer.getCheckedElements();
			for (int i = 0; i < elements.length; i++) {
				ClasspathElement element = (ClasspathElement) elements[i];
				IProject elementProject = element.getProject();
				if (elementProject != null && !elementProject.hasNature(IModuleConstants.MODULE_NATURE_ID)) {
					if (composedOp == null)
						composedOp = new WorkspaceModifyComposedOperation();
					composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(J2EEProjectUtilities.createFlexJavaProjectForProjectOperation(elementProject, false)));
				}
			}
		} catch (CoreException ce) {
		}
		return composedOp;
	}

	protected ClassPathSelection getUnSelectedClassPathSelectionForWLPs() {
		ClassPathSelection selection = new ClassPathSelection();
		Object[] checkedElements = tableManager.availableJARsViewer.getCheckedElements();
		List modelElements = model.getClassPathSelectionForWLPs().getClasspathElements();
		for (int i = 0; i < modelElements.size(); i++) {
			List checkedElementsList = Arrays.asList(checkedElements);
			if (!checkedElementsList.contains(modelElements.get(i))) {
				selection.getClasspathElements().add(modelElements.get(i));
			}
		}
		return selection;
	}

	private ClassPathSelection getSelectedClassPathSelection() {
		ClassPathSelection selection = new ClassPathSelection();
		Object[] checkedElements = tableManager.availableJARsViewer.getCheckedElements();
		for (int i = 0; i < checkedElements.length; i++) {
			selection.getClasspathElements().add(checkedElements[i]);
		}
		return selection;
	}

	protected ClassPathSelection getUnSelectedClassPathSelection() {
		ClassPathSelection selection = new ClassPathSelection();
		Object[] checkedElements = tableManager.availableJARsViewer.getCheckedElements();
		List modelElements = model.getClassPathSelection().getClasspathElements();
		for (int i = 0; i < modelElements.size(); i++) {
			List checkedElementsList = Arrays.asList(checkedElements);
			if (!checkedElementsList.contains(modelElements.get(i))) {
				selection.getClasspathElements().add(modelElements.get(i));
			}
		}
		return selection;
	}


	private ClassPathSelection getSelectedClassPathSelectionForWLPs() {
		ClassPathSelection selection = new ClassPathSelection();
		Object[] checkedElements = tableManager.availableJARsViewer.getCheckedElements();
		for (int i = 0; i < checkedElements.length; i++) {
			selection.getClasspathElements().add(checkedElements[i]);
		}
		return selection;
	}

	protected UpdateManifestOperation createManifestOperation() {
		return new UpdateManifestOperation(project.getName(), model.getClassPathSelection().toString(), true);
	}
	
	protected void createClasspathAttributeUpdateOperation(final WorkspaceModifyComposedOperation composedOp, final ClassPathSelection selection, final boolean isWebApp) {
		final Map selectedEntriesToRuntimePath = new HashMap();
		final Map unselectedEntriesToRuntimePath = new HashMap();
		final List elements = selection.getClasspathElements();
		for (int i = 0; i < elements.size(); i++) {
			final ClasspathElement element = (ClasspathElement) elements.get(i);
			if (element.isClasspathEntry()) {
				final IClasspathEntry entry = element.getClasspathEntry();
				final IClasspathAttribute attrib = ClasspathDependencyUtil.checkForComponentDependencyAttribute(entry);
				boolean hasDepAttrib = false;
				if (attrib != null && attrib.getName().equals(IClasspathDependencyConstants.CLASSPATH_COMPONENT_DEPENDENCY)) {
					hasDepAttrib = true;
				}
				final IPath runtimePath = ClasspathDependencyUtil.getRuntimePath(attrib, isWebApp, ClasspathDependencyUtil.isClassFolderEntry(entry));
				if (element.isSelected()) {
					// only add if we don't already have the attribute
					if (!hasDepAttrib) {
						selectedEntriesToRuntimePath.put(entry, runtimePath);
					}
				} else {
					// only add if we already have the attribute
					if (hasDepAttrib) {
						unselectedEntriesToRuntimePath.put(entry, runtimePath);
					}
				}
			}
		}
		
		// if there are any attributes to add, create an operation to add all necessary attributes 
		if (!selectedEntriesToRuntimePath.isEmpty()) {
			IDataModelOperation op = UpdateClasspathAttributeUtil.createAddDependencyAttributesOperation(project.getName(), selectedEntriesToRuntimePath); 
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(op));
		}
		// if there are any attributes to remove, create an operation to remove all necessary attributes
		if (!unselectedEntriesToRuntimePath.isEmpty()) {
			IDataModelOperation op = UpdateClasspathAttributeUtil.createRemoveDependencyAttributesOperation(project.getName(), unselectedEntriesToRuntimePath); 
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(op));
		}
	}

	protected boolean isReadOnly() {
		return JemProjectUtilities.isBinaryProject(project);
	}

}
