/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.core.hcr;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
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.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchListener;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.util.IClassFileReader;
import org.eclipse.jdt.core.util.ISourceAttribute;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaHotCodeReplaceListener;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.core.JavaDebugUtils;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
import org.eclipse.jdt.internal.debug.core.model.JDIStackFrame;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.VirtualMachine;

/**
 * The hot code replace manager listens for changes to
 * class files and notifies running debug targets of the changes.
 * <p>
 * Currently, replacing .jar files has no effect on running targets.
 */
public class JavaHotCodeReplaceManager implements IResourceChangeListener, ILaunchListener, IDebugEventSetListener {
	/**
	 * Singleton 
	 */
	private static JavaHotCodeReplaceManager fgInstance= null;
	/**
	 * The class file extension
	 */
	private static final String CLASS_FILE_EXTENSION= "class"; //$NON-NLS-1$
	
	/**
	 * The list of <code>IJavaHotCodeReplaceListeners</code> which this hot code replace 
	 * manager will notify about hot code replace attempts.
	 */
	private ListenerList fHotCodeReplaceListeners= new ListenerList();
	
	/**
	 * The lists of hot swap targets which support HCR and those which don't
	 */
	private ArrayList fHotSwapTargets= new ArrayList(1);
	private ArrayList fNoHotSwapTargets= new ArrayList(1);
	
	/**
	 * A mapping of the last time projects were built.
	 * <ol>
	 * <li>key: project (IProject)</li>
	 * <li>value: build date (ProjectBuildTime)</li>
	 * </ol>
	 */
	private Map fProjectBuildTimes= new HashMap();
	private static Date fStartupDate= new Date();
	
	/**
	 * Cache of compilation unit deltas renewed on each HCR attempt.
	 */
	private Map fDeltaCache = new HashMap();
	
	/**
	 * Utility object used for tracking build times of projects.
	 * The HCR manager receives notification of builds AFTER
	 * the build has occurred but BEFORE the classfile
	 * resource changed deltas are fired. Thus, when the
	 * current build time is set, we need to hang onto
	 * the last build time so that we can use the last build
	 * time for comparing changes to compilation units (for smart
	 * drop to frame).
	 */
	class ProjectBuildTime {
		private Date fCurrentDate= new Date();
		private Date fPreviousDate= new Date();
		
		public void setCurrentBuildDate(Date date) {
			fPreviousDate= fCurrentDate;
			fCurrentDate= date;
		}
		
		public void setLastBuildDate(Date date) {
			fPreviousDate= date;
			if (fPreviousDate.getTime() > fCurrentDate.getTime()) {
				// If the previous date is set later than the current
				// date, move the current date up to the previous.
				fCurrentDate= fPreviousDate;
			}
		}
		
		/**
		 * Returns the last build time
		 */
		public Date getLastBuildDate() {
			return fPreviousDate;
		}
	}
	
	/**
	 * Visitor for resource deltas.
	 */
	protected ChangedClassFilesVisitor fClassfileVisitor = new ChangedClassFilesVisitor();
	
	/**
	 * Creates a new HCR manager
	 */
	private JavaHotCodeReplaceManager() {
	}
	/**
	 * Returns the singleton HCR manager
	 */
	public static synchronized JavaHotCodeReplaceManager getDefault() {
		if (fgInstance == null) {
			fgInstance= new JavaHotCodeReplaceManager();
		}
		return fgInstance;
	}
	/**
	 * Registers this HCR manager as a resource change listener. This method
	 * is called by the JDI debug model plugin on startup.
	 */
	public void startup() {
		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
		DebugPlugin.getDefault().addDebugEventListener(this);
	}
	
	/**
	 * Deregisters this HCR manager as a resource change listener. Removes all hot
	 * code replace listeners. This method is called by the JDI debug model plugin
	 * on shutdown.
	 */
	public void shutdown() {
		DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
		DebugPlugin.getDefault().removeDebugEventListener(this);
		getWorkspace().removeResourceChangeListener(this);
		fHotCodeReplaceListeners = new ListenerList();
		fHotSwapTargets= null;
		fNoHotSwapTargets= null;
	}
	/**
	 * Returns the workspace.
	 */
	protected IWorkspace getWorkspace() {
		return ResourcesPlugin.getWorkspace();
	}
	
	/**
	 * Returns the launch manager.
	 */
	protected ILaunchManager getLaunchManager() {
		return DebugPlugin.getDefault().getLaunchManager();
	}
	/**
	 * @see IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
	 */
	public void resourceChanged(IResourceChangeEvent event) {
		List projects= getBuiltProjects(event);
		if (!projects.isEmpty()) {
			updateProjectBuildTime(projects);
		}
		if (fHotSwapTargets.isEmpty() && fNoHotSwapTargets.isEmpty()) {
			// If there are no targets to notify, only update the build times.
			return;
		}
		ChangedClassFilesVisitor visitor = getChangedClassFiles(event);
		if (visitor != null) {
			List resources = visitor.getChangedClassFiles();
			List names = visitor.getQualifiedNamesList();
			if (!resources.isEmpty()) {
				notifyTargets(resources, names);
			}
		}
	}
	
