/*******************************************************************************
 * Copyright (c) 2003, 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
 *******************************************************************************/
package org.eclipse.jst.j2ee.application.internal.operations;



import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
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.IClasspathAttribute;
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.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Container;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.ManifestException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.commonarchivecore.internal.impl.CommonarchiveFactoryImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategy;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.ZipFileLoadStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.internal.archive.operations.ComponentLoadStrategyImpl;
import org.eclipse.jst.j2ee.internal.archive.operations.EARComponentLoadStrategyImpl;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.javaee.ejb.EJBJar;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.UnresolveableURIException;
import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;



public class ClassPathSelection {
	protected Archive archive;
	protected org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest manifest;
	protected IVirtualComponent component;
	protected IProject earProject;
	protected IVirtualComponent earComponent;
	protected List classpathElements;
	protected Map urisToElements;
	protected boolean modified;
	private String targetProjectName;
	protected Map ejbToClientJARs = null;
	protected Map clientToEJBJARs = null;
	public static final int FILTER_EJB_SERVER_JARS = 0;
	public static final int FILTER_EJB_CLIENT_JARS = 1;
	public static final int FILTER_NONE = 2;

	protected int filterLevel = 2;

	protected static Comparator comparator = new Comparator() {
		/**
		 * @see Comparator#compare(Object, Object)
		 */
		public int compare(Object o1, Object o2) {
			int retVal = 0;
			if (o1 instanceof Archive)
			{
				Archive a1 = (Archive) o1;
				Archive a2 = (Archive) o2;
				retVal = a1.getURI().compareTo(a2.getURI());
			}
			else if (o1 instanceof IVirtualReference)
			{
				IVirtualReference ref1 = (IVirtualReference) o1;
				IVirtualReference ref2 = (IVirtualReference) o2;
				retVal = ref1.getArchiveName().compareTo(ref2.getArchiveName());
			}
			else
			{
				retVal = o1.toString().compareTo(o2.toString());
			}
			return retVal;
		}
	};

	public ClassPathSelection(Archive anArchive, String targetProjectName, EARFile earFile) {
		super();
		archive = anArchive;
		this.targetProjectName = targetProjectName;
		initializeEARProject(earFile);
		initializeElements();
	}

	/**
	 * ClassPathSelection constructor comment.
	 */
	public ClassPathSelection(Archive anArchive, EARFile earFile) {
		super();
		archive = anArchive;
		initializeEARProject(earFile);
		initializeElements();
	}

	/**
	 * Creates without an EAR component.
	 */
	public ClassPathSelection(IVirtualComponent aComponent) {
		super();
		component = aComponent;
		targetProjectName = aComponent.getProject().getName();
		initializeElements();
	}
	
	/**
	 * ClassPathSelection constructor comment.
	 */
	public ClassPathSelection(IVirtualComponent aComponent, IVirtualComponent anEarComponent) {
		this(aComponent);
		earComponent = anEarComponent;
		earProject = earComponent.getProject();
		initializeElements();
	}

	/**
	 * ClassPathSelection constructor comment.
	 */
	public ClassPathSelection() {
		super();
	}

	protected ClasspathElement createElement(Archive referencingArchive, Archive referencedArchive, String cpEntry) {
		ClasspathElement element = new ClasspathElement(referencingArchive);
		element.setValid(true);
				
		String uriString = referencedArchive.getURI();
		URI uri = URI.createURI(uriString);

		boolean hasAbsolutePath = uri.hasAbsolutePath();
		if( hasAbsolutePath ){
			uriString = uri.lastSegment();
		}
		
		//element.setText(referencedArchive.getURI());
		element.setText(uriString);
		element.setTargetArchive(referencedArchive);
		element.setEarProject(earProject);
		if( earComponent != null ){
			IContainer earConentFolder = earComponent.getRootFolder().getUnderlyingFolder();
			if( earConentFolder.getType() == IResource.FOLDER ){
				element.setEarContentFolder( earConentFolder.getName());
			}else {
				element.setEarContentFolder( "" );
			}
		}
	
		setProjectValues(element, referencedArchive);
		if (cpEntry != null)
			element.setValuesSelected(cpEntry);
		setType(element, referencedArchive);
		return element;
	}

	protected ClasspathElement createElement(IVirtualComponent referencingArchive, IVirtualReference referencedArchive, String cpEntry) {
		ClasspathElement element = new ClasspathElement(referencingArchive);
		element.setValid(true);
				
		String uriString = referencedArchive.getArchiveName();
		
		element.setText(uriString);
		element.setTargetComponent(referencedArchive.getReferencedComponent());
		element.setEarProject(earProject);
		if( earComponent != null ){
			IContainer earConentFolder = earComponent.getRootFolder().getUnderlyingFolder();
			if( earConentFolder.getType() == IResource.FOLDER ){
				element.setEarContentFolder( earConentFolder.getName());
			}else {
				element.setEarContentFolder( "" );
			}
		}
	
		setProjectValues(element, referencedArchive);
		if (cpEntry != null)
			element.setValuesSelected(cpEntry);
		setType(element, referencedArchive);
		return element;
	}

