/*******************************************************************************
 * Copyright (c) 2007, 2014 QNX Software Systems 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:
 *     Ericsson - initial API and implementation this class is based on
 *     QNX Software Systems - Initial implementation for Jtag debugging
 *     Sage Electronic Engineering, LLC - bug 305943
 *              - API generalization to become transport-independent (allow
 *                connections via serial ports and pipes).
 *     John Dallaway - Wrong groupId during initialization (Bug 349736)    
 *     Marc Khouzam (Ericsson) - Updated to extend FinalLaunchSequence instead of copying it (bug 324101)
 *     William Riley (Renesas) - Memory viewing broken (Bug 413483)
 *     Marc Khouzam (Ericsson) - Cannot disable Delay command (bug 413437)
 *******************************************************************************/
package org.eclipse.cdt.debug.gdbjtag.core;

/**
 * @author Andy Jin
 *
 */

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.eclipse.cdt.debug.core.CDebugUtils;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.GDBJtagDeviceContribution;
import org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.GDBJtagDeviceContributionFactory;
import org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.IGDBJtagDevice;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.cdt.dsf.gdb.launching.FinalLaunchSequence;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
import org.eclipse.cdt.dsf.gdb.service.IGDBMemory;
import org.eclipse.cdt.dsf.gdb.service.SessionType;
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICommand;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.utils.CommandLineUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.VariablesPlugin;

/**
 * The final launch sequence for the Jtag hardware debugging using the
 * DSF/GDB debugger framework.
 * <p>
 * This class is based on the implementation of the standard DSF/GDB debugging
 * <code>org.eclipse.cdt.dsf.gdb.launching.FinalLaunchSequence</code>
 * <p>
 * It adds Jtag hardware debugging specific steps to initialize remote target
 * and start the remote Jtag debugging.
 * <p>
 * @since 7.0
 */
public class GDBJtagDSFFinalLaunchSequence extends FinalLaunchSequence {

	/** utility method; cuts down on clutter */
	private void queueCommands(List<String> commands, RequestMonitor rm) {
		if (!commands.isEmpty()) { 
			fCommandControl.queueCommand(
					new CLICommand<MIInfo>(fCommandControl.getContext(), composeCommand(commands)),
					new DataRequestMonitor<MIInfo>(getExecutor(), rm));
		}
		else {
			rm.done();
		}
	}

	private IGDBControl fCommandControl;
	private IGDBBackend	fGDBBackend;
	private IMIProcesses fProcService;
	private IGDBJtagDevice fGdbJtagDevice;

	private DsfServicesTracker fTracker;
	private IMIContainerDMContext fContainerCtx;
	
	/**
	 * @since 8.2
	 */
	public GDBJtagDSFFinalLaunchSequence(DsfSession session, Map<String, Object> attributes, RequestMonitorWithProgress rm) {
		super(session, attributes, rm);
	}