	/**
	 * Returns all projects which this event says may have been built.
	 */
	protected List getBuiltProjects(IResourceChangeEvent event) {
		IResourceDelta delta= event.getDelta();
		if (event.getType() != IResourceChangeEvent.POST_BUILD || delta == null || event.getBuildKind() == 0) {
			return Collections.EMPTY_LIST;
		}
		if (event.getBuildKind() == IncrementalProjectBuilder.AUTO_BUILD && !ResourcesPlugin.getWorkspace().isAutoBuilding()) {
			// If this is an auto build and the workspace is not autobuilding,
			// no projects will actually be compiled.
			return Collections.EMPTY_LIST;
		}
		Object source = event.getSource();
		if (source instanceof IProject) {
			List list= new ArrayList();
			list.add(source);
			return list;
		} else if (source instanceof IWorkspace){
			IProject[] allProjects = ((IWorkspace) source).getRoot().getProjects();
			return Arrays.asList(allProjects);
		}
		return Collections.EMPTY_LIST;
	}
	
	/**
	 * If the given event contains a build notification, update the
	 * last build time of the corresponding project
	 */
	private void updateProjectBuildTime(List projects) {
		Iterator iter= projects.iterator();
		IProject project= null;
		Date currentDate= new Date();
		ProjectBuildTime buildTime= null;
		while (iter.hasNext()) {
			project= (IProject) iter.next();
			buildTime= (ProjectBuildTime)fProjectBuildTimes.get(project);
			if (buildTime == null) {
				buildTime= new ProjectBuildTime();
				fProjectBuildTimes.put(project, buildTime);
			}
			buildTime.setCurrentBuildDate(currentDate);
		}
	}
	
	/**
	 * Returns the last known build time for the given project.
	 * If no build time is known for the given project, the 
	 * last known build time for the project is set to the 
	 * hot code replace manager's startup time.
	 */
	protected long getLastProjectBuildTime(IProject project) {
		ProjectBuildTime time= (ProjectBuildTime)fProjectBuildTimes.get(project);
		if (time == null) {
			time= new ProjectBuildTime();
			time.setLastBuildDate(fStartupDate);
			fProjectBuildTimes.put(project, time);
		}
		return time.getLastBuildDate().getTime();
	}
	
	/**
	 * Notifies the targets of the changed types
	 */
	private void notifyTargets(final List resources, final List qualifiedNames) {
		final List hotSwapTargets= getHotSwapTargets();
		final List noHotSwapTargets= getNoHotSwapTargets();
		if (!hotSwapTargets.isEmpty()) {
			Runnable runnable= new Runnable() {
				public void run() {
					doHotCodeReplace(hotSwapTargets, resources, qualifiedNames);
				}
			};
			DebugPlugin.getDefault().asyncExec(runnable);	
		}
		if (!noHotSwapTargets.isEmpty()) {
			Runnable runnable= new Runnable() {
				public void run() {
					notifyUnsupportedHCR(noHotSwapTargets, resources, qualifiedNames);
				}
			};
			DebugPlugin.getDefault().asyncExec(runnable);
		}
	}
	
	/**
	 * Filters elements out of the given collections of resources and qualified names
	 * if there is no type corresponding tyep loaded in the given debug target. This
	 * method allows us to avoid bogus HCR attempts and "HCR failed" notifications.
	 *   
     * @param target the debug target
     * @param resources the list of resources to filter
     * @param qualifiedNames the list of qualified names to filter, which corresponds
     *  to the list of resources on a one-to-one-basis
     */
    private void filterUnloadedTypes(JDIDebugTarget target, List resources, List qualifiedNames) {
		for (int i= 0, numElements= qualifiedNames.size(); i < numElements; i++) {
		    String name= (String) qualifiedNames.get(i);
		    List list = target.jdiClassesByName(name);
		    if (list.isEmpty()) {
		        // If no classes with the given name are loaded in the VM, don't waste
		        // cycles trying to replace.
		        qualifiedNames.remove(i);
		        resources.remove(i);
		        // Decrement the index and number of elements to compensate for item removal
		        i--;
		        numElements--;
		    }
	    }
    }
    /**
	 * Notify the given targets that HCR failed for classes
	 * with the given fully qualified names.
	 */
	protected void notifyUnsupportedHCR(List targets, List resources, List qualifiedNames) {
		Iterator iter= targets.iterator();
		JDIDebugTarget target= null;
		while (iter.hasNext()) {	
			target= (JDIDebugTarget) iter.next();
			if (target.isAvailable()) {
			    // Make a local copy of the resources/names to swap so we can filter
			    // unloaded types on a per-target basis.
			    List resourcesToReplace= new ArrayList(resources);
			    List qualifiedNamesToReplace= new ArrayList(qualifiedNames);
				filterUnloadedTypes(target, resourcesToReplace, qualifiedNamesToReplace);
				
				if (!qualifiedNamesToReplace.isEmpty()) {
				    // Don't notify if the changed types aren't loaded.
				    fireHCRFailed(target, null);
				    notifyFailedHCR(target, qualifiedNamesToReplace);
				}
			} else {
			    // Targets should be unregistered when they terminate,
			    // but this is a fallback.
			    deregisterTarget(target);
			}
		}
	}
	
	protected void notifyFailedHCR(JDIDebugTarget target, List qualifiedNames) {
		if (target.isAvailable()) {
			target.addOutOfSynchTypes(qualifiedNames);
			target.fireChangeEvent(DebugEvent.STATE);
		}
	}	
	
	/**
	 * Returns the currently registered debug targets that support
	 * hot code replace.
	 */
	protected List getHotSwapTargets() {
		return (List) fHotSwapTargets.clone();
	}
	
	/**
	 * Returns the currently registered debug targets that do
	 * not support hot code replace.
	 */
	protected List getNoHotSwapTargets() {
		return (List) fNoHotSwapTargets.clone();
	}
	