	protected ClasspathElement createInvalidElement(String cpEntry) {
		ClasspathElement element = new ClasspathElement(archive);
		element.setValid(false);
		element.setSelected(true);
		element.setRelativeText(cpEntry);
		element.setText(cpEntry);
		element.setEarProject(earProject);
		setInvalidProject(element);
		return element;
	}
	
	public ClasspathElement createProjectElement(IProject project) {
		ClasspathElement element = new ClasspathElement(project);
		element.setValid(true);
		element.setSelected(true);
		element.setText(project.getName());
		element.setProject(project);
		addClasspathElement(element,element.getProjectName());
		return element;
	}
	
	public ClasspathElement createProjectElement(IProject project, boolean existingEntry ) {
		ClasspathElement element = new ClasspathElement(project);
		element.setValid(true);
		element.setSelected(existingEntry);
		element.setText(project.getName());
		element.setProject(project);
		addClasspathElement(element,element.getProjectName());
		return element;
	}
	
	
	public ClasspathElement createArchiveElement(URI uri, String name, String cpEntry) {
		ClasspathElement element = new ClasspathElement(uri);
		element.setValid(false);
		element.setRelativeText(name);
		if (cpEntry != null)
			element.setValuesSelected(cpEntry);		
		element.setText(name);
		element.setEarProject(earProject);
		return element;
	}
	