	public GDBJtagDSFFinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach, RequestMonitorWithProgress rm) {
		this(launch.getSession(), getAttributes(launch), rm);
    }

	@SuppressWarnings("unchecked")
	private static Map<String, Object> getAttributes(GdbLaunch launch) {
		try {
			return launch.getLaunchConfiguration().getAttributes();
		} catch (CoreException e) {
		}
		return new HashMap<String, Object>();
	}
    
	/** @since 8.2 */
	protected IMIContainerDMContext getContainerContext() {
		return fContainerCtx;
	}

	/** @since 8.2 */
	protected void setContainerContext(IMIContainerDMContext ctx) {
		fContainerCtx = ctx;
	}

	/** @since 8.2 */
	protected static final String GROUP_JTAG = "GROUP_JTAG";

	@Override
	protected String[] getExecutionOrder(String group) {
		if (GROUP_TOP_LEVEL.equals(group)) {
			// Initialize the list with the base class' steps
			// We need to create a list that we can modify, which is why we create our own ArrayList.
			List<String> orderList = new ArrayList<String>(Arrays.asList(super.getExecutionOrder(GROUP_TOP_LEVEL)));

			// First, remove all steps of the base class that we don't want to use.
			orderList.removeAll(Arrays.asList(new String[] { 
					"stepNewProcess",   //$NON-NLS-1$
			}));

			// Now insert our steps before the data model initialized event is sent
			orderList.add(orderList.indexOf("stepDataModelInitializationComplete"), GROUP_JTAG);

			return orderList.toArray(new String[orderList.size()]);
		}

		// Finally, deal with our groups and their steps.
		if (GROUP_JTAG.equals(group)) {
			return new String[] {
					"stepInitializeJTAGFinalLaunchSequence",
					"stepRetrieveJTAGDevice",   //$NON-NLS-1$
					"stepLoadSymbols",   //$NON-NLS-1$
					"stepConnectToTarget",   //$NON-NLS-1$
					"stepResetBoard",   //$NON-NLS-1$
					"stepDelayStartup",   //$NON-NLS-1$
					"stepHaltBoard",   //$NON-NLS-1$
					"stepUserInitCommands",   //$NON-NLS-1$
					"stepLoadImage",   //$NON-NLS-1$
					
					"stepUpdateContainer",   //$NON-NLS-1$
					
					"stepInitializeMemory",   //$NON-NLS-1$
					"stepSetArguments",   //$NON-NLS-1$
					"stepSetEnvironmentVariables",   //$NON-NLS-1$
					"stepStartTrackingBreakpoints",   //$NON-NLS-1$
					
					"stepSetProgramCounter",   //$NON-NLS-1$
					"stepStopScript",   //$NON-NLS-1$
					"stepResumeScript",   //$NON-NLS-1$
					"stepUserDebugCommands",   //$NON-NLS-1$
					"stepJTAGCleanup",   //$NON-NLS-1$
			};
		}
		
		// For any subgroups of the base class
		return super.getExecutionOrder(group);
	}

	/** 
	 * Initialize the members of the class.
	 * This step is mandatory for the rest of the sequence to complete.
	 * @since 8.2
	 */
	@Execute
	public void stepInitializeJTAGFinalLaunchSequence(RequestMonitor rm) {
		fTracker = new DsfServicesTracker(Activator.getBundleContext(), getSession().getId());
		fGDBBackend = fTracker.getService(IGDBBackend.class);
		if (fGDBBackend == null) {
			rm.done(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot obtain GDBBackend service", null)); //$NON-NLS-1$
			return;
		}

		fCommandControl = fTracker.getService(IGDBControl.class);
		if (fCommandControl == null) {
			rm.done(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot obtain control service", null)); //$NON-NLS-1$
			return;
		}

		fProcService = fTracker.getService(IMIProcesses.class);
		if (fProcService == null) {
			rm.done(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot obtain process service", null)); //$NON-NLS-1$
			return;
		}
		
        // When we are starting to debug a new process, the container is the default process used by GDB.
        // We don't have a pid yet, so we can simply create the container with the UNIQUE_GROUP_ID
        setContainerContext(fProcService.createContainerContextFromGroupId(fCommandControl.getContext(), MIProcesses.UNIQUE_GROUP_ID));

		rm.done();
	}

	/** 
	 * Rollback method for {@link #stepInitializeJTAGFinalLaunchSequence()}
	 * @since 4.0 
	 */
	@RollBack("stepInitializeJTAGFinalLaunchSequence")
	public void rollBackInitializeFinalLaunchSequence(RequestMonitor rm) {
		if (fTracker != null) fTracker.dispose();
		fTracker = null;
		rm.done();
	}
	
	/*
	 * Retrieve the IGDBJtagDevice instance
	 */
	/** @since 8.2 */
	@Execute
	public void stepRetrieveJTAGDevice(final RequestMonitor rm) {
		Exception exception = null;
		try {
			fGdbJtagDevice = getGDBJtagDevice();
		} catch (NullPointerException e) {
			exception = e;
		}
		if (fGdbJtagDevice == null) {
			// Abort the launch
			rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get Jtag device", exception)); //$NON-NLS-1$
		}
		rm.done();
	}
	
	/*
	 * Execute symbol loading
	 */
	/** @since 8.2 */
	@Execute
	public void stepLoadSymbols(final RequestMonitor rm) {
		try {
			if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_LOAD_SYMBOLS, IGDBJtagConstants.DEFAULT_LOAD_SYMBOLS)) {
				String symbolsFileName = null;

				// New setting in Helios. Default is true. Check for existence
				// in order to support older launch configs
				if (getAttributes().containsKey(IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_SYMBOLS) &&
						CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_SYMBOLS, IGDBJtagConstants.DEFAULT_USE_PROJ_BINARY_FOR_SYMBOLS)) {
					IPath programFile = fGDBBackend.getProgramPath();
					if (programFile != null) {
						symbolsFileName = programFile.toOSString();
					}
				}
				else {
					symbolsFileName = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SYMBOLS_FILE_NAME, IGDBJtagConstants.DEFAULT_SYMBOLS_FILE_NAME);
					if (symbolsFileName.length() > 0) {
						symbolsFileName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(symbolsFileName);
					} else {
						symbolsFileName = null;
					}
				}

				if (symbolsFileName == null) {
					rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, Messages.getString("GDBJtagDebugger.err_no_img_file"), null)); //$NON-NLS-1$
					rm.done();
					return;
				}

				// Escape windows path separator characters TWICE, once for Java and once for GDB.						
				symbolsFileName = symbolsFileName.replace("\\", "\\\\"); //$NON-NLS-1$ //$NON-NLS-2$

				String symbolsOffset = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SYMBOLS_OFFSET, IGDBJtagConstants.DEFAULT_SYMBOLS_OFFSET);
				if (symbolsOffset.length() > 0) {
					symbolsOffset = "0x" + symbolsOffset;					
				}
				List<String> commands = new ArrayList<String>();
				fGdbJtagDevice.doLoadSymbol(symbolsFileName, symbolsOffset, commands);
				queueCommands(commands, rm);									

			} else {
				rm.done();
			}
		} catch (CoreException e) {
			rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot load symbol", e)); //$NON-NLS-1$
			rm.done();
		}
	}

	/*
	 * Hook up to remote target
	 */
	/** @since 8.2 */
	@SuppressWarnings("deprecation")
	@Execute
	public void stepConnectToTarget(final RequestMonitor rm) {
		try {
			if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_USE_REMOTE_TARGET, IGDBJtagConstants.DEFAULT_USE_REMOTE_TARGET)) {
				List<String> commands = new ArrayList<String>();
				if (fGdbJtagDevice instanceof IGDBJtagConnection) {
					URI	uri = new URI(CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_CONNECTION, IGDBJtagConstants.DEFAULT_CONNECTION));
					IGDBJtagConnection device = (IGDBJtagConnection)fGdbJtagDevice;
					device.doRemote(uri.getSchemeSpecificPart(), commands);
				} else {
					// Handle legacy network device contributions that don't understand URIs
					String ipAddress = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IP_ADDRESS, IGDBJtagConstants.DEFAULT_IP_ADDRESS);
					int portNumber = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_PORT_NUMBER, IGDBJtagConstants.DEFAULT_PORT_NUMBER);
					fGdbJtagDevice.doRemote(ipAddress, portNumber, commands);
				}
				queueCommands(commands, rm);
			} else {
				rm.done();
			}
		} catch (URISyntaxException e) {
			rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Invalid remote target connection syntax", e)); //$NON-NLS-1$
			rm.done();
		}
	}
	
	/*
	 * Run device-specific code to reset the board
	 */
	/** @since 8.2 */
	@Execute
	public void stepResetBoard(final RequestMonitor rm) {
			if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_DO_RESET, IGDBJtagConstants.DEFAULT_DO_RESET)) {
				List<String> commands = new ArrayList<String>();
				fGdbJtagDevice.doReset(commands);
				queueCommands(commands, rm);
			} else {
				rm.done();
			}
	}
	
	/*
	 * Run device-specific code to delay the startup
	 */
	/** @since 8.2 */
	@Execute
	public void stepDelayStartup(final RequestMonitor rm) {
		// The delay is also controlled by the RESET attribute.
		if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_DO_RESET, IGDBJtagConstants.DEFAULT_DO_RESET)) {
			int defaultDelay = fGdbJtagDevice.getDefaultDelay();
			List<String> commands = new ArrayList<String>();
			fGdbJtagDevice.doDelay(CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_DELAY, defaultDelay), commands);
			queueCommands(commands, rm);
		} else {
			rm.done();
		}						
	}
	
	/*
	 * Run device-specific code to halt the board
	 */
	/** @since 8.2 */
	@Execute
	public void stepHaltBoard(final RequestMonitor rm) {
			if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_DO_HALT, IGDBJtagConstants.DEFAULT_DO_HALT)) {
				List<String> commands = new ArrayList<String>();
				fGdbJtagDevice.doHalt(commands);
				queueCommands(commands, rm);								
			} else {
				rm.done();
			}
	}
	
	/*
	 * Execute any user defined init commands
	 */
	/** @since 8.2 */
	@Execute
	public void stepUserInitCommands(final RequestMonitor rm) {
		try {
			String userCmd = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_INIT_COMMANDS, IGDBJtagConstants.DEFAULT_INIT_COMMANDS);
			userCmd = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(userCmd);
			if (userCmd.length() > 0) {
				String[] commands = userCmd.split("\\r?\\n"); //$NON-NLS-1$

				CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm);
				crm.setDoneCount(commands.length);
				for (int i = 0; i < commands.length; ++i) {
					fCommandControl.queueCommand(
							new CLICommand<MIInfo>(fCommandControl.getContext(), commands[i]),
							new DataRequestMonitor<MIInfo>(getExecutor(), crm));
				}
			}
			else {
				rm.done();
			}
		} catch (CoreException e) {
			rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot run user defined init commands", e)); //$NON-NLS-1$
			rm.done();
		}
	}
	
	/*
	 * Execute image loading
	 */
	/** @since 8.2 */
	@Execute
	public void stepLoadImage(final RequestMonitor rm) {
		try {
			String imageFileName = null;
			if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_LOAD_IMAGE, IGDBJtagConstants.DEFAULT_LOAD_IMAGE)) {
				// New setting in Helios. Default is true. Check for existence
				// in order to support older launch configs
				if (getAttributes().containsKey(IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_IMAGE) &&
						CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_USE_PROJ_BINARY_FOR_IMAGE, IGDBJtagConstants.DEFAULT_USE_PROJ_BINARY_FOR_IMAGE)) {
					IPath programFile = fGDBBackend.getProgramPath();
					if (programFile != null) {
						imageFileName = programFile.toOSString();
					}
				}
				else {
					imageFileName = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IMAGE_FILE_NAME, IGDBJtagConstants.DEFAULT_IMAGE_FILE_NAME); 
					if (imageFileName.length() > 0) {
						imageFileName = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(imageFileName);
					} else {
						imageFileName = null;
					}
				}

				if (imageFileName == null) {
					rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, Messages.getString("GDBJtagDebugger.err_no_img_file"), null)); //$NON-NLS-1$
					rm.done();
					return;
				}

				// Escape windows path separator characters TWICE, once for Java and once for GDB.						
				imageFileName = imageFileName.replace("\\", "\\\\"); //$NON-NLS-1$ //$NON-NLS-2$

				String imageOffset = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IMAGE_OFFSET, IGDBJtagConstants.DEFAULT_IMAGE_OFFSET);
				if (imageOffset.length() > 0) {
					imageOffset = (imageFileName.endsWith(".elf")) ? "" : "0x" + CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IMAGE_OFFSET, IGDBJtagConstants.DEFAULT_IMAGE_OFFSET); //$NON-NLS-2$ 
				}
				List<String> commands = new ArrayList<String>();
				fGdbJtagDevice.doLoadImage(imageFileName, imageOffset, commands);
				queueCommands(commands, rm);									
			} 
			else {
				rm.done();
			}
		} catch (CoreException e) {
			rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot load image", e)); //$NON-NLS-1$
			rm.done();
		}
	}
	
	/**
	 * Now that we are connected to the target, we should update
	 * our container to properly fill in its pid.
	 * @since 8.2
	 */
	@Execute
	public void stepUpdateContainer(RequestMonitor rm) {
		String groupId = getContainerContext().getGroupId();
        setContainerContext(fProcService.createContainerContextFromGroupId(fCommandControl.getContext(), groupId));
		rm.done();
	}
	
	/**
	 * Specify the arguments to the program that will be run.
	 * @since 8.2
	 */
	@Execute
	public void stepSetArguments(RequestMonitor rm) {
		try {
			String args = CDebugUtils.getAttribute(
					getAttributes(),
					ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS,
					""); //$NON-NLS-1$

			if (args.length() != 0) {
				args = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(args);
				String[] argArray = CommandLineUtil.argumentsToArray(args);
				fCommandControl.queueCommand(
						fCommandControl.getCommandFactory().createMIGDBSetArgs(getContainerContext(), argArray), 
						new ImmediateDataRequestMonitor<MIInfo>(rm));
			} else {
				rm.done();
			}
		} catch (CoreException e) {
			rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get inferior arguments", e)); //$NON-NLS-1$
			rm.done();
		}    		
	}
	
	/**
	 * Specify environment variables if needed
	 * @since 8.2
	 */
	@Execute
	public void stepSetEnvironmentVariables(RequestMonitor rm) {
		boolean clear = false;
		Properties properties = new Properties();
		try {
			// here we need to pass the proper container context
			clear = fGDBBackend.getClearEnvironment();
			properties = fGDBBackend.getEnvironmentVariables();
		} catch (CoreException e) {
			rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot get environment information", e)); //$NON-NLS-1$
			rm.done();
			return;
		}

		if (clear == true || properties.size() > 0) {
			fCommandControl.setEnvironment(properties, clear, rm);
		} else {
			rm.done();
		}
	}
	
	/* 
	 * Start tracking the breakpoints once we know we are connected to the target (necessary for remote debugging) 
	 */
	/** @since 8.2 */
	@Execute
	public void stepStartTrackingBreakpoints(final RequestMonitor rm) {
		MIBreakpointsManager bpmService = fTracker.getService(MIBreakpointsManager.class);
		bpmService.startTrackingBpForProcess(getContainerContext(), rm);
	}
	
	/*
	 * Set the program counter
	 */
	/** @since 8.2 */
	@Execute
	public void stepSetProgramCounter(final RequestMonitor rm) {
			if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SET_PC_REGISTER, IGDBJtagConstants.DEFAULT_SET_PC_REGISTER)) {
				String pcRegister = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_PC_REGISTER, CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_IMAGE_OFFSET, IGDBJtagConstants.DEFAULT_PC_REGISTER)); 
				List<String> commands = new ArrayList<String>();
				fGdbJtagDevice.doSetPC(pcRegister, commands);
				queueCommands(commands, rm);								
			} else {
				rm.done();
			}
	}
	
	/*
	 * Execute the stop script
	 */
	/** @since 8.2 */
	@Execute
	public void stepStopScript(final RequestMonitor rm) {
			if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SET_STOP_AT, IGDBJtagConstants.DEFAULT_SET_STOP_AT)) {
				String stopAt = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_STOP_AT, IGDBJtagConstants.DEFAULT_STOP_AT); 
				List<String> commands = new ArrayList<String>();
				fGdbJtagDevice.doStopAt(stopAt, commands);
				queueCommands(commands, rm);								
			} else {
				rm.done();
			}
	}

	/*
	 * Execute the resume script
	 */
	/** @since 8.2 */
	@Execute
	public void stepResumeScript(final RequestMonitor rm) {
			if (CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_SET_RESUME, IGDBJtagConstants.DEFAULT_SET_RESUME)) {
				List<String> commands = new ArrayList<String>();
				fGdbJtagDevice.doContinue(commands);
				queueCommands(commands, rm);									
			} else {
				rm.done();
			}
	}
	
	/*
	 * Run any user defined commands to start debugging
	 */
	/** @since 8.2 */
	@Execute
	public void stepUserDebugCommands(final RequestMonitor rm) {
		try {
			String userCmd = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_RUN_COMMANDS, IGDBJtagConstants.DEFAULT_RUN_COMMANDS); 
			if (userCmd.length() > 0) {
				userCmd = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(userCmd);
				String[] commands = userCmd.split("\\r?\\n"); //$NON-NLS-1$

				CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm);
				crm.setDoneCount(commands.length);
				for (int i = 0; i < commands.length; ++i) {
					fCommandControl.queueCommand(
							new CLICommand<MIInfo>(fCommandControl.getContext(), commands[i]),
							new DataRequestMonitor<MIInfo>(getExecutor(), crm));
				}
			}
			else {
				rm.done();
			}
		} catch (CoreException e) {
			rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, -1, "Cannot run user defined run commands", e)); //$NON-NLS-1$
			rm.done();
		}
	}

	private IGDBJtagDevice getGDBJtagDevice () {
		IGDBJtagDevice gdbJtagDevice = null;
		String jtagDeviceName = CDebugUtils.getAttribute(getAttributes(), IGDBJtagConstants.ATTR_JTAG_DEVICE, IGDBJtagConstants.DEFAULT_JTAG_DEVICE); 
		GDBJtagDeviceContribution[] availableDevices = GDBJtagDeviceContributionFactory.getInstance().getGDBJtagDeviceContribution();
		for (GDBJtagDeviceContribution availableDevice : availableDevices) {
			if (jtagDeviceName.equals(availableDevice.getDeviceName())) {
				gdbJtagDevice = availableDevice.getDevice();
				break;
			}
		}
		return gdbJtagDevice;
	}

	/**
	 * @param commands
	 * @return String commands in String format
	 */
	private String composeCommand(Collection<String> commands) {
		if (commands.isEmpty())
			return null;
		StringBuffer sb = new StringBuffer();
		Iterator<String> it = commands.iterator();
		while (it.hasNext()) {
			sb.append(it.next());
		}
		return sb.toString();
	}
	
	/**
	 * Cleanup now that the sequence has been run.
	 * @since 8.2
	 */
	@Execute
	public void stepJTAGCleanup(final RequestMonitor requestMonitor) {
		fTracker.dispose();
		fTracker = null;
		requestMonitor.done();
	}

	/**
	 * Initialize the memory service with the data for given process.
	 * @since 8.3
	 */
	@Execute
	public void stepInitializeMemory(final RequestMonitor rm) {
		IGDBMemory memory = fTracker.getService(IGDBMemory.class);
		IMemoryDMContext memContext = DMContexts.getAncestorOfType(getContainerContext(), IMemoryDMContext.class);
		if (memory == null || memContext == null) {
			rm.done();
			return;
		}
		memory.initializeMemoryData(memContext, rm);
	}
}
