/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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.text.MessageFormat;
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.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.VMDisconnectedException;
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 = () -> doHotCodeReplace(hotSwapTargets, resources, qualifiedNames);
			DebugPlugin.getDefault().asyncExec(runnable);
		}
		if (!noHotSwapTargets.isEmpty()) {
			Runnable runnable = () -> notifyUnsupportedHCR(noHotSwapTargets, resources,
					qualifiedNames);
			DebugPlugin.getDefault().asyncExec(runnable);
		}
	}

	/**
	 * 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);
				target.filterNotLoadedTypes(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;
			}
			if (!isHCREnabled(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);

			// Make sure we only try to replace types from related projects
			target.filterUnrelatedResources(resourcesToReplace, qualifiedNamesToReplace);
			if (qualifiedNamesToReplace.isEmpty()) {
				// If none of the changed types are related to our target, do nothing.
				continue;
			}

			target.filterNotLoadedTypes(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();
	}

	private boolean isHCREnabled(JDIDebugTarget target) {
		ILaunch l = target.getLaunch();
		if (l != null) {
			boolean disabledByLaunch = "true".equals(l.getAttribute(JDIDebugModel.DISABLE_HCR_LAUNCH_ATTRIBUTE)); //$NON-NLS-1$
			return !disabledByLaunch;
		}
		return false;
	}

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

}