	public void buildClasspathComponentDependencyMap(final IVirtualComponent comp, final Map pathToComp) {
		if (comp != null && comp instanceof J2EEModuleVirtualComponent) {
			J2EEModuleVirtualComponent j2eeComp = (J2EEModuleVirtualComponent) comp;
			IVirtualReference[] cpRefs = j2eeComp.getJavaClasspathReferences();

			for (int i = 0; i < cpRefs.length; i++) {
				// only ../ mappings supported at this level
				if (!cpRefs[i].getRuntimePath().equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH)) {
					continue;
				}
				
				final IVirtualComponent referencedComponent = cpRefs[i].getReferencedComponent();
				final IPath path = ClasspathDependencyUtil.getClasspathVirtualReferenceLocation(cpRefs[i]); 
				final IVirtualComponent existingComp = (IVirtualComponent) pathToComp.get(path);
				if (existingComp != null) {
					// replace with a temp VirtualArchiveComponent whose IProject is set to a new pseudo name that is
					// the concatenation of all project contributions for that archive
					if (existingComp instanceof VirtualArchiveComponent) {
						final VirtualArchiveComponent oldComp = (VirtualArchiveComponent) existingComp;
						final IVirtualComponent newComp = updateDisplayVirtualArchiveComponent(oldComp, cpRefs[i]);
						pathToComp.put(path, newComp);
					}
				} else {
					pathToComp.put(path, referencedComponent);
				}
			}
		}
	}
	
	/**
	 * Create a new VirtualArchiveComponent (used only for display purposes) whose IProject is set to a dummy value whose
	 * name is a concatentation of the existing name and the name of the project associated with the new ref.
	 * This is used to represent the case where a single unique archive is referenced/contributed by multiple dependent projects.
	 */ 
	public static VirtualArchiveComponent updateDisplayVirtualArchiveComponent(final VirtualArchiveComponent oldComp, final IVirtualReference newRef) {
		final String newProjName = oldComp.getProject().getName() + " " + newRef.getReferencedComponent().getProject().getName();  
		final IProject newProj = ResourcesPlugin.getWorkspace().getRoot().getProject(newProjName);
		final VirtualArchiveComponent newComponent = (VirtualArchiveComponent) ComponentCore.createArchiveComponent(newProj, oldComp.getName());
		return newComponent;
	}
	
	public ClasspathElement[] createClasspathEntryElements(final IVirtualComponent comp, final IPath archiveRuntimePath, final IPath classFolderRuntimePath) throws CoreException {
		final List elements = new ArrayList();
		if (comp != null && comp.getProject().isAccessible()) {
			final IProject project = comp.getProject();
			if (project.hasNature(JavaCore.NATURE_ID)) {
				final IJavaProject javaProject = JavaCore.create(project);
				final boolean isWebApp = J2EEProjectUtilities.isDynamicWebProject(project);
				final Map taggedEntries = ClasspathDependencyUtil.getRawComponentClasspathDependencies(javaProject);
				
				Iterator i = taggedEntries.keySet().iterator();
				while (i.hasNext()) {
					final IClasspathEntry entry = (IClasspathEntry) i.next();
					final IClasspathAttribute attrib = (IClasspathAttribute) taggedEntries.get(entry);
					final boolean isClassFolder = ClasspathDependencyUtil.isClassFolderEntry(entry);
					final IPath runtimePath = ClasspathDependencyUtil.getRuntimePath(attrib, isWebApp, isClassFolder); 
					if (runtimePath != null && ((isClassFolder && !runtimePath.equals(classFolderRuntimePath)) || (!isClassFolder && !runtimePath.equals(archiveRuntimePath)))) {
						// if runtime path does not match target runtime path, skip
						continue;
					}
					final ClasspathElement element = createClasspathElementForEntry(project, entry);
					element.setSelected(true);
					addClasspathElement(element, element.getArchiveURI().toString());
				}
				
				final List potentialEntries = ClasspathDependencyUtil.getPotentialComponentClasspathDependencies(javaProject);
				i = potentialEntries.iterator();
				while (i.hasNext()) {
					final IClasspathEntry entry = (IClasspathEntry) i.next();
					if (isWebApp && classFolderRuntimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_COMPONENT_PATH) && ClasspathDependencyUtil.isClassFolderEntry(entry)) {
						// don't display class folder dependencies for dynamic web projects on the non-web lib dependency page
						continue;
					}
					final ClasspathElement element = createClasspathElementForEntry(project, entry);
					element.setSelected(false);
					addClasspathElement(element, element.getArchiveURI().toString());
				}
			}
		}
		return (ClasspathElement[]) elements.toArray(new ClasspathElement[elements.size()]);
	}

	private ClasspathElement createClasspathElementForEntry(final IProject project, final IClasspathEntry entry) {
		final IPath entryPath = entry.getPath();
		final URI archiveURI = URI.createURI(entryPath.toString());
		final int kind = entry.getEntryKind();
		String elementName = entryPath.toString();
		if (kind == IClasspathEntry.CPE_CONTAINER) {
			try {
				final IClasspathContainer container = JavaCore.getClasspathContainer(entryPath, JavaCore.create(project));
				if (container != null) {
					elementName = container.getDescription();
				}
			} catch (CoreException ce) {
			}
		}

		ClasspathElement element = createClasspathEntryElement(project, archiveURI, elementName, entry);
		return element;
	}
		
	/**
	 * @param element
	 */
	private void setInvalidProject(ClasspathElement element) {
		IProject earProj = element.getEarProject();
		//IVirtualComponent[] component = ComponentUtilities.getComponent(earProj.getName());
		IVirtualComponent refEarComponent = ComponentUtilities.getComponent(earProj.getName());
		
		IVirtualReference[] references = J2EEProjectUtilities.getComponentReferences(refEarComponent);
		String moduleName = element.getRelativeText();
		if(moduleName != null) {
			IVirtualComponent modComponent = null;
			for (int cnt=0; cnt < references.length; cnt++)
			{
				if (moduleName.equals(references[cnt].getArchiveName()))
				{
					modComponent = references[cnt].getReferencedComponent();
				}
			}
			if(modComponent != null) {
				IProject mappedProject = modComponent.getProject();
				element.setProject(mappedProject);
			}
		}
	}

	/**
	 * Insert the method's description here. Creation date: (8/22/2001 1:17:21 PM)
	 * 
	 * @return java.util.List
	 */
	public java.util.List getClasspathElements() {
		if(classpathElements == null)
			classpathElements = new ArrayList();
		return classpathElements;
	}
	
	public java.util.List getSelectedClasspathElements() {
		ArrayList list = new ArrayList();
		Iterator it = getClasspathElements().iterator();
		while(it.hasNext()) {
			ClasspathElement element = (ClasspathElement)it.next();
			if( element.isSelected() ){
				list.add(element);
			}
		}
		return list;
	}	

	/**
	 * Adapter method to convert the manifest class path entries which map to a project to a list of
	 * classpath entries for a java build path
	 */
	protected IClasspathEntry[] getClasspathEntries(boolean filterSelected) {
		List result = new ArrayList();
		IClasspathEntry[] array = null;
		ClasspathElement element = null;
		if(classpathElements != null) {
		for (int i = 0; i < classpathElements.size(); i++) {
			element = (ClasspathElement) classpathElements.get(i);
			if (filterSelected && !element.isSelected())
				continue;
			array = ((ClasspathElement) classpathElements.get(i)).newClasspathEntries();
			if (array == null)
				continue;
			for (int j = 0; j < array.length; j++) {
				if (!result.contains(array[j]))
					result.add(array[j]);
			}
		}
		return (IClasspathEntry[]) result.toArray(new IClasspathEntry[result.size()]);
		}
		return null;
	}

	/**
	 * Adapter method to convert the manifest class path entries which map to a project to a list of
	 * classpath entries for a java build path
	 */
	public IClasspathEntry[] getClasspathEntriesForAll() {
		return getClasspathEntries(false);
	}

	/**
	 * Adapter method to convert the manifest class path entries which map to a project to a list of
	 * classpath entries for a java build path
	 */
	public IClasspathEntry[] getClasspathEntriesForSelected() {
		return getClasspathEntries(true);
	}

	protected EARFile getEARFile() {
		if (archive == null)
			return null;

		Container parent = archive.getContainer();
		if (parent != null && parent.isEARFile())
			return (EARFile) parent;
		return null;
	}

	protected static IProject getEARProject(Archive anArchive) {
		Container c = anArchive.getContainer();
		if (!c.isEARFile())
			return null;
		EARFile ear = (EARFile) c;
		LoadStrategy loader = ear.getLoadStrategy();
		if (!(loader instanceof EARComponentLoadStrategyImpl))
			return null;

		return ((EARComponentLoadStrategyImpl) loader).getComponent().getProject();
	}

	public Archive getArchive() {
		return archive;
	}

	protected IProject getProject(Archive anArchive) {
		IVirtualComponent comp = getComponent(anArchive);
		if (comp != null) {
			return comp.getProject();
		}
		return null;
	}
	
	protected IVirtualComponent getComponent(Archive anArchive) {
		LoadStrategy loader = anArchive.getLoadStrategy();
		if (loader instanceof ComponentLoadStrategyImpl)
			return ((ComponentLoadStrategyImpl) loader).getComponent();
		return null;
	}

	public String getText() {
		return archive.getURI();
	}

	protected Archive getArchive(String uri, List archives) {
		for (int i = 0; i < archives.size(); i++) {
			Archive anArchive = (Archive) archives.get(i);
			
			String archiveURIString = anArchive.getURI();
			URI archiveURI = URI.createURI(archiveURIString);
			boolean hasAbsolutePath = archiveURI.hasAbsolutePath();
			if( hasAbsolutePath ){
				archiveURIString = archiveURI.lastSegment();
			}
			if (archiveURIString.equals(uri))
				return anArchive;
		}
		return null;
	}

	protected IVirtualReference getVirtualReference(String uri, List archives) {
		for (int i = 0; i < archives.size(); i++) {
			IVirtualReference anArchive = (IVirtualReference) archives.get(i);
			
			String archiveURIString = anArchive.getArchiveName();
			if (archiveURIString.equals(uri))
				return anArchive;
		}
		return null;
	}

	public static boolean isValidDependency(IVirtualComponent referencedJAR, IVirtualComponent referencingJAR) {
		//No other modules should reference wars
		if (J2EEProjectUtilities.isDynamicWebComponent(referencedJAR))
			return false;

		if (referencedJAR == referencingJAR)
			return false;

		//Clients can reference all but the WARs, which we've already covered
		// above; WARs and EJB JARs
		//can reference all but WARs, above, or ApplicationClients
		return J2EEProjectUtilities.isApplicationClientComponent(referencingJAR) || !J2EEProjectUtilities.isApplicationClientComponent(referencedJAR);
	}

	protected void initializeElements() {
//		ejbToClientJARs = J2EEProjectUtilities.collectEJBClientJARs(getEARFile());
		ejbToClientJARs = new HashMap();
		IVirtualComponent currentComponent = null;
		IVirtualComponent clientComponent = null;
		Object rootModelObject = null;
		IModelProvider modelProvider = null;
		String ejbClientJarName = null;
		List archives = null;
		IVirtualReference other = null;
		ClasspathElement element = null;
		String[] cp = new String[0];
		
		if (earComponent != null) {
			IVirtualReference[] references = earComponent.getReferences();		
			for (int cnt=0; cnt<references.length; cnt++)
			{
				clientComponent = null;
				modelProvider = null;
				rootModelObject = null;
				ejbClientJarName = null;
				currentComponent = references[cnt].getReferencedComponent();
				if (J2EEProjectUtilities.isEJBComponent(currentComponent))
				{
					if(currentComponent.isBinary()){
						//TODO add binary support
						continue;
					} else {
						modelProvider = ModelProviderManager.getModelProvider(currentComponent);
						if(modelProvider==null) {
							continue;
						}
						rootModelObject = modelProvider.getModelObject();
					}
					if (rootModelObject instanceof EJBJar)
					{
						ejbClientJarName = ((EJBJar)rootModelObject).getEjbClientJar();
					}
					else if (rootModelObject instanceof org.eclipse.jst.j2ee.ejb.EJBJar)
					{
						ejbClientJarName = ((org.eclipse.jst.j2ee.ejb.EJBJar)rootModelObject).getEjbClientJar();
					}
					if (ejbClientJarName != null)
					{
						clientComponent = J2EEProjectUtilities.getModule(earComponent, ejbClientJarName);
					}
					if (clientComponent != null)
					{
						ejbToClientJARs.put(currentComponent, clientComponent);
					}
				}
			}
			clientToEJBJARs = reverse(ejbToClientJARs);
			classpathElements = new ArrayList();
			urisToElements = new HashMap();

			
			try {
				//			cp = archive.getManifest().getClassPathTokenized();
				manifest = J2EEProjectUtilities.readManifest(component.getProject());
				cp = manifest.getClassPathTokenized();
			} catch (ManifestException ex) {
				Logger.getLogger().logError(ex);
			}
			String projectUri = earComponent.getReference(component.getName()).getArchiveName();
			archives = new ArrayList(Arrays.asList(earComponent.getReferences()));
			
			for (int i = 0; i < cp.length; i++) {
				String cpEntry = cp[i];
				String uri = ArchiveUtil.deriveEARRelativeURI(cpEntry, projectUri);

				other = getVirtualReference(uri, archives);
				if (other != null && isValidDependency(other.getReferencedComponent(), component)) {
					element = createElement(component, other, cpEntry);
					archives.remove(other);
				} else {
					element = createInvalidElement(cpEntry);
					if (element.representsImportedJar()) {
						element.setValid(true);
						element.setProject(getProject(archive));
					}
					if (other != null)
						element.setProject(other.getReferencedComponent().getProject());

					if( other == null ){
						//making a best guess for the project name
						if( element.getProject() == null ){
							int  index = cpEntry.indexOf(".jar"); //$NON-NLS-1$
							if( index > 0 ){
								String projectName = cpEntry.substring(0, index);
								IPath projectPath = new Path(projectName);
								//if there are multiple segments and no reference archive is found
								//then either this is pointing to a jar in the EAR that doesn't exist
								//or the DependecyGraphManager is stale
								if(projectPath.segmentCount() > 1){
									if(earComponent != null && earComponent.getProject() != null){
										element.setProject(earComponent.getProject());
									}
								} else {
									IProject project = ProjectUtilities.getProject( projectName );
									if( project != null && project.exists() )
										element.setProject( project );
								}
							}
						}
					}
				}
				addClasspathElement(element, uri);
			}
		}
		
		// Add resolved contributions from tagged classpath entries
		// XXX Don't show resolved contributions from tagged classpath entries on this project's classpath; we should elements corresponding to the raw entries instead
		//createClasspathComponentDependencyElements(comp);
		
		// Add elements for raw classpath entries (either already tagged or potentially taggable) 
		try {
		    createClasspathEntryElements(component, IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH, IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_COMPONENT_PATH);
		} catch (CoreException ce) {
			Logger.getLogger(J2EEPlugin.PLUGIN_ID).logError(ce);
		}
		
		if (earComponent != null) {
			Collections.sort(archives, comparator);
			//Anything that remains in the list of available archives that is valid should be
			//available for selection
			for (int i = 0; i < archives.size(); i++) {
				other = (IVirtualReference) archives.get(i);

				if (other != archive && isValidDependency(other.getReferencedComponent(), component)) {
					IProject project = other.getReferencedComponent().getProject();
					if (null == targetProjectName || null == project || !project.getName().equals(targetProjectName)) {
						element = createElement(component, other, null);
						element.setProject(other.getReferencedComponent().getProject());
						addClasspathElement(element, other.getArchiveName());
					}
				}
			}
			IVirtualReference[] newrefs = earComponent.getReferences();
			for( int i=0; i < newrefs.length; i++){
				IVirtualReference ref = newrefs[i];
				IVirtualComponent referencedComponent = ref.getReferencedComponent();
				boolean isBinary = referencedComponent.isBinary();
				if( isBinary ){

					/**
					 * Warning clean-up 12/05/2005
					 */   
					//String uri = J2EEProjectUtilities.getResolvedPathForArchiveComponent(referencedComponent.getName()).toString();
					String unresolvedURI = ref.getArchiveName();
					if(unresolvedURI == null){
						try {
							unresolvedURI = ModuleURIUtil.getArchiveName(URI.createURI(ModuleURIUtil.getHandleString(referencedComponent)));
						} catch (UnresolveableURIException e) {
							e.printStackTrace();
						}
					}

					if(unresolvedURI != null){
						URI archiveURI = URI.createURI(unresolvedURI);	

						boolean  alreadyInList = false;
						Iterator iter = getClasspathElements().iterator();
						while(iter.hasNext()){
							ClasspathElement tmpelement = (ClasspathElement)iter.next();
							if(unresolvedURI.endsWith(tmpelement.getText())){
								alreadyInList = true;
								break;
							}
						}

						if( !alreadyInList ){
							if( inManifest(cp, archiveURI.lastSegment())){
								element = createArchiveElement(URI.createURI(ModuleURIUtil.getHandleString(referencedComponent)), archiveURI.lastSegment(), archiveURI.lastSegment());
								addClasspathElement(element, unresolvedURI);
							}else{
								element = createArchiveElement(URI.createURI(ModuleURIUtil.getHandleString(referencedComponent)), archiveURI.lastSegment(), null);
								addClasspathElement(element, unresolvedURI);							
							}
						}
					}
				}
			}
		}	
	}
	
	public ClasspathElement createClasspathArchiveElement(final IProject project, URI archiveURI, String unresolvedURI) {
		final ClasspathElement element = createArchiveElement(archiveURI, archiveURI.lastSegment(), archiveURI.lastSegment());
		element.setProject(project);
		element.setClasspathDependency(true);
		return element;
	}
	
	public ClasspathElement createClasspathEntryElement(final IProject project, URI archiveURI, String elementName, IClasspathEntry entry) {
		final ClasspathElement element = createArchiveElement(archiveURI, elementName, elementName);
		element.setProject(project);
		element.setClasspathEntry(true, entry);
		element.setValid(true);
		return element;
	}

	boolean inManifest(String[] cp, String archiveName ){
		boolean result = false;
		String cpEntry = "";
		for (int i = 0; i < cp.length; i++) {
			cpEntry = cp[i];
			if( archiveName.equals(cpEntry)){
				result = true;
			}
		}
		return result;
	}
		
	protected List loadClassPathArchives(){
        /**
         * Warning clean-up 12/05/2005
         */   
		//LoadStrategy loadStrat = archive.getLoadStrategy();
		
		List archives = new ArrayList();
		
		if( earComponent!= null){
			IVirtualReference[] newrefs = earComponent.getReferences();
			for( int i=0; i < newrefs.length; i++){
				IVirtualReference ref = newrefs[i];
				IVirtualComponent referencedComponent = ref.getReferencedComponent();
				boolean isBinary = referencedComponent.isBinary();
			
				if( isBinary ){
					String uri = J2EEProjectUtilities.getResolvedPathForArchiveComponent(referencedComponent.getName()).toString();
		
					try {
						ZipFileLoadStrategyImpl strat = createLoadStrategy(uri);
						Archive archive = null;
						try {
							archive = CommonarchiveFactoryImpl.getActiveFactory().primOpenArchive(strat, uri);
						} catch (OpenFailureException e) {
							// TODO Auto-generated catch block
							Logger.getLogger().logError(e);
						}

						archives.add(archive);
						
					} catch (FileNotFoundException e) {
						Logger.getLogger().logError(e);
					} catch (IOException e) {
						Logger.getLogger().logError(e);
					}
				}
				
			}
		}
		return archives;
	}
	
	Archive getClassPathArchive(String uri, List archives){
		for (int i = 0; i < archives.size(); i++) {
			Archive anArchive = (Archive) archives.get(i);
			
			String archiveURIString = anArchive.getURI();
			URI archiveURI = URI.createURI(archiveURIString);
			boolean hasAbsolutePath = archiveURI.hasAbsolutePath();
			if( hasAbsolutePath ){
				archiveURIString = archiveURI.lastSegment();
			}
			if (archiveURIString.equals(uri))
				return anArchive;
		}
		return null;
	}
	
	boolean  isClassPathArchive(String uri, List archives){
		for (int i = 0; i < archives.size(); i++) {
			Archive anArchive = (Archive) archives.get(i);
			
			String archiveURIString = anArchive.getURI();
			URI archiveURI = URI.createURI(archiveURIString);
	         /**
	          * Warning clean-up 12/05/2005
	          */   
			//boolean hasAbsolutePath = archiveURI.hasAbsolutePath();
			if( archiveURI.lastSegment().equals(uri) ){
				return true;
			}
		}
		return false;
	}	
	
	public ZipFileLoadStrategyImpl createLoadStrategy(String uri) throws FileNotFoundException, IOException {
		String filename = uri.replace('/', java.io.File.separatorChar);
		java.io.File file = new java.io.File(filename);
		if (!file.exists()) {
			throw new FileNotFoundException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.file_not_found_EXC_, (new Object[]{uri, file.getAbsolutePath()}))); // = "URI Name: {0}; File name: {1}"
		}
		if (file.isDirectory()) {
			throw new FileNotFoundException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.file_not_found_EXC_, (new Object[]{uri, file.getAbsolutePath()}))); // = "URI Name: {0}; File name: {1}"
		}
		return new org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.ZipFileLoadStrategyImpl(file);
	}
	
	
	private void initializeEARProject(EARFile earFile) {
		LoadStrategy loadStrat = earFile.getLoadStrategy();
		if (loadStrat instanceof EARComponentLoadStrategyImpl){
			earComponent = ((EARComponentLoadStrategyImpl) loadStrat).getComponent();
			earProject = ((EARComponentLoadStrategyImpl) loadStrat).getComponent().getProject();
		}	
	}

	private void setType(ClasspathElement element, Archive other) {
		if (other == null)
			return;
		else if (clientToEJBJARs.containsKey(other))
			element.setJarType(ClasspathElement.EJB_CLIENT_JAR);
		else if (other.isEJBJarFile())
			element.setJarType(ClasspathElement.EJB_JAR);
	}

	private void setType(ClasspathElement element, IVirtualReference other) {
		if (other == null)
			return;
		else if (clientToEJBJARs.containsKey(other))
			element.setJarType(ClasspathElement.EJB_CLIENT_JAR);
		else if (J2EEProjectUtilities.isEJBComponent(other.getReferencedComponent()))
			element.setJarType(ClasspathElement.EJB_JAR);
	}

	/**
	 * @param localejbToClientJARs
	 * @return
	 */
	private Map reverse(Map localejbToClientJARs) {
		if (localejbToClientJARs == null || localejbToClientJARs.isEmpty())
			return Collections.EMPTY_MAP;
		Map result = new HashMap();
		Iterator iter = localejbToClientJARs.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			result.put(entry.getValue(), entry.getKey());
		}
		return result;
	}

	public void addClasspathElement(ClasspathElement element, String uri) {
		getClasspathElements().add(element);
		getUrisToElements().put(uri, element);
		element.setParentSelection(this);
	}

	/**
	 * Insert the method's description here. Creation date: (8/22/2001 6:05:11 PM)
	 * 
	 * @return boolean
	 */
	public boolean isModified() {
		return modified;
	}

	/**
	 * Insert the method's description here. Creation date: (8/22/2001 6:05:11 PM)
	 * 
	 * @param newModified
	 *            boolean
	 */
	public void setModified(boolean newModified) {
		modified = newModified;
	}

	protected void setProjectValues(ClasspathElement element, Archive referencedArchive) {
		IProject p = getProject(referencedArchive);
		if (p == null)
			return;

		element.setProject(p);
		//Handle the imported jars in the project
		String[] cp = null;
		try {
			cp = referencedArchive.getManifest().getClassPathTokenized();
		} catch (ManifestException mfEx) {
			Logger.getLogger().logError(mfEx);
			cp = new String[]{};
		}
		List paths = new ArrayList(cp.length);
		for (int i = 0; i < cp.length; i++) {

			IFile file = null;
			try {
				file = p.getFile(cp[i]);
			} catch (IllegalArgumentException invalidPath) {
				continue;
			}
			if (file.exists())
				paths.add(file.getFullPath());
		}
		if (!paths.isEmpty())
			element.setImportedJarPaths(paths);
	}

	protected void setProjectValues(ClasspathElement element, IVirtualReference referencedArchive) {
		IProject p = referencedArchive.getReferencedComponent().getProject();
		if (p == null)
			return;

		element.setProject(p);
		//Handle the imported jars in the project
		String[] cp = null;
		try {
//			cp = referencedArchive.getManifest().getClassPathTokenized();
			ArchiveManifest referencedManifest = J2EEProjectUtilities.readManifest(p);
			cp = referencedManifest.getClassPathTokenized();
		} catch (ManifestException mfEx) {
			Logger.getLogger().logError(mfEx);
			cp = new String[]{};
		}
		List paths = new ArrayList(cp.length);
		for (int i = 0; i < cp.length; i++) {

			IFile file = null;
			try {
				file = p.getFile(cp[i]);
			} catch (IllegalArgumentException invalidPath) {
				continue;
			}
			if (file.exists())
				paths.add(file.getFullPath());
		}
		if (!paths.isEmpty())
			element.setImportedJarPaths(paths);
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < classpathElements.size(); i++) {
			ClasspathElement element = (ClasspathElement) classpathElements.get(i);
			if (element.isSelected() && !element.isClasspathDependency() && !element.isClasspathEntry()) {
				sb.append(element.getRelativeText());
				sb.append(" "); //$NON-NLS-1$
			}
		}
		//Remove the trailing space
		if (sb.length() > 0)
			sb.deleteCharAt(sb.length() - 1);
		return sb.toString();
	}

	public void setAllSelected(boolean selected) {
		setAllSelected(classpathElements, selected);
	}

	public void setAllSelected(List elements, boolean selected) {
		for (int i = 0; i < elements.size(); i++) {
			ClasspathElement elmt = (ClasspathElement) elements.get(i);
			elmt.setSelected(selected);
		}
	}

	/* borrowed code from jdt */
	protected List moveUp(List elements, List move) {
		int nElements = elements.size();
		List res = new ArrayList(nElements);
		Object floating = null;
		for (int i = 0; i < nElements; i++) {
			Object curr = elements.get(i);
			if (move.contains(curr)) {
				res.add(curr);
			} else {
				if (floating != null) {
					res.add(floating);
				}
				floating = curr;
			}
		}
		if (floating != null) {
			res.add(floating);
		}
		return res;
	}

	/* borrowed code from jdt */
	public void moveUp(List toMoveUp) {
		setModifiedIfAnySelected(toMoveUp);
		if (toMoveUp.size() > 0)
			classpathElements = moveUp(classpathElements, toMoveUp);
	}

	/* borrowed code from jdt */
	public void moveDown(List toMoveDown) {
		setModifiedIfAnySelected(toMoveDown);
		if (toMoveDown.size() > 0)
			classpathElements = reverse(moveUp(reverse(classpathElements), toMoveDown));

	}

	/* borrowed code from jdt */
	protected List reverse(List p) {
		List reverse = new ArrayList(p.size());
		for (int i = p.size() - 1; i >= 0; i--) {
			reverse.add(p.get(i));
		}
		return reverse;
	}

	public ClasspathElement getClasspathElement(String uri) {
		if (urisToElements == null)
			return null;
		return (ClasspathElement) urisToElements.get(uri);
	}

	public ClasspathElement getClasspathElement(IVirtualComponent archiveComponent) {
		if (archiveComponent != null) {
			for (int i = 0; i < classpathElements.size(); i++) {
				ClasspathElement elmnt = (ClasspathElement) classpathElements.get(i);
				if (archiveComponent.equals(elmnt.getComponent()))
					return elmnt;
			}
		}
		return null;
	}

	public ClasspathElement getClasspathElement(IProject archiveProject) {
		if (archiveProject != null) {
			for (int i = 0; i < classpathElements.size(); i++) {
				ClasspathElement elmnt = (ClasspathElement) classpathElements.get(i);
				if (archiveProject.equals(elmnt.getProject()))
					return elmnt;
			}
		}
		return null;
	}

	public boolean hasDirectOrIndirectDependencyTo(IProject archiveProject) {
		ClasspathElement element = getClasspathElement(archiveProject);
		if (element == null)
			return false;
		Archive anArchive = null;
		if (element.isValid()) {
			try {
				anArchive = (Archive) getEARFile().getFile(element.getText());
			} catch (FileNotFoundException e) {
			}
		}
		return anArchive != null && archive.hasClasspathVisibilityTo(anArchive);
	}

	public boolean hasDirectOrIndirectDependencyTo(String jarName) {
		ClasspathElement element = getClasspathElement(jarName);
		if (element == null)
			return false;
		Archive anArchive = null;
		if (element.isValid()) {
			try {
				anArchive = (Archive) getEARFile().getFile(element.getText());
			} catch (FileNotFoundException e) {
			}
		}
		return anArchive != null && archive.hasClasspathVisibilityTo(anArchive);
	}


	public boolean isAnyJarSelected(int type) {
		if (classpathElements != null) {
			for (int i = 0; i < classpathElements.size(); i++) {
				ClasspathElement element = (ClasspathElement) classpathElements.get(i);
				if (element.getJarType() == type && element.isSelected())
					return true;
			}
		}
		return false;
	}


	public boolean isAnyEJBJarSelected() {
		return isAnyJarSelected(ClasspathElement.EJB_JAR);
	}



	public boolean isAnyEJBClientJARSelected() {
		return isAnyJarSelected(ClasspathElement.EJB_CLIENT_JAR);

	}

	/**
	 * @return
	 */
	public int getFilterLevel() {
		return filterLevel;
	}

	/**
	 * @param i
	 */
	public void setFilterLevel(int i) {
		filterLevel = i;
	}

	/**
	 * This method selects or deselects indivual elements based on the filter level, and
	 * additionally sets the filter level.
	 * 
	 * @param i
	 */
	public void selectFilterLevel(int level) {
		setFilterLevel(level);
		switch (level) {
			case FILTER_EJB_CLIENT_JARS :
				invertClientJARSelections(ClasspathElement.EJB_CLIENT_JAR);
				break;
			case FILTER_EJB_SERVER_JARS :
				invertClientJARSelections(ClasspathElement.EJB_JAR);
				break;
			default :
				break;
		}
	}

	public void invertClientJARSelection(IProject aProject, IProject opposite) {
		ClasspathElement element = getClasspathElement(aProject);
		ClasspathElement oppositeElement = (opposite == null ? null : getClasspathElement(opposite));
		if (element.isSelected())
			invertSelectionIfPossible(element, oppositeElement);
	}

	private void invertClientJARSelections(int elementType) {
		if (classpathElements == null)
			return;

		for (int i = 0; i < classpathElements.size(); i++) {
			ClasspathElement element = (ClasspathElement) classpathElements.get(i);
			if (element.getJarType() == elementType && element.isSelected()) {
				invertSelectionIfPossible(element, null);
			}
		}
	}

	/**
	 * @param element
	 * @param elementType
	 */
	private void invertSelectionIfPossible(ClasspathElement element, ClasspathElement opposite) {
		if (element == null)
			return;
		if (opposite == null)
			opposite = getOppositeElement(element);
		if (opposite != null) {
			opposite.setSelected(true);
			element.setSelected(false);
		}
	}

	/**
	 * If the element represents an EJB client JAR, returns the corresponding server JAR. If the
	 * element represents an EJB server JAR, returns the corresponding client JAR.
	 */
	public ClasspathElement getOppositeElement(ClasspathElement element) {
		String uri = element.getText();
		IVirtualComponent target = element.getTargetComponent();
		if (uri == null || target == null)
			return null;
		IVirtualComponent oppositeJAR = null;
		switch (element.getJarType()) {
			case (ClasspathElement.EJB_CLIENT_JAR) :
				oppositeJAR = (IVirtualComponent) clientToEJBJARs.get(target);
				break;
			case (ClasspathElement.EJB_JAR) :
				oppositeJAR = (IVirtualComponent) ejbToClientJARs.get(target);
				break;
			default :
				break;
		}
		if (oppositeJAR != null)
			return getClasspathElement(oppositeJAR);

		return null;
	}

	private void setModifiedIfAnySelected(List elements) {
		for (int i = 0; i < elements.size(); i++) {
			ClasspathElement element = (ClasspathElement) elements.get(i);
			if (element.isSelected())
				setModified(true);
		}
	}

	public boolean isMyClientJAR(ClasspathElement element) {
		if (element == null || ejbToClientJARs == null)
			return false;
		IVirtualComponent myClientJar = (IVirtualComponent) ejbToClientJARs.get(component);
		return myClientJar != null && myClientJar == element.getTargetComponent();
	}

	public Map getUrisToElements() {
		if(urisToElements == null)
			urisToElements = new HashMap();
		return urisToElements;
	}

}
