/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     Yevgen Kogan - Bug 403475 - Hot Code Replace drops too much frames in some cases
 *******************************************************************************/
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.Platform;
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.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<IJavaHotCodeReplaceListener> fHotCodeReplaceListeners = new ListenerList<>();

	/**
	 * The lists of hot swap targets which support HCR and those which don't
	 */
	private ArrayList<JDIDebugTarget> fHotSwapTargets = new ArrayList<>(1);
	private ArrayList<JDIDebugTarget> 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<IProject, ProjectBuildTime> fProjectBuildTimes = new HashMap<>();
	private static Date fStartupDate = new Date();

	/**
	 * Cache of compilation unit deltas renewed on each HCR attempt.
	 */
	private Map<ICompilationUnit, CompilationUnitDelta> 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 plug-in on startup.
	 */
	public void startup() {
		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
		DebugPlugin.getDefault().addDebugEventListener(this);
	}

	/**
	 * unregisters this HCR manager as a resource change listener. Removes all
	 * hot code replace listeners. This method is called by the JDI debug model
	 * plug-in on shutdown.
	 */
	public void shutdown() {
		DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
		DebugPlugin.getDefault().removeDebugEventListener(this);
		getWorkspace().removeResourceChangeListener(this);
		fHotCodeReplaceListeners = new ListenerList<>();
		synchronized (this) {
			fHotSwapTargets.clear();
			fNoHotSwapTargets.clear();
		}
	}

	/**
	 * 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)
	 */
	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		List<IProject> projects = getBuiltProjects(event);
		if (!projects.isEmpty()) {
			updateProjectBuildTime(projects);
		}
		synchronized (this) {
			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<IResource> resources = visitor.getChangedClassFiles();
			List<String> names = visitor.getQualifiedNamesList();
			if (!resources.isEmpty()) {
				notifyTargets(resources, names);
			}
		}
	}

	/**
	 * Returns all projects which this event says may have been built.
	 */
	protected List<IProject> 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<IProject> list = new ArrayList<>();
			list.add((IProject) 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<IProject> projects) {
		Date currentDate = new Date();
		ProjectBuildTime buildTime = null;
		for(IProject project : projects) {
			buildTime = 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 = 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<IResource> resources, final List<String> qualifiedNames) {
		final List<JDIDebugTarget> hotSwapTargets = getHotSwapTargets();
		final List<JDIDebugTarget> noHotSwapTargets = getNoHotSwapTargets();
		if (!hotSwapTargets.isEmpty()) {
			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					doHotCodeReplace(hotSwapTargets, resources, qualifiedNames);
				}
			};
			DebugPlugin.getDefault().asyncExec(runnable);
		}
		if (!noHotSwapTargets.isEmpty()) {
			Runnable runnable = new Runnable() {
				@Override
				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 type 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<IResource> resources,
			List<String> qualifiedNames) {
		for (int i = 0, numElements = qualifiedNames.size(); i < numElements; i++) {
			String name = qualifiedNames.get(i);
			List<ReferenceType> 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<JDIDebugTarget> targets, List<IResource> resources,
			List<String> qualifiedNames) {
		Iterator<JDIDebugTarget> iter = targets.iterator();
		JDIDebugTarget target = null;
		while (iter.hasNext()) {
			target = 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<IResource> resourcesToReplace = new ArrayList<>(resources);
				List<String> 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 fall-back.
				deregisterTarget(target);
			}
		}
	}

	protected void notifyFailedHCR(JDIDebugTarget target, List<String> qualifiedNames) {
		if (target.isAvailable()) {
			target.addOutOfSynchTypes(qualifiedNames);
			target.fireChangeEvent(DebugEvent.STATE);
		}
	}

	/**
	 * Returns the currently registered debug targets that support hot code
	 * replace.
	 */
	protected synchronized List<JDIDebugTarget> getHotSwapTargets() {
		return new ArrayList<>(fHotSwapTargets);
	}

	/**
	 * Returns the currently registered debug targets that do not support hot
	 * code replace.
	 */
	protected synchronized List<JDIDebugTarget> getNoHotSwapTargets() {
		return new ArrayList<>(fNoHotSwapTargets);
	}

	/**
	 * 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<JDIDebugTarget> targets, List<IResource> resources,
			List<String> qualifiedNames) {

		// Check whether hot code replace is enabled
		if (!Platform.getPreferencesService().getBoolean(
				JDIDebugPlugin.getUniqueIdentifier(),
				JDIDebugPlugin.PREF_ENABLE_HCR,
				true,
				null)) {
			return; // disabled
		}

		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<JDIDebugTarget> iter = targets.iterator();
		while (iter.hasNext()) {
			JDIDebugTarget target = 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<IResource> resourcesToReplace = new ArrayList<>(resources);
			List<String> qualifiedNamesToReplace = new ArrayList<>(qualifiedNames);
			filterUnloadedTypes(target, resourcesToReplace,
					qualifiedNamesToReplace);
			if (qualifiedNamesToReplace.isEmpty()) {
				// If none of the changed types are loaded, do nothing.
				continue;
			}

			List<IThread> 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 in case 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<String> qualifiedNames)
			throws DebugException {
		String[] typeNames = 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, 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<IResource> resources,
			List<String> qualifiedNames) throws DebugException {
		if (target.supportsJDKHotCodeReplace()) {
			target.setHCROccurred(true);
			Map<ReferenceType, byte[]> 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,
									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<String> 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<ReferenceType, byte[]> getTypesToBytes(JDIDebugTarget target, List<IResource> resources,
			List<String> qualifiedNames) {
		Map<ReferenceType, byte[]> typesToBytes = new HashMap<>(resources.size());
		Iterator<IResource> resourceIter = resources.iterator();
		Iterator<String> nameIter = qualifiedNames.iterator();
		IResource resource;
		String name;
		while (resourceIter.hasNext()) {
			resource = resourceIter.next();
			name = nameIter.next();
			List<ReferenceType> classes = target.jdiClassesByName(name);
			byte[] bytes = null;
			try {
				bytes = Util.getResourceContentsAsByteArray((IFile) resource);
			} catch (JavaModelException jme) {
				continue;
			}
			for(ReferenceType type : classes) {
				typesToBytes.put(type, bytes);
			}
		}
		return typesToBytes;
	}

	/**
	 * Return the listeners to notify for the given target. Target specific
	 * listeners take precedence over generic listeners registered with the
	 * debug model plug-in.
	 *
	 * @param target
	 *            Java debug target
	 * @return hot code replace listeners
	 */
	private ListenerList<IJavaHotCodeReplaceListener> getHotCodeReplaceListeners(IJavaDebugTarget target) {
		ListenerList<IJavaHotCodeReplaceListener> listeners = null;
		if (target instanceof JDIDebugTarget) {
			listeners = ((JDIDebugTarget) target).getHotCodeReplaceListeners();
		}
		if (listeners == null || listeners.size() == 0) {
			listeners = fHotCodeReplaceListeners;
		}
		return listeners;
	}

	/**
	 * Notifies listeners that a hot code replace attempt succeeded
	 */
	private void fireHCRSucceeded(IJavaDebugTarget target) {
		ListenerList<IJavaHotCodeReplaceListener> listeners = getHotCodeReplaceListeners(target);
		for (IJavaHotCodeReplaceListener listener : listeners) {
			listener.hotCodeReplaceSucceeded(target);
		}
	}

	/**
	 * Notifies listeners that a hot code replace attempt failed with the given
	 * exception
	 */
	private void fireHCRFailed(JDIDebugTarget target, DebugException exception) {
		ListenerList<IJavaHotCodeReplaceListener> listeners = getHotCodeReplaceListeners(target);
		for (IJavaHotCodeReplaceListener listener : listeners) {
			listener.hotCodeReplaceFailed(target, exception);
		}
	}

	/**
	 * Notifies listeners that obsolete methods remain on the stack
	 */
	private void fireObsoleteMethods(JDIDebugTarget target) {
		ListenerList<IJavaHotCodeReplaceListener> listeners = getHotCodeReplaceListeners(target);
		for (IJavaHotCodeReplaceListener listener : listeners) {
			listener.obsoleteMethods(target);
		}
	}

	/**
	 * Looks for the deepest affected 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<IResource> resources,
			List<String> replacedClassNames) throws DebugException {
		List<JDIStackFrame> dropFrames = getAffectedFrames(target.getThreads(), resources,
				replacedClassNames);

		// All threads that want to drop to frame are able. Proceed with the
		// drop
		JDIStackFrame dropFrame = null;
		Iterator<JDIStackFrame> iter = dropFrames.iterator();
		while (iter.hasNext()) {
			try {
				dropFrame = iter.next();
				dropFrame.dropToFrame();
			} catch (DebugException de) {
				notifyFailedDrop(
						((JDIThread) dropFrame.getThread())
								.computeStackFrames(),
						replacedClassNames);
			}
		}
	}

	/**
	 * Looks for the deepest affected 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<IResource> resources,
			List<String> replacedClassNames, List<IThread> poppedThreads) throws DebugException {
		List<JDIStackFrame> popFrames = getAffectedFrames(target.getThreads(), resources,
				replacedClassNames);

		// All threads that want to drop to frame are able. Proceed with the
		// drop
		JDIStackFrame popFrame = null;
		Iterator<JDIStackFrame> iter = popFrames.iterator();
		while (iter.hasNext()) {
			try {
				popFrame = 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<IJavaStackFrame> frames = null;
		for (IThread thread : threads) {
			frames = ((JDIThread) thread).computeNewStackFrames();
			for(IJavaStackFrame frame : frames) {
				if(frame.isObsolete()) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Returns a list of frames which should be popped in the given threads.
	 */
	protected List<JDIStackFrame> getAffectedFrames(IThread[] threads, List<IResource> resourceList,
			List<String> replacedClassNames) throws DebugException {
		JDIThread thread = null;
		JDIStackFrame affectedFrame = null;
		List<JDIStackFrame> 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<String> replacedClassNames) throws DebugException {
		List<IJavaStackFrame> frames = thread.computeStackFrames();
		JDIStackFrame affectedFrame = null;
		JDIStackFrame frame = null;
		ICompilationUnit compilationUnit = null;
		CompilationUnitDelta delta = null;
		IProject project = null;
		for (int j = 0; j < frames.size(); 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));

						String typeName = frame.getDeclaringTypeName();
						typeName = typeName.replace('$', '.');

						if (!delta.hasChanged(typeName, 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 pop-able
				// 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 = 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<String> 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<String> iter = replacedClassNames.iterator();
		int index;
		String className = null;
		while (iter.hasNext()) {
			className = 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<IThread> threads) throws DebugException {
		Iterator<IThread> 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;
		}
		try {
			IJavaElement sourceElement = JavaDebugUtils.resolveJavaElement(frame, launch);
			if (sourceElement instanceof IType) {
				return ((IType) sourceElement).getCompilationUnit();
			}
			if (sourceElement instanceof ICompilationUnit) {
				return (ICompilationUnit) sourceElement;
			}
			return null;
		}
		catch (CoreException e) {
			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<IJavaStackFrame> frames, List<String> replacedClassNames)
			throws DebugException {
		for(IJavaStackFrame frame : frames) {
			if (replacedClassNames.contains(frame.getDeclaringTypeName())) {
				((JDIStackFrame)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<IResource> fFiles = null;

		/**
		 * Collection of qualified type names, corresponding to class files.
		 */
		protected List<String> fNames = null;

		/**
		 * Answers whether children should be visited.
		 * <p>
		 * If the associated resource is a class file which has been changed,
		 * record it.
		 */
		@Override
		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 (!Platform.getPreferencesService().getBoolean(
											JDIDebugPlugin.getUniqueIdentifier(),
											JDIDebugModel.PREF_HCR_WITH_COMPILATION_ERRORS,
											true,
											null)) {
										// 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 (IMarker problemMarker : problemMarkers) {
												if (problemMarker.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<IResource> getChangedClassFiles() {
			return fFiles;
		}

		/**
		 * Returns a collection of qualified type names corresponding to the
		 * changed class files.
		 *
		 * @return List
		 */
		public List<String> 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)
	 */
	@Override
	public void launchRemoved(ILaunch launch) {
		IDebugTarget[] debugTargets = launch.getDebugTargets();
		for (IDebugTarget debugTarget : debugTargets) {
			IJavaDebugTarget jt = debugTarget
					.getAdapter(IJavaDebugTarget.class);
			if (jt != null) {
				deregisterTarget((JDIDebugTarget) jt);
			}
		}
	}

	/**
	 * Begin listening for resource changes when a launch is registered with a
	 * hot swap-able target.
	 *
	 * @see org.eclipse.debug.core.ILaunchListener#launchAdded(org.eclipse.debug.core.ILaunch)
	 */
	@Override
	public void launchAdded(ILaunch launch) {
		IDebugTarget[] debugTargets = launch.getDebugTargets();
		for (IDebugTarget debugTarget : debugTargets) {
			IJavaDebugTarget jt = debugTarget
					.getAdapter(IJavaDebugTarget.class);
			if (jt != null) {
				JDIDebugTarget target = (JDIDebugTarget) jt;
				if (target.supportsHotCodeReplace()) {
					addHotSwapTarget(target);
				} else if (target.isAvailable()) {
					addNonHotSwapTarget(target);
				}
			}
		}
		synchronized (this) {
			if (!fHotSwapTargets.isEmpty() || !fNoHotSwapTargets.isEmpty()) {
				getWorkspace().addResourceChangeListener(this,
						IResourceChangeEvent.POST_BUILD);
			}
		}
	}

	/**
	 * Begin listening for resource changes when a launch is registered with a
	 * hot swap-able target.
	 *
	 * @see ILaunchListener#launchChanged(ILaunch)
	 */
	@Override
	public void launchChanged(ILaunch launch) {
		launchAdded(launch);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse
	 * .debug.core.DebugEvent[])
	 */
	@Override
	public void handleDebugEvents(DebugEvent[] events) {
		for (DebugEvent event : events) {
			if (event.getKind() == DebugEvent.TERMINATE) {
				Object source = event.getSource();
				if (source instanceof IAdaptable
						&& source instanceof IDebugTarget) {
					IJavaDebugTarget jt = ((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 (ILaunch launche : launches) {
			IDebugTarget[] targets = launche.getDebugTargets();
			for (IDebugTarget debugTarget : targets) {
				IJavaDebugTarget jt = debugTarget
						.getAdapter(IJavaDebugTarget.class);
				if (jt != null) {
					if (((JDIDebugTarget) jt).isAvailable()) {
						return;
					}
				}
			}
		}
	}

	/**
	 * Adds the given target to the list of hot-swap-able targets. Has no effect
	 * if the target is already registered.
	 *
	 * @param target
	 *            a target that supports hot swap
	 */
	protected synchronized void addHotSwapTarget(JDIDebugTarget target) {
		if (!fHotSwapTargets.contains(target)) {
			fHotSwapTargets.add(target);
		}
	}

	/**
	 * Adds the given target to the list of non hot-swap-able targets. Has no
	 * effect if the target is already registered.
	 *
	 * @param target
	 *            a target that does not support hot swap
	 */
	protected synchronized void addNonHotSwapTarget(JDIDebugTarget target) {
		if (!fNoHotSwapTargets.contains(target)) {
			fNoHotSwapTargets.add(target);
		}
	}

}