	/**
	 * Perform a hot code replace with the given resources.
	 * For a JDK 1.4 compliant VM this involves:
	 * <ol>
	 * <li>Popping all frames from all thread stacks which will be affected by reloading the given resources</li>
	 * <li>Telling the VirtualMachine to redefine the affected classes</li>
	 * <li>Performing a step-into operation on all threads which were affected by the class redefinition.
	 *     This returns execution to the first (deepest) affected method on the stack</li>
	 * </ol>
	 * For a J9 compliant VM this involves:
	 * <ol>
	 * <li>Telling the VirtualMachine to redefine the affected classes</li>
	 * <li>Popping all frames from all thread stacks which were affected by reloading the given resources and then
	 *     performing a step-into operation on all threads which were affected by the class redefinition.</li>
	 * </ol>
	 * 
	 * @param targets the targets in which to perform HCR
	 * @param resources the resources which correspond to the changed classes
	 */
	private void doHotCodeReplace(List targets, List resources, List qualifiedNames) {
		MultiStatus ms= new MultiStatus(JDIDebugPlugin.getUniqueIdentifier(), DebugException.TARGET_REQUEST_FAILED, "At least one target failed to drop to frame after successful hot code replace.", null);  //$NON-NLS-1$
		Iterator iter= targets.iterator();
		while (iter.hasNext()) {
			JDIDebugTarget target= (JDIDebugTarget) iter.next();
			if (!target.isAvailable()) {
			    deregisterTarget(target);
				continue;
			}
		    // Make a local copy of the resources/names to swap so we can filter
		    // unloaded types on a per-target basis.
		    List resourcesToReplace= new ArrayList(resources);
		    List qualifiedNamesToReplace= new ArrayList(qualifiedNames);
			filterUnloadedTypes(target, resourcesToReplace, qualifiedNamesToReplace);
			if (qualifiedNamesToReplace.isEmpty()) {
			    // If none of the changed types are loaded, do nothing.
			    continue;
			}
			
			List poppedThreads= new ArrayList();
			target.setIsPerformingHotCodeReplace(true);
			try {
				boolean framesPopped= false;
				if (target.canPopFrames()) {
					// JDK 1.4 drop to frame support:
					// JDK 1.4 spec is faulty around methods that have
					// been rendered obsolete after class redefinition.
					// Thus, pop the frames that contain affected methods
					// *before* the class redefinition to avoid problems.
					try {
						attemptPopFrames(target, resourcesToReplace, qualifiedNamesToReplace, poppedThreads);
						framesPopped= true; // No exception occurred
					} catch (DebugException de) {
					    if (shouldLogHCRException(de)) {
					        ms.merge(de.getStatus());
					    }
					}
				}
				target.removeOutOfSynchTypes(qualifiedNamesToReplace);
				if (target.supportsJDKHotCodeReplace()) {
					redefineTypesJDK(target, resourcesToReplace, qualifiedNamesToReplace);
				} else if (target.supportsJ9HotCodeReplace()) {
					redefineTypesJ9(target, qualifiedNamesToReplace);
				}
				if (containsObsoleteMethods(target)) {
					fireObsoleteMethods(target);
				}
				try {
					if (target.canPopFrames() && framesPopped) {
						// Second half of JDK 1.4 drop to frame support:
						// All affected frames have been popped and the classes
						// have been reloaded. Step into the first changed
						// frame of each affected thread.
							// must re-set 'is doing HCR' to be able to step
							target.setIsPerformingHotCodeReplace(false);
							attemptStepIn(poppedThreads);
					} else {
						// J9 drop to frame support:
						// After redefining classes, drop to frame
						attemptDropToFrame(target, resourcesToReplace, qualifiedNamesToReplace);
					}
				} catch (DebugException de) {
				    if (shouldLogHCRException(de)) {
				        ms.merge(de.getStatus());
				    }
				}
				fireHCRSucceeded(target);
			} catch (DebugException de) {
				// target update failed
				fireHCRFailed(target, de);
			}
			// also re-set 'is doing HCR' here incase HCR failed
			target.setIsPerformingHotCodeReplace(false);
			target.fireChangeEvent(DebugEvent.CONTENT);
		}
		if (!ms.isOK()) {
			JDIDebugPlugin.log(ms);
		}
		fDeltaCache.clear();
	}
	
	/**
	 * Returns whether the given exception, which occurred during HCR, should be logged.
	 * We anticipate that we can get IncompatibleThreadStateExceptions if the user happens
	 * to resume a thread at just the right moment. Since this has no ill effects for HCR,
	 * we don't log these exceptions.
	 */
	private boolean shouldLogHCRException(DebugException exception) {
	    return !(exception.getStatus().getException() instanceof IncompatibleThreadStateException ||
	    		 exception.getStatus().getCode() == IJavaThread.ERR_INCOMPATIBLE_THREAD_STATE ||
	    		 exception.getStatus().getCode() == IJavaThread.ERR_THREAD_NOT_SUSPENDED);
	}

	/**
	 * Replaces the given types in the given J9 debug target.
	 * A fully qualified name of each type must be supplied.
	 *
	 * Breakpoints are reinstalled automatically when the new
	 * types are loaded.
	 *
	 * @exception DebugException if this method fails.  Reasons include:
	 * <ul>
	 * <li>Failure communicating with the VM.  The DebugException's
	 * status code contains the underlying exception responsible for
	 * the failure.</li>
	 * <li>The target VM was unable to reload a type due to a shape
	 * change</li>
	 * </ul>
	 */
	private void redefineTypesJ9(JDIDebugTarget target, List qualifiedNames) throws DebugException {
		String[] typeNames = (String[]) qualifiedNames.toArray(new String[qualifiedNames.size()]);					
		if (target.supportsJ9HotCodeReplace()) {
			target.setHCROccurred(true);
			org.eclipse.jdi.hcr.VirtualMachine vm= (org.eclipse.jdi.hcr.VirtualMachine) target.getVM();
			if (vm == null) {
				target.requestFailed(JDIDebugHCRMessages.JavaHotCodeReplaceManager_Hot_code_replace_failed___VM_disconnected__1, null); 
			}
			int result= org.eclipse.jdi.hcr.VirtualMachine.RELOAD_FAILURE;
			try {
				result= vm.classesHaveChanged(typeNames);
			} catch (RuntimeException e) {
				target.targetRequestFailed(MessageFormat.format(JDIDebugHCRMessages.JavaHotCodeReplaceManager_exception_replacing_types, new String[] {e.toString()}), e); 
			}
			switch (result) {
				case org.eclipse.jdi.hcr.VirtualMachine.RELOAD_SUCCESS:
					break;
				case org.eclipse.jdi.hcr.VirtualMachine.RELOAD_IGNORED:
					target.targetRequestFailed(JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_ignored, null); 
					break;
				case org.eclipse.jdi.hcr.VirtualMachine.RELOAD_FAILURE:
					target.targetRequestFailed(JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_failed, null); 
					target.addOutOfSynchTypes(qualifiedNames);
					break;
			}
		} else {
			target.notSupported(JDIDebugHCRMessages.JavaHotCodeReplaceManager_does_not_support_hcr); 
			target.addOutOfSynchTypes(qualifiedNames);
		}
	}
	
	/**
	 * Replaces the given types in the given JDK-compliant debug target.
	 * 
	 * This method is to be used for JDK hot code replace.
	 */
	private void redefineTypesJDK(JDIDebugTarget target, List resources, List qualifiedNames) throws DebugException {
		if (target.supportsJDKHotCodeReplace()) {
			target.setHCROccurred(true);
			Map typesToBytes= getTypesToBytes(target, resources, qualifiedNames);
			try {
				VirtualMachine vm = target.getVM();
				if (vm == null) {
					target.requestFailed(JDIDebugHCRMessages.JavaHotCodeReplaceManager_Hot_code_replace_failed___VM_disconnected__2, null); 
				}
				vm.redefineClasses(typesToBytes);
			} catch (UnsupportedOperationException exception) {
				String detail= exception.getMessage();
				if (detail != null) {
					redefineTypesFailedJDK(target, qualifiedNames, MessageFormat.format(JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_unsupported_operation, new String[] {detail}), exception); 
				} else {
					redefineTypesFailedJDK(target, qualifiedNames, JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_unsupported_redefinition, exception); 
				}				
			} catch (NoClassDefFoundError exception) {
				redefineTypesFailedJDK(target, qualifiedNames, JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_bad_bytes, exception); 
			} catch (VerifyError exception) {
				redefineTypesFailedJDK(target, qualifiedNames, JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_verify_error, exception); 
			} catch (UnsupportedClassVersionError exception) {
				redefineTypesFailedJDK(target, qualifiedNames, JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_unsupported_class_version, exception); 
			} catch (ClassFormatError exception) {
				redefineTypesFailedJDK(target, qualifiedNames, JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_class_format_error, exception); 
			} catch (ClassCircularityError exception) {
				redefineTypesFailedJDK(target, qualifiedNames, JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_class_circularity_error, exception); 
			} catch (RuntimeException exception) {
				redefineTypesFailedJDK(target, qualifiedNames, JDIDebugHCRMessages.JavaHotCodeReplaceManager_hcr_failed, exception); 
			}
			target.reinstallBreakpointsIn(resources, qualifiedNames);
		} else {
			target.notSupported(JDIDebugHCRMessages.JavaHotCodeReplaceManager_does_not_support_hcr); 
		}
	}
	
	/**
	 * Error handling for JDK hot code replace.
	 * 
	 * The given exception occurred when redefinition was attempted
	 * for the given types.
	 */
	private void redefineTypesFailedJDK(JDIDebugTarget target, List qualifiedNames, String message, Throwable exception) throws DebugException {
		target.addOutOfSynchTypes(qualifiedNames);
		target.jdiRequestFailed(message, exception);
	}
	
	/**
	 * Returns a mapping of class files to the bytes that make up those
	 * class files.
	 * 
	 * @param target the debug target to query
	 * @param resources the classfiles
	 * @param qualifiedNames the fully qualified type names corresponding to the
	 *  classfiles. The typeNames correspond to the resources on a one-to-one
	 *  basis.
	 * @return a mapping of class files to bytes
	 *  key: class file
	 *  value: the bytes which make up that classfile
	 */
	private Map getTypesToBytes(JDIDebugTarget target, List resources, List qualifiedNames) {
		Map typesToBytes= new HashMap(resources.size());
		Iterator resourceIter= resources.iterator();
		Iterator nameIter= qualifiedNames.iterator();
		IResource resource;
		String name;
		while (resourceIter.hasNext()) {
			resource= (IResource) resourceIter.next();
			name= (String) nameIter.next();
			List classes= target.jdiClassesByName(name);
			byte[] bytes= null;
			try {
				bytes= Util.getResourceContentsAsByteArray((IFile) resource);
			} catch (JavaModelException jme) {
				continue;
			}
			Iterator classIter= classes.iterator();
			while (classIter.hasNext()) {
				ReferenceType type= (ReferenceType) classIter.next();
				typesToBytes.put(type, bytes);
			}
		}
		return typesToBytes;
	}
	
	/**
	 * Notifies listeners that a hot code replace attempt succeeded
	 */
	private void fireHCRSucceeded(IJavaDebugTarget target) {
		Object[] listeners= fHotCodeReplaceListeners.getListeners();
		for (int i=0; i<listeners.length; i++) {
			((IJavaHotCodeReplaceListener)listeners[i]).hotCodeReplaceSucceeded(target);
		}		
	}
	
	/**
	 * Notifies listeners that a hot code replace attempt failed with the given exception
	 */
	private void fireHCRFailed(JDIDebugTarget target, DebugException exception) {
		Object[] listeners= fHotCodeReplaceListeners.getListeners();
		for (int i=0; i<listeners.length; i++) {
			((IJavaHotCodeReplaceListener)listeners[i]).hotCodeReplaceFailed(target, exception);
		}
	}
	
	/**
	 * Notifies listeners that obsolete methods remain on the stack
	 */
	private void fireObsoleteMethods(JDIDebugTarget target) {
		Object[] listeners= fHotCodeReplaceListeners.getListeners();
		for (int i=0; i<listeners.length; i++) {
			((IJavaHotCodeReplaceListener)listeners[i]).obsoleteMethods(target);
		}
	}
	
	/**
	 * Looks for the deepest effected stack frame in the stack
	 * and forces a drop to frame.  Does this for all of the active
	 * stack frames in the target.
	 * 
	 * @param target the debug target in which frames are to be dropped
	 * @param replacedClassNames the classes that have been redefined
	 */
	protected void attemptDropToFrame(JDIDebugTarget target, List resources, List replacedClassNames) throws DebugException {
		List dropFrames= getAffectedFrames(target.getThreads(), resources, replacedClassNames);

		// All threads that want to drop to frame are able. Proceed with the drop
		JDIStackFrame dropFrame= null;
		Iterator iter= dropFrames.iterator();
		while (iter.hasNext()) {
			try {
				dropFrame= ((JDIStackFrame)iter.next());
				dropFrame.dropToFrame();
			} catch (DebugException de) {
				notifyFailedDrop(((JDIThread)dropFrame.getThread()).computeStackFrames(), replacedClassNames);
			}
		}
	}
	
	/**
	 * Looks for the deepest effected stack frame in the stack
	 * and forces a drop to frame.  Does this for all of the active
	 * stack frames in the target.
	 * 
	 * @param target the debug target in which frames are to be dropped
	 * @param replacedClassNames the classes that have been redefined
	 * @param poppedThreads a list of the threads in which frames
	 *        were popped.This parameter may have entries added by this method
	 */
	protected void attemptPopFrames(JDIDebugTarget target, List resources, List replacedClassNames, List poppedThreads) throws DebugException {
		List popFrames= getAffectedFrames(target.getThreads(), resources, replacedClassNames);

		// All threads that want to drop to frame are able. Proceed with the drop
		JDIStackFrame popFrame= null;
		Iterator iter= popFrames.iterator();
		while (iter.hasNext()) {
			try {
				popFrame= ((JDIStackFrame)iter.next());
				popFrame.popFrame();
				poppedThreads.add(popFrame.getThread());
			} catch (DebugException de) {
				poppedThreads.remove(popFrame.getThread());
				notifyFailedDrop(((JDIThread)popFrame.getThread()).computeStackFrames(), replacedClassNames);
			}
		}
	}
	
	/**
	 * Returns whether or not the given target contains stack frames with obsolete
	 * methods.
	 */
	protected boolean containsObsoleteMethods(JDIDebugTarget target) throws DebugException {
		IThread[] threads=target.getThreads();
		List frames= null;
		Iterator iter= null;
		for (int i= 0, numThreads= threads.length; i < numThreads; i++) {
			frames= ((JDIThread)threads[i]).computeNewStackFrames();
			iter= frames.iterator();
			while (iter.hasNext()) {
				if (((JDIStackFrame)iter.next()).isObsolete()) {
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 * Returns a list of frames which should be popped in the given threads.
	 */
	protected List getAffectedFrames(IThread[] threads, List resourceList, List replacedClassNames) throws DebugException {
		JDIThread thread= null;
		JDIStackFrame affectedFrame= null;
		List popFrames= new ArrayList();
		int numThreads= threads.length;
		IResource[] resources= new IResource[resourceList.size()];
		resourceList.toArray(resources);
		for (int i = 0; i < numThreads; i++) {
			thread= (JDIThread) threads[i];
			if (thread.isSuspended()) {
				affectedFrame= getAffectedFrame(thread, replacedClassNames);
				if (affectedFrame == null) {
					// No frame to drop to in this thread
					continue;
				}
				if (affectedFrame.supportsDropToFrame()) {
					popFrames.add(affectedFrame);
				} else {
					// if any thread that should drop does not support the drop,
					// do not drop in any threads.
					for (int j= 0; j < numThreads; j++) {
						notifyFailedDrop(((JDIThread)threads[i]).computeStackFrames(), replacedClassNames);
					}
					throw new DebugException(new Status(IStatus.ERROR, JDIDebugModel.getPluginIdentifier(),
						DebugException.NOT_SUPPORTED, JDIDebugHCRMessages.JavaHotCodeReplaceManager_Drop_to_frame_not_supported, null)); 
				}
			}
		}
		return popFrames;
	}
	
	/**
	 * Returns the stack frame that should be dropped to in the
	 * given thread after a hot code replace.
	 * This is calculated by determining if the threads contain stack frames
	 * that reside in one of the given replaced class names. If possible, only
	 * stack frames whose methods were directly affected (and not simply all frames
	 * in affected types) will be returned.
	 */
	protected JDIStackFrame getAffectedFrame(JDIThread thread, List replacedClassNames) throws DebugException {
		List frames= thread.computeStackFrames();
		JDIStackFrame affectedFrame= null;
		JDIStackFrame frame= null;
		ICompilationUnit compilationUnit= null;
		CompilationUnitDelta delta= null;
		IProject project= null;
		for (int j= frames.size() - 1; j >= 0; j--) {
			frame= (JDIStackFrame) frames.get(j);
			if (containsChangedType(frame, replacedClassNames)) {
				// smart drop to frame support
				compilationUnit= getCompilationUnit(frame);
				// if we can't find the source, then do type-based drop
				if (compilationUnit != null) {
					try {
						project= compilationUnit.getCorrespondingResource().getProject();
					    delta = getDelta(compilationUnit, getLastProjectBuildTime(project));
						if (!delta.hasChanged(frame.getName(), frame.getSignature())) {
							continue;
						}
					} catch (CoreException exception) {
						// If smart drop to frame fails, just do type-based drop	
					}
				}

				if (frame.supportsDropToFrame()) {
					affectedFrame= frame;
					break;
				}
				// The frame we wanted to drop to cannot be popped.
				// Set the affected frame to the next lowest poppable
				// frame on the stack.
				while (j > 0) {
					j--;
					frame= (JDIStackFrame) frames.get(j);
					if (frame.supportsDropToFrame()) {
						affectedFrame= frame;
						break;
					}
				}
				break;
			}
		}
		return affectedFrame;
	}
	
	/**
	 * Returns the delta object for the given compilation unit
	 * 
	 * @param cu compilation unit
	 * @param time time to compare to (i.e. compare to first version before this time)
	 * @return delta object
	 */
	private CompilationUnitDelta getDelta(ICompilationUnit cu, long time) throws CoreException {
	    CompilationUnitDelta delta = (CompilationUnitDelta) fDeltaCache.get(cu);
	    if (delta == null) {
	    	delta= new CompilationUnitDelta(cu, time);
	    	fDeltaCache.put(cu, delta);
	    }
	    return delta;
	}
	
	/**
	 * Returns whether the given frame's declaring type was changed
	 * based on the given list of changed class names.
	 */
	protected boolean containsChangedType(JDIStackFrame frame, List replacedClassNames) throws DebugException {
		String declaringTypeName= frame.getDeclaringTypeName();
		// Check if the frame's declaring type was changed
		if (replacedClassNames.contains(declaringTypeName)) {
			return true;
		}
		// Check if one of the frame's declaring type's inner classes have changed
		Iterator iter= replacedClassNames.iterator();
		int index;
		String className= null;
		while (iter.hasNext()) {
			className= (String) iter.next();
			index= className.indexOf('$');
			if (index > -1 && declaringTypeName.equals(className.substring(0, index))) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Performs a "step into" operation on the given threads.
	 */
	protected void attemptStepIn(List threads) throws DebugException {
		Iterator iter= threads.iterator();
		while (iter.hasNext()) {
			((JDIThread) iter.next()).stepInto();
		}
	}
	
	/**
	 * Returns the compilation unit associated with this
	 * Java stack frame. Returns <code>null</code> for a binary
	 * stack frame.
	 */
	protected ICompilationUnit getCompilationUnit(IJavaStackFrame frame) {
		ILaunch launch= frame.getLaunch();
		if (launch == null) {
			return null;
		}
		ISourceLocator locator= launch.getSourceLocator();
		if (locator == null) {
			return null;
		}
		IJavaDebugTarget target = (IJavaDebugTarget) frame.getDebugTarget();
		String def = target.getDefaultStratum();
		target.setDefaultStratum("Java"); //$NON-NLS-1$
		Object sourceElement= locator.getSourceElement(frame);
		target.setDefaultStratum(def);
		if (!(sourceElement instanceof IJavaElement) && sourceElement instanceof IAdaptable) {
			sourceElement = ((IAdaptable)sourceElement).getAdapter(IJavaElement.class);
		}
		if (sourceElement instanceof IType) {
			return ((IType)sourceElement).getCompilationUnit();
		}
		if (sourceElement instanceof ICompilationUnit) {
			return (ICompilationUnit)sourceElement;
		}
		return null;
	}
	
	/**
	 * Returns the method in which this stack frame is
	 * suspended or <code>null</code> if none can be found
	 */
	public IMethod getMethod(JDIStackFrame frame, ICompilationUnit unit) throws CoreException {
		String declaringTypeName= frame.getDeclaringTypeName();
		String methodName= frame.getMethodName();
		String[] arguments= null;
		try {
			arguments= Signature.getParameterTypes(frame.getSignature());
		} catch (IllegalArgumentException exception) {
			// If Signature can't parse the signature, we can't
			// create the method
			return null;
		}
		String typeName = getUnqualifiedName(declaringTypeName);
		int index = typeName.indexOf('$');
		IType type = null;
		if (index > 0) {
			String remaining = typeName.substring(index + 1);
			typeName = typeName.substring(0, index);
			type = unit.getType(typeName);
			while (remaining != null) {
				index = remaining.indexOf('$');
				if (index > 0) {
					typeName = remaining.substring(0, index);
					remaining = remaining.substring(index + 1);
				} else {
					typeName = remaining;
					remaining = null;
				}
				type = type.getType(typeName);
			}
		} else {
			type = unit.getType(typeName);
		}
		if (type != null) {
			return type.getMethod(methodName, arguments);
		}
		return null;
	}
	
	/**
	 * Given a fully qualified name, return the unqualified name.
	 */
	protected String getUnqualifiedName(String qualifiedName) {
		int index= qualifiedName.lastIndexOf('.');
		return qualifiedName.substring(index + 1);
	}
	
	/**
	 * Notify the given frames that a drop to frame has failed after
	 * an HCR with the given class names.
	 */
	private void notifyFailedDrop(List frames, List replacedClassNames) throws DebugException {
		JDIStackFrame frame;
		Iterator iter= frames.iterator();
		while (iter.hasNext()) {
			frame= (JDIStackFrame) iter.next();
			if (replacedClassNames.contains(frame.getDeclaringTypeName())) {
				frame.setOutOfSynch(true);
			}
		}
	}
	/**
	 * Returns the class file visitor after visiting the resource change.
	 * The visitor contains the changed class files and qualified type names.
	 * Returns <code>null</code> if the visitor encounters an exception,
	 * or the delta is not a POST_BUILD.
	 */
	protected ChangedClassFilesVisitor getChangedClassFiles(IResourceChangeEvent event) {
		IResourceDelta delta= event.getDelta();
		if (event.getType() != IResourceChangeEvent.POST_BUILD || delta == null) {
			return null;
		}
		fClassfileVisitor.reset();
		try {
			delta.accept(fClassfileVisitor);
		} catch (CoreException e) {
			JDIDebugPlugin.log(e);
			return null; // quiet failure
		}
		return fClassfileVisitor;
	}
	
	/**
	 * A visitor which collects changed class files.
	 */
	class ChangedClassFilesVisitor implements IResourceDeltaVisitor {
		/**
		 * The collection of changed class files.
		 */
		protected List fFiles= null;
		
		/**
		 * Collection of qualified type names, corresponding to class files.
		 */
		protected List fNames= null;
		
		/**
		 * Answers whether children should be visited.
		 * <p>
		 * If the associated resource is a class file which 
		 * has been changed, record it.
		 */
		public boolean visit(IResourceDelta delta) {
			if (delta == null || 0 == (delta.getKind() & IResourceDelta.CHANGED)) {
				return false;
			}
			IResource resource= delta.getResource();
			if (resource != null) {
				switch (resource.getType()) {
					case IResource.FILE :
						if (0 == (delta.getFlags() & IResourceDelta.CONTENT))
							return false;
						if (CLASS_FILE_EXTENSION.equals(resource.getFullPath().getFileExtension())) {
							IPath localLocation = resource.getLocation();
							if (localLocation != null) {
								String path = localLocation.toOSString();  
								IClassFileReader reader = ToolFactory.createDefaultClassFileReader(path, IClassFileReader.CLASSFILE_ATTRIBUTES);
								if (reader != null) {
									// this name is slash-delimited 
									String qualifiedName = new String(reader.getClassName());
									boolean hasBlockingErrors= false;
									try {
										if (!JDIDebugModel.getPreferences().getBoolean(JDIDebugModel.PREF_HCR_WITH_COMPILATION_ERRORS)) {
											// If the user doesn't want to replace classfiles containing
											// compilation errors, get the source file associated with 
											// the class file and query it for compilation errors
											IJavaProject pro = JavaCore.create(resource.getProject());
											ISourceAttribute sourceAttribute = reader.getSourceFileAttribute();
											String sourceName = null; 
											if (sourceAttribute != null) {
												sourceName = new String(sourceAttribute.getSourceFileName());
											}
											IResource sourceFile= getSourceFile(pro, qualifiedName, sourceName);
											if (sourceFile != null) {
												IMarker[] problemMarkers= null;
												problemMarkers= sourceFile.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
												for (int i= 0; i < problemMarkers.length; i++) {
													if (problemMarkers[i].getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR) {
														hasBlockingErrors= true;
														break;
													}
												}
											}
										}
									} catch (CoreException e) {
										JDIDebugPlugin.log(e);
									}
									if (!hasBlockingErrors) {
										fFiles.add(resource);
										// dot-delimit the name
										fNames.add(qualifiedName.replace('/','.'));
									}
								}
							}
						}
						return false;
						
					default :
						return true;
				}
			}
			return true;
		}
		/**
		 * Resets the file collection to empty
		 */
		public void reset() {
			fFiles = new ArrayList();
			fNames = new ArrayList();
		}
		
		/**
		 * Answers a collection of changed class files or <code>null</code>
		 */
		public List getChangedClassFiles() {
			return fFiles;
		}
		
		/**
		 * Returns a collection of qualified type names corresponding to the
		 * changed class files.
		 * 
		 * @return List
		 */
		public List getQualifiedNamesList() {
			return fNames;
		}
		
		/**
		 * Returns the source file associated with the given type, or
		 * <code>null</code> if no source file could be found.
		 * 
		 * @param project the java project containing the classfile
		 * @param qualifiedName fully qualified name of the type, slash
		 * delimited
		 * @param sourceAttribute debug source attribute, or <code>null</code>
		 * if none
		 */
		private IResource getSourceFile(IJavaProject project, String qualifiedName, String sourceAttribute) {
			String name = null;
			IJavaElement element = null;
			try {
				if (sourceAttribute == null) { 
					element = JavaDebugUtils.findElement(qualifiedName, project);
				} else {
					int i = qualifiedName.lastIndexOf('/');
					if (i > 0) {
						name = qualifiedName.substring(0, i + 1);
						name = name + sourceAttribute;
					} else {
						name = sourceAttribute;
					}
					element = project.findElement(new Path(name));
				}
				if (element instanceof ICompilationUnit) {
					ICompilationUnit cu = (ICompilationUnit) element;
					return cu.getCorrespondingResource();
				}
			} catch (CoreException e) {
			}
			return null;
		}
	}

	
	/**
	 * Adds the given listener to the collection of hot code replace listeners.
	 * Listeners are notified when hot code replace attempts succeed or fail.
	 */
	public void addHotCodeReplaceListener(IJavaHotCodeReplaceListener listener) {
		fHotCodeReplaceListeners.add(listener);
	}
	
	/**
	 * Removes the given listener from the collection of hot code replace listeners.
	 * Once a listener is removed, it will no longer be notified of hot code replace
	 * attempt successes or failures.
	 */
	public void removeHotCodeReplaceListener(IJavaHotCodeReplaceListener listener) {
		fHotCodeReplaceListeners.remove(listener);
	}
	
	/**
	 * @see ILaunchListener#launchRemoved(ILaunch)
	 */
	public void launchRemoved(ILaunch launch) {
		IDebugTarget[] debugTargets= launch.getDebugTargets();
		for (int i = 0; i < debugTargets.length; i++) {
			IJavaDebugTarget jt = (IJavaDebugTarget)debugTargets[i].getAdapter(IJavaDebugTarget.class);
			if (jt != null) {
				deregisterTarget((JDIDebugTarget)jt);		
			}
		}
	}

	/**
	 * Begin listening for resource changes when a launch is
	 * registered with a hot swapable target.
	 * 
	 * @see org.eclipse.debug.core.ILaunchListener#launchAdded(org.eclipse.debug.core.ILaunch)
	 */
	public void launchAdded(ILaunch launch) {
		IDebugTarget[] debugTargets= launch.getDebugTargets();
		for (int i = 0; i < debugTargets.length; i++) {
			IJavaDebugTarget jt = (IJavaDebugTarget)debugTargets[i].getAdapter(IJavaDebugTarget.class);
			if (jt != null) {
				JDIDebugTarget target = (JDIDebugTarget)jt;
				if (target.supportsHotCodeReplace()) {
					addHotSwapTarget(target);
				} else if (target.isAvailable()){
					addNonHotSwapTarget(target);
				}				
			}
		}
		if (!fHotSwapTargets.isEmpty() || !fNoHotSwapTargets.isEmpty()) {
			getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_BUILD);
		}
	}
	
	/**
	 * Begin listening for resource changes when a launch is
	 * registered with a hot swapable target.
	 * 
	 * @see ILaunchListener#launchChanged(ILaunch)
	 */
	public void launchChanged(ILaunch launch) {
		launchAdded(launch);
	}	
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
	 */
	public void handleDebugEvents(DebugEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			DebugEvent event = events[i];
			if (event.getKind() == DebugEvent.TERMINATE) {
				Object source = event.getSource();
				if (source instanceof IAdaptable && source instanceof IDebugTarget) {
					IJavaDebugTarget jt = (IJavaDebugTarget)((IAdaptable)source).getAdapter(IJavaDebugTarget.class);
					if (jt != null) {
						deregisterTarget((JDIDebugTarget)jt);
					}	
				}
			}
		}
	}
	
	protected void deregisterTarget(JDIDebugTarget target) {
		// Remove the target from its hot swap target cache.
		if (!fHotSwapTargets.remove(target)) {
			fNoHotSwapTargets.remove(target);
		}
		ILaunch[] launches= DebugPlugin.getDefault().getLaunchManager().getLaunches();		
		// If there are no more active JDIDebugTargets, stop
		// listening to resource changes.
		for (int i= 0; i < launches.length; i++) {
			IDebugTarget[] targets = launches[i].getDebugTargets();
			for (int j = 0; j < targets.length; j++) {
				IDebugTarget debugTarget = targets[j];
				IJavaDebugTarget jt = (IJavaDebugTarget)debugTarget.getAdapter(IJavaDebugTarget.class);
				if (jt != null) {
					if (((JDIDebugTarget)jt).isAvailable()) {
						return;
					}
				}
			}
		}
	}
	
	/**
	 * Adds the given target to the list of hot-swappable targets.
	 * Has no effect if the target is already registered.
	 * 
	 * @param target a target that supports hot swap
	 */
	protected void addHotSwapTarget(JDIDebugTarget target) {
		if (!fHotSwapTargets.contains(target)) {
			fHotSwapTargets.add(target);
		}
	}
	
	/**
	 * Adds the given target to the list of non hot-swappable targets.
	 * Has no effect if the target is already registered.
	 * 
	 * @param target a target that does not support hot swap
	 */
	protected void addNonHotSwapTarget(JDIDebugTarget target) {
		if (!fNoHotSwapTargets.contains(target)) {
			fNoHotSwapTargets.add(target);
		}
	}

}

