/***************************************************************************************************
 * Copyright (c) 2003, 2004 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.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.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.common.componentcore.util.ComponentUtilities;
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.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.util.EARArtifactEdit;
import org.eclipse.jst.j2ee.internal.archive.operations.ComponentLoadStrategyImpl;
import org.eclipse.jst.j2ee.internal.archive.operations.EARComponentLoadStrategyImpl;
import org.eclipse.jst.j2ee.internal.project.J2EEComponentUtilities;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;


public class ClassPathSelection {
	protected Archive archive;
	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) {
			Archive a1 = (Archive) o1;
			Archive a2 = (Archive) o2;
			return a1.getURI().compareTo(a2.getURI());
		}
	};

	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();
	}
	
	/**
	 * 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);
		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;
	}

	/**
	 * @param element
	 */
	private void setInvalidProject(ClasspathElement element) {
		IProject earProj = element.getEarProject();
		IVirtualComponent component = J2EEComponentUtilities.getComponent(earProj.getName())[0];
		EARArtifactEdit edit = null;
		try {
			edit = EARArtifactEdit.getEARArtifactEditForRead(component);
		if (edit != null) {
			String moduleName = element.getRelativeText();
			if(moduleName != null) {
				IVirtualComponent modComponent = edit.getModule(moduleName);
				if(modComponent != null) {
				IProject mappedProject = modComponent.getProject();
				element.setProject(mappedProject);
				}
			}
		}
	  } finally {
		  if(edit != null) {
			  edit.dispose();
		    edit = null;
		  }
	  }
	}

	/**
	 * 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;
	}

	/**
	 * 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) {
		LoadStrategy loader = anArchive.getLoadStrategy();
		if (loader instanceof ComponentLoadStrategyImpl)
			return ((ComponentLoadStrategyImpl) loader).getComponent().getProject();
		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;
			
			
//			if (anArchive.getURI().equals(uri))
//				return anArchive;
		}
		return null;
	}

	protected void initializeElements() {
		ejbToClientJARs = J2EEProjectUtilities.collectEJBClientJARs(getEARFile());
		clientToEJBJARs = reverse(ejbToClientJARs);
		classpathElements = new ArrayList();
		urisToElements = new HashMap();
		String[] cp = new String[0];
		try {
			cp = archive.getManifest().getClassPathTokenized();
		} catch (ManifestException ex) {
			Logger.getLogger().logError(ex);
		}
		List archives = getEARFile().getArchiveFiles();
		Archive other = null;
		ClasspathElement element = null;
		for (int i = 0; i < cp.length; i++) {
			String cpEntry = cp[i];
			String uri = ArchiveUtil.deriveEARRelativeURI(cpEntry, archive);
			other = getArchive(uri, archives);
			if (other != null && ArchiveUtil.isValidDependency(other, archive)) {
				element = createElement(archive, other, cpEntry);
				archives.remove(other);
			} else {
				element = createInvalidElement(cpEntry);
				if (element.representsImportedJar()) {
					element.setValid(true);
					element.setProject(getProject(archive));
				}
				if (other != null)
					element.setProject(getProject(other));
			}
			addClasspathElement(element, uri);
		}
		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 = (Archive) archives.get(i);
			if (other != archive && ArchiveUtil.isValidDependency(other, archive)) {
				IProject project = getProject(other);
				if (null == targetProjectName || null == project || !project.getName().equals(targetProjectName)) {
					element = createElement(archive, other, null);
					element.setProject(getProject(other));
					addClasspathElement(element, other.getURI());
				}
			}
		}
		List classPathArchives = loadClassPathArchives();
		for (int i = 0; i < classPathArchives.size(); i++) {
			other = (Archive) classPathArchives.get(i);
			if (other != archive && ArchiveUtil.isValidDependency(other, archive)) {
				IProject project = getProject(other);
				if (null == targetProjectName || null == project || !project.getName().equals(targetProjectName)) {
					boolean inClassPath = false;
					for (int j = 0; j < cp.length; j++) {
						String cpEntry = cp[j];
						
						if( other != null && other.getName().equals(cpEntry)){
							if( isClassPathArchive(cpEntry, classPathArchives) ){
								other = getClassPathArchive(cpEntry, classPathArchives);
								if (other != null && ArchiveUtil.isValidDependency(other, archive)) {
									element = createElement(archive, other, cpEntry);
									//archives.remove(other);
									//classPathArchives.remove(other);
									inClassPath = true;
									break;
								}
							}
						}
					}
					if( !inClassPath ){
						element = createElement(archive, other, null);
						element.setProject(getProject(other));
						addClasspathElement(element, other.getURI());							
					}					

				}
			}
		}
		
	}

	protected List loadClassPathArchives(){
		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 = ComponentUtilities.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);
			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("file_not_found_EXC_", (new Object[]{uri, file.getAbsolutePath()}))); //$NON-NLS-1$ = "URI Name: {0}; File name: {1}"
		}
		if (file.isDirectory()) {
			throw new FileNotFoundException(CommonArchiveResourceHandler.getString("file_not_found_EXC_", (new Object[]{uri, file.getAbsolutePath()}))); //$NON-NLS-1$ = "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);
	}

	/**
	 * @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;
	}

	protected 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);
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < classpathElements.size(); i++) {
			ClasspathElement element = (ClasspathElement) classpathElements.get(i);
			if (element.isSelected()) {
				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(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();
		Archive target = element.getTargetArchive();
		if (uri == null || target == null)
			return null;
		Archive oppositeJAR = null;
		switch (element.getJarType()) {
			case (ClasspathElement.EJB_CLIENT_JAR) :
				oppositeJAR = (Archive) clientToEJBJARs.get(target);
				break;
			case (ClasspathElement.EJB_JAR) :
				oppositeJAR = (Archive) ejbToClientJARs.get(target);
				break;
			default :
				break;
		}
		if (oppositeJAR != null)
			return getClasspathElement(oppositeJAR.getURI());

		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;
		Archive myClientJar = (Archive) ejbToClientJARs.get(archive);
		return myClientJar != null && myClientJar == element.getTargetArchive();
	}

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

}