/*******************************************************************************
 * Copyright (c) 2005 The Regents of the University of California.
 * This material was produced under U.S. Government contract W-7405-ENG-36
 * for Los Alamos National Laboratory, which is operated by the University
 * of California for the U.S. Department of Energy. The U.S. Government has
 * rights to use, reproduce, and distribute this software. NEITHER THE
 * GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
 * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
 * to produce derivative works, such modified software should be clearly marked,
 * so as not to confuse it with the version available from LANL.
 *
 * Additionally, 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
 *
 * LA-CC 04-115
 *******************************************************************************/
package org.eclipse.ptp.launch.internal;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IBinaryParser;
import org.eclipse.cdt.core.ICExtensionReference;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IPersistableSourceLocator;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ptp.core.IModelManager;
import org.eclipse.ptp.core.IPTPLaunchConfigurationConstants;
import org.eclipse.ptp.core.PTPCorePlugin;
import org.eclipse.ptp.core.attributes.AttributeManager;
import org.eclipse.ptp.core.attributes.BooleanAttribute;
import org.eclipse.ptp.core.attributes.EnumeratedAttribute;
import org.eclipse.ptp.core.attributes.IAttribute;
import org.eclipse.ptp.core.attributes.StringAttribute;
import org.eclipse.ptp.core.elementcontrols.IResourceManagerControl;
import org.eclipse.ptp.core.elements.IPJob;
import org.eclipse.ptp.core.elements.IPQueue;
import org.eclipse.ptp.core.elements.IPUniverse;
import org.eclipse.ptp.core.elements.IResourceManager;
import org.eclipse.ptp.core.elements.attributes.JobAttributes;
import org.eclipse.ptp.core.elements.attributes.ResourceManagerAttributes;
import org.eclipse.ptp.core.elements.events.IChangedJobEvent;
import org.eclipse.ptp.core.elements.events.IChangedMachineEvent;
import org.eclipse.ptp.core.elements.events.IChangedQueueEvent;
import org.eclipse.ptp.core.elements.events.INewJobEvent;
import org.eclipse.ptp.core.elements.events.INewMachineEvent;
import org.eclipse.ptp.core.elements.events.INewQueueEvent;
import org.eclipse.ptp.core.elements.events.IRemoveJobEvent;
import org.eclipse.ptp.core.elements.events.IRemoveMachineEvent;
import org.eclipse.ptp.core.elements.events.IRemoveQueueEvent;
import org.eclipse.ptp.core.elements.events.IResourceManagerChangeEvent;
import org.eclipse.ptp.core.elements.events.IResourceManagerErrorEvent;
import org.eclipse.ptp.core.elements.events.IResourceManagerSubmitJobErrorEvent;
import org.eclipse.ptp.core.elements.listeners.IQueueChildListener;
import org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener;
import org.eclipse.ptp.core.elements.listeners.IResourceManagerListener;
import org.eclipse.ptp.core.events.IChangedResourceManagerEvent;
import org.eclipse.ptp.core.events.INewResourceManagerEvent;
import org.eclipse.ptp.core.events.IRemoveResourceManagerEvent;
import org.eclipse.ptp.core.listeners.IModelManagerChildListener;
import org.eclipse.ptp.debug.core.IPDebugConfiguration;
import org.eclipse.ptp.debug.core.IPDebugger;
import org.eclipse.ptp.debug.core.PTPDebugCorePlugin;
import org.eclipse.ptp.debug.core.launch.IPLaunch;
import org.eclipse.ptp.debug.core.launch.PLaunch;
import org.eclipse.ptp.debug.ui.PTPDebugUIPlugin;
import org.eclipse.ptp.launch.PTPLaunchPlugin;
import org.eclipse.ptp.launch.data.ISynchronizationRule;
import org.eclipse.ptp.launch.data.RuleFactory;
import org.eclipse.ptp.launch.messages.Messages;
import org.eclipse.ptp.launch.rulesengine.ILaunchProcessCallback;
import org.eclipse.ptp.launch.rulesengine.IRuleAction;
import org.eclipse.ptp.launch.rulesengine.RuleActionFactory;
import org.eclipse.ptp.launch.ui.extensions.AbstractRMLaunchConfigurationFactory;
import org.eclipse.ptp.launch.ui.extensions.IRMLaunchConfigurationDynamicTab;
import org.eclipse.ptp.remote.core.IRemoteConnection;
import org.eclipse.ptp.remote.core.IRemoteConnectionManager;
import org.eclipse.ptp.remote.core.IRemoteFileManager;
import org.eclipse.ptp.remote.core.IRemoteServices;
import org.eclipse.ptp.remote.core.PTPRemoteCorePlugin;
import org.eclipse.ptp.rm.remote.core.AbstractRemoteResourceManagerConfiguration;
import org.eclipse.ptp.rmsystem.IResourceManagerConfiguration;
import org.eclipse.ptp.utils.core.linux.ArgumentParser;

/**
 *
 */
public abstract class AbstractParallelLaunchConfigurationDelegate extends
		LaunchConfigurationDelegate implements ILaunchProcessCallback {
	private List<ISynchronizationRule> extraSynchronizationRules;
	public enum JobStatus {SUBMITTED, COMPLETED, ERROR}

	/**
	 * The JobSubmission class encapsulates all the information used in
	 * a job submission. Once the job is created *and starts running*,
	 * this information is used to complete the launch.
	 */
	private class JobSubmission {
		private ILaunchConfiguration configuration;
		private String mode;
		private String id;
		private String error = null;
		private IPLaunch launch;
		private AttributeManager attrMgr;
		private IPDebugger debugger;
		private JobStatus status = JobStatus.SUBMITTED;
		private final ReentrantLock subLock = new ReentrantLock();;
		private final Condition subCondition = subLock.newCondition();

		public JobSubmission(int count, ILaunchConfiguration configuration, String mode, IPLaunch launch,
				AttributeManager attrMgr, IPDebugger debugger) {
			this.configuration = configuration;
			this.mode = mode;
			this.launch = launch;
			this.attrMgr = attrMgr;
			this.debugger = debugger;
			this.id = "JOB_" + Long.toString(System.currentTimeMillis()) + Integer.toString(count); //$NON-NLS-1$
		}

		/**
		 * Wait for the job state to change
		 *
		 * @return the state
		 */
		public JobStatus waitFor(IProgressMonitor monitor) {
			subLock.lock();
			try {
				while (!monitor.isCanceled() && status != JobStatus.SUBMITTED) {
					try {
						subCondition.await(100, TimeUnit.MILLISECONDS);
					} catch (InterruptedException e) {
						// Expect to be interrupted if monitor is canceled
					}
				}

				return status;
			} finally {
				subLock.unlock();
			}
		}

		/**
		 * @return the attrMgr
		 */
		public AttributeManager getAttrMgr() {
			return attrMgr;
		}

		/**
		 * @return the configuration
		 */
		public ILaunchConfiguration getConfiguration() {
			return configuration;
		}

		/**
		 * @return the debugger
		 */
		public IPDebugger getDebugger() {
			return debugger;
		}

		/**
		 * @return the error
		 */
		public String getError() {
			return error;
		}

		/**
		 * @return the job submission id
		 */
		public String getId() {
			return id;
		}

		/**
		 * @return the launch
		 */
		public IPLaunch getLaunch() {
			return launch;
		}

		/**
		 * @return the mode
		 */
		public String getMode() {
			return mode;
		}

		/**
		 * set the error
		 */
		public void setError(String error) {
			this.error = error;
			setStatus(JobStatus.ERROR);
		}

		/**
		 * set the current status
		 */
		public void setStatus(JobStatus status) {
			subLock.lock();
			try {
				this.status = status;
				subCondition.signalAll();
			} finally {
				subLock.unlock();
			}
		}
	}

	private final class MMChildListener implements IModelManagerChildListener {
		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.listeners.IModelManagerChildListener#handleEvent(org.eclipse.ptp.core.events.IChangedResourceManagerEvent)
		 */
		public void handleEvent(IChangedResourceManagerEvent e) {
			// Don't need to do anything
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.listeners.IModelManagerChildListener#handleEvent(org.eclipse.ptp.core.events.INewResourceManagerEvent)
		 */
		public void handleEvent(INewResourceManagerEvent e) {
			/*
			 * Add resource manager child listener so we get notified when new
			 * machines are added to the model.
			 */
			final IResourceManager rm = e.getResourceManager();
	        rm.addChildListener(resourceManagerChildListener);
	        rm.addElementListener(resourceManagerListener);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.listeners.IModelManagerChildListener#handleEvent(org.eclipse.ptp.core.events.IRemoveResourceManagerEvent)
		 */
		public void handleEvent(IRemoveResourceManagerEvent e) {
			/*
			 * Removed resource manager child listener when resource manager is removed.
			 */
			final IResourceManager rm = e.getResourceManager();
	        rm.removeChildListener(resourceManagerChildListener);
	        rm.removeElementListener(resourceManagerListener);
		}
	}

	private final class QueueChildListener implements IQueueChildListener {
		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IQueueChildListener#handleEvent(org.eclipse.ptp.core.elements.events.IChangedJobEvent)
		 */
		public void handleEvent(IChangedJobEvent e) {
			for (IPJob job : e.getJobs()) {
				/*
				 * If the job state has changed to running, find the JobSubmission that
				 * corresponds to this job and perform remainder of job launch actions
				 */
				StringAttribute subIdAttr = job.getAttribute(JobAttributes.getSubIdAttributeDefinition());
				if (subIdAttr != null) {
					IAttribute<?,?,?> stateAttr = job.getAttribute(JobAttributes.getStateAttributeDefinition());
					if (stateAttr != null) {
						JobAttributes.State state = (JobAttributes.State)((EnumeratedAttribute<?>)stateAttr).getValue();
						if (state == JobAttributes.State.RUNNING) {
							JobSubmission jobSub = jobSubmissions.remove(subIdAttr.getValue());
							if (jobSub != null) {
								jobSub.setStatus(JobStatus.COMPLETED);
								doCompleteJobLaunch(jobSub.getConfiguration(), jobSub.getMode(), jobSub.getLaunch(), jobSub.getAttrMgr(), jobSub.getDebugger(), job);
							}
						} else if(state == JobAttributes.State.TERMINATED || state == JobAttributes.State.ERROR) {
							JobSubmission jobSub = jobInfos.remove(subIdAttr.getValue());
							if(jobSub != null) {
								if (state == JobAttributes.State.TERMINATED) {
									ILaunchConfiguration lconf = jobSub.getConfiguration();
									// If needed, copy data back.
									try {
										// Get the list of paths to be copied back.
										doPosLaunchSynchronization(lconf);
									} catch (CoreException e1) {
										PTPLaunchPlugin.log(e1);
									}
								}
								doCleanuoLaunch(jobSub.getConfiguration(), jobSub.getMode(), jobSub.getLaunch(), jobSub.getAttrMgr(), jobSub.getDebugger(), job);
							}
						}
					}
				}
			}
		}


		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IQueueChildListener#handleEvent(org.eclipse.ptp.core.elements.events.INewJobEvent)
		 */
		public void handleEvent(INewJobEvent e) {
			for (IPJob job : e.getJobs()) {
				/*
				 * If the new job is one that we launched, check to see if it's in our list
				 * of job submissions. If not, assume that we have reconnected to a session
				 * so we need to re-create the launch configuration that was used launch it.
				 * If it's a debug job, and it has not yet started running, then
				 * start a debug session. It's possible the job will never run, so we
				 * need to clean up any debug sessions before exiting Eclipse.
				 */
				StringAttribute subAttr = job.getAttribute(JobAttributes.getSubIdAttributeDefinition());
				if (subAttr != null) {
					IAttribute<?,?,?> launchAttr = job.getAttribute(JobAttributes.getLaunchedByPTPFlagAttributeDefinition());
					if (launchAttr != null && ((BooleanAttribute)launchAttr).getValue()) {
						JobSubmission jobSub = jobSubmissions.get(subAttr.getValue());
						if (jobSub == null) {
							// recreate launch configuration
							// jobSub = ....;
							// jobSubmissions.put(job, jobSub);
						}
						IAttribute<?,?,?> debugAttr = job.getAttribute(JobAttributes.getDebugFlagAttributeDefinition());
						if (debugAttr != null && ((BooleanAttribute)debugAttr).getValue()) {
						}
					}
				}
			}
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IQueueChildListener#handleEvent(org.eclipse.ptp.core.elements.events.IRemoveJobEvent)
		 */
		public void handleEvent(IRemoveJobEvent e) {
		}
	}

	private final class RMChildListener implements IResourceManagerChildListener {
		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IResourceManagerMachineListener#handleEvent(org.eclipse.ptp.core.elements.events.IResourceManagerChangedMachineEvent)
		 */
		public void handleEvent(IChangedMachineEvent e) {
			// Don't need to do anything
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener#handleEvent(org.eclipse.ptp.core.elements.events.IResourceManagerChangedQueueEvent)
		 */
		public void handleEvent(IChangedQueueEvent e) {
			// Can safely ignore
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IResourceManagerMachineListener#handleEvent(org.eclipse.ptp.core.elements.events.IResourceManagerNewMachineEvent)
		 */
		public void handleEvent(INewMachineEvent e) {
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener#handleEvent(org.eclipse.ptp.core.elements.events.INewQueueEvent)
		 */
		public void handleEvent(INewQueueEvent e) {
			for (IPQueue queue : e.getQueues()) {
				queue.addChildListener(queueChildListener);
			}
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IResourceManagerMachineListener#handleEvent(org.eclipse.ptp.core.elements.events.IResourceManagerRemoveMachineEvent)
		 */
		public void handleEvent(IRemoveMachineEvent e) {
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IResourceManagerChildListener#handleEvent(org.eclipse.ptp.core.elements.events.IResourceManagerRemoveQueueEvent)
		 */
		public void handleEvent(IRemoveQueueEvent e) {
			for (IPQueue queue : e.getQueues()) {
				queue.removeChildListener(queueChildListener);
			}
		}
	}

	private final class RMListener implements IResourceManagerListener {
		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IResourceManagerListener#handleEvent(org.eclipse.ptp.core.elements.events.IResourceManagerChangeEvent)
		 */
		public void handleEvent(IResourceManagerChangeEvent e) {
			// Ignore
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IResourceManagerListener#handleEvent(org.eclipse.ptp.core.elements.events.IResourceManagerErrorEvent)
		 */
		public void handleEvent(IResourceManagerErrorEvent e) {
			// TODO Auto-generated method stub
		}

		/* (non-Javadoc)
		 * @see org.eclipse.ptp.core.elements.listeners.IResourceManagerListener#handleEvent(org.eclipse.ptp.core.elements.events.IResourceManagerSubmitJobErrorEvent)
		 */
		public void handleEvent(IResourceManagerSubmitJobErrorEvent e) {
			JobSubmission jobSub = jobSubmissions.remove(e.getJobSubmissionId());
			jobSub.setError(e.getMessage());
		}
	}

    /**
	 * Get the program arguments specified in the Arguments tab
	 *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected static String getArguments(ILaunchConfiguration configuration) throws CoreException {
	    return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_ARGUMENTS, (String)null);
	}

	/**
	 * Get the debugger executable path
	 *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected static String getDebuggerExePath(ILaunchConfiguration configuration) throws CoreException {
	    return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_DEBUGGER_EXECUTABLE_PATH, (String)null);
	}

	/**
	 * Get the ID of the debugger for this launch
	 *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected static String getDebuggerID(ILaunchConfiguration configuration) throws CoreException {
	    return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_DEBUGGER_ID, (String)null);
	}

	/**
     * Get the debugger "stop in main" flag
     *
	 * @param configuration
	 * @return "stop in main" flag
	 * @throws CoreException
	 */
	protected static boolean getDebuggerStopInMainFlag(ILaunchConfiguration configuration) throws CoreException {
	    return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_STOP_IN_MAIN, false);
	}

	/**
	 * Get the working directory for this debug session
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected static String getDebuggerWorkDirectory(ILaunchConfiguration configuration) throws CoreException {
	    return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_DEBUGGER_WORKING_DIR, (String)null);
	}

	/**
     * Get the absolute path of the executable to launch. If the executable is on a remote machine,
     * this is the path to the executable on that machine.
     *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected static String getExecutablePath(ILaunchConfiguration configuration) throws CoreException {
	    return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_EXECUTABLE_PATH, (String)null);
	}

    /**
	 * Get the name of the application to launch
	 *
	 * @deprecated
	 *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	@Deprecated
	protected static String getProgramName(ILaunchConfiguration configuration) throws CoreException {
	    return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_APPLICATION_NAME, (String)null);
	}

	/**
	 * Get the name of the project
	 *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected static String getProjectName(ILaunchConfiguration configuration) throws CoreException {
	    return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null);
	}

	/**
	 * Get the name of the queue for the launch
	 *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected static String getQueueName(ILaunchConfiguration configuration) throws CoreException {
		return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_QUEUE_NAME, (String)null);
	}

	/**
	 * Get the resource manager to use for the launch
	 *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected static String getResourceManagerUniqueName(ILaunchConfiguration configuration) throws CoreException {
		return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_RESOURCE_MANAGER_UNIQUENAME, (String)null);
	}

	/**
     * Get the working directory for the application launch
     *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected static String getWorkDirectory(ILaunchConfiguration configuration) throws CoreException {
	    return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_WORK_DIRECTORY, (String)null);
	}

	/**
	 * Get if the executable shall be copied to remote target before launch.
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	public boolean getCopyExecutable(ILaunchConfiguration configuration)
			throws CoreException {
		return configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_COPY_EXECUTABLE, false);
	}

	private int jobCount = 0;

	/*
	 * Model listeners
	 */
	private final IModelManagerChildListener modelManagerChildListener = new MMChildListener();
	private final IResourceManagerChildListener resourceManagerChildListener = new RMChildListener();
	private final IResourceManagerListener resourceManagerListener = new RMListener();
	private final IQueueChildListener queueChildListener = new QueueChildListener();
	/*
	 * HashMap used to keep track of job submissions
	 */
	protected Map<String, JobSubmission> jobSubmissions = Collections.synchronizedMap(new HashMap<String, JobSubmission>());
	/*
	 * Temporary workaround. Leave a copy of jobSubmissions to get job information even after the submission.
	 */
	protected Map<String, JobSubmission> jobInfos = Collections.synchronizedMap(new HashMap<String, JobSubmission>());

	public AbstractParallelLaunchConfigurationDelegate() {
		IModelManager mm = PTPCorePlugin.getDefault().getModelManager();
		synchronized (mm) {
		    for (IResourceManager rm : mm.getUniverse().getResourceManagers()) {
		    	for (IPQueue queue : rm.getQueues()) {
		    		queue.addChildListener(queueChildListener);
		    	}
		        rm.addChildListener(resourceManagerChildListener);
		        rm.addElementListener(resourceManagerListener);
		    }
		    mm.addListener(modelManagerChildListener);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getLaunch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String)
	 */
	@Override
	public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
		return new PLaunch(configuration, mode, null);
	}

	/**
	 * Get the attributes from the resource manager specific launch page.
	 *
	 * @param configuration
	 * @param mode
	 * @return IAttribute[]
	 * @throws CoreException
	 */
	private IAttribute<?,?,?>[] getResourceAttributes(ILaunchConfiguration configuration, String mode)
		throws CoreException {

		IResourceManager rm = getResourceManager(configuration);

		final AbstractRMLaunchConfigurationFactory rmFactory =
			PTPLaunchPlugin.getDefault().getRMLaunchConfigurationFactory(rm);
		if (rmFactory == null) {
			return new IAttribute[0];
		}
		IRMLaunchConfigurationDynamicTab rmDynamicTab = rmFactory.create(rm);
		return rmDynamicTab.getAttributes(rm, null, configuration, mode);
	}

	/**
	 * Abort the job launch if anything goes wrong.
	 *
	 * @param message
	 * @param exception
	 * @param code
	 * @throws CoreException
	 */
	protected void abort(String message, Throwable exception, int code) throws CoreException {
	    throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), code, message, exception));
	}

	/**
	 * This method is called when the job state changes to RUNNING. This allows the launcher to
	 * complete the job launch.
	 *
	 * @param configuration
	 * @param mode
	 * @param launch
	 * @param mgr
	 * @param debugger
	 * @param job
	 */
	protected abstract void doCompleteJobLaunch(ILaunchConfiguration configuration, String mode, IPLaunch launch,
			AttributeManager mgr, IPDebugger debugger, IPJob job);

	protected abstract void doCleanuoLaunch(ILaunchConfiguration configuration,
			String mode, IPLaunch launch, AttributeManager attrMgr,
			IPDebugger debugger, IPJob job);

//	protected void doCleanupJobLaunch(ILaunchConfiguration configuration, String mode,
//			IPLaunch launch, AttributeManager attrMgr, IPDebugger debugger,
//			IPJob job) {
//		if (debugger != null) {
//			debugger.cleanup(configuration, attrMgr, launch);
//		}
//	}

	/**
	 * Get all the attributes specified in the launch configuration.
	 *
	 * @param configuration
	 * @param mode
	 * @return AttributeManager
	 * @throws CoreException
	 */
	protected AttributeManager getAttributeManager(ILaunchConfiguration configuration, String mode) throws CoreException {
		IResourceManager rm = getResourceManager(configuration);
		if (rm == null) {
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_No_ResourceManager, null, 0);
		}

		AttributeManager attrMgr = new AttributeManager();

		/*
		 * Collect attributes from Resources tab
		 */
		attrMgr.addAttributes(getResourceAttributes(configuration, mode));

		/*
		 * Make sure there is a queue, even if the resources tab doesn't require
		 * one to be specified.
		 */
		if (attrMgr.getAttribute(JobAttributes.getQueueIdAttributeDefinition()) == null) {
			IPQueue queue = getQueueDefault(rm);
			attrMgr.addAttribute(JobAttributes.getQueueIdAttributeDefinition().create(queue.getID()));
		}

		/*
		 * Collect attributes from Application tab
		 */
		IPath programPath = verifyExecutablePath(configuration);
		attrMgr.addAttribute(JobAttributes.getExecutableNameAttributeDefinition().create(programPath.lastSegment()));

		String path = programPath.removeLastSegments(1).toString();
		if (path != null) {
			attrMgr.addAttribute(JobAttributes.getExecutablePathAttributeDefinition().create(path));
		}

		/*
		 * Collect attributes from Debugger tab
		 */
		verifyDebuggerPath(configuration);
		Boolean stopInMainFlag = getDebuggerStopInMainFlag(configuration);
		attrMgr.addAttribute(JobAttributes.getDebuggerStopInMainFlagAttributeDefinition().create(stopInMainFlag));

		/*
		 * Collect attributes from Arguments tab
		 */
		String wd = verifyWorkDirectory(configuration);
		if (wd != null) {
			attrMgr.addAttribute(JobAttributes.getWorkingDirectoryAttributeDefinition().create(wd));
		}

		String[] argArr = getProgramArguments(configuration);
		if (argArr != null) {
			attrMgr.addAttribute(JobAttributes.getProgramArgumentsAttributeDefinition().create(argArr));
		}

		/*
		 * Collect attributes from Environment tab
		 */
		String[] envArr = getEnvironmentToAppend(configuration);
		if (envArr != null) {
			attrMgr.addAttribute(JobAttributes.getEnvironmentAttributeDefinition().create(envArr));
		}

		/*
		 * PTP launched this job
		 */
		attrMgr.addAttribute(JobAttributes.getLaunchedByPTPFlagAttributeDefinition().create(true));

		return attrMgr;
	}

	/**
	 * Get the debugger configuration
	 *
	 * @param configuration launch configuration
	 * @return debugger configuration
	 * @throws CoreException
	 */
	protected IPDebugConfiguration getDebugConfig(ILaunchConfiguration config) throws CoreException {
		IPDebugConfiguration dbgCfg = null;
		try {
			dbgCfg = PTPDebugCorePlugin.getDefault().getDebugConfiguration(getDebuggerID(config));
		} catch (CoreException e) {
			System.out.println("ParallelLaunchConfigurationDelegate.getDebugConfig() Error"); //$NON-NLS-1$
			throw e;
		}
		return dbgCfg;
	}

	/**
	 * Convert application arguments to an array of strings.
	 *
	 * @param configuration launch configuration
	 * @return array of strings containing the program arguments
	 * @throws CoreException
	 */
	protected String[] getProgramArguments(ILaunchConfiguration configuration) throws CoreException {
		String temp = getArguments(configuration);
		if (temp != null && temp.length() > 0) {
			// Replaced PTPs ArgumentParser with better ArgumentParser contributed with RemoteTools.
//			ArgumentParser ap = new ArgumentParser(temp);
//			List<String> args = ap.getArguments();
			ArgumentParser ap = new ArgumentParser(temp);
			List<String> args = ap.getTokenList();
			if (args != null) {
				return args.toArray(new String[args.size()]);
			}
		}
		return new String[0];
	}

	/**
	 * Get the path of the program to launch. No longer used since the program may not be
	 * on the local machine.
	 *
	 * @deprecated
	 *
	 * @param configuration launch configuration
	 * @return IPath corresponding to program executable
	 * @throws CoreException
	 */
	@Deprecated
	protected IPath getProgramFile(ILaunchConfiguration configuration) throws CoreException {
		IProject project = verifyProject(configuration);
		String fileName = getProgramName(configuration);
		if (fileName == null)
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_Application_file_not_specified, null, IStatus.INFO);

		IPath programPath = new Path(fileName);
		if (!programPath.isAbsolute()) {
			programPath = project.getFile(programPath).getLocation();
		}
		if (!programPath.toFile().exists()) {
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_Application_file_does_not_exist,
					new FileNotFoundException(
							NLS.bind(Messages.AbstractParallelLaunchConfigurationDelegate_Path_not_found, new Object[] {programPath.toString()})),
							IPTPLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST);
		}
		/* --old
		IFile programPath = project.getFile(fileName);
		if (programPath == null || !programPath.exists() || !programPath.getLocation().toFile().exists())
			abort(LaunchMessages.getResourceString("AbstractParallelLaunchConfigurationDelegate.Application_file_does_not_exist"), new FileNotFoundException(LaunchMessages.getFormattedResourceString("AbstractParallelLaunchConfigurationDelegate.Application_path_not_found", programPath.getLocation().toString())), IStatus.INFO);
		 */
		return programPath;
	}

	/**
	 * Get the IProject object from the project name.
	 *
     * @param project name of the project
     * @return IProject resource
     */
    protected IProject getProject(String project) {
        return getWorkspaceRoot().getProject(project);
    }

	/**
	 * Get the default queue for the given resource manager
	 *
	 * @param rm resource manager
	 * @return default queue
	 */
	protected IPQueue getQueueDefault(IResourceManager rm) {
		final IPQueue[] queues = rm.getQueues();
		if (queues.length == 0) {
			return null;
		}
		return queues[0];
	}

	/**
	 * Find the resource manager that corresponds to the unique name specified in the configuration
	 *
	 * @param configuration launch configuration
	 * @return resource manager
	 * @throws CoreException
	 */
	protected IResourceManager getResourceManager(ILaunchConfiguration configuration) throws CoreException {
		IPUniverse universe = PTPCorePlugin.getDefault().getUniverse();
		IResourceManager[] rms = universe.getResourceManagers();
		String rmUniqueName = getResourceManagerUniqueName(configuration);
		for (IResourceManager rm : rms) {
			if (rm.getState() == ResourceManagerAttributes.State.STARTED &&
					rm.getUniqueName().equals(rmUniqueName)) {
				return rm;
			}
		}
		return null;
	}

	/**
	 * Get the workspace root.
	 *
     * @return workspace root
     */
    protected IWorkspaceRoot getWorkspaceRoot() {
    	return ResourcesPlugin.getWorkspace().getRoot();
    }

	/**
	 * Create a source locator from the ID specified in the configuration, or create
	 * a default one if it hasn't been specified.
	 *
	 * @param launch
	 * @param configuration
	 * @throws CoreException
	 */
	protected void setDefaultSourceLocator(ILaunch launch, ILaunchConfiguration configuration) throws CoreException {
		//  set default source locator if none specified
		if (launch.getSourceLocator() == null) {
			IPersistableSourceLocator sourceLocator;
			String id = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null);
			if (id == null) {
				sourceLocator = PTPDebugUIPlugin.createDefaultSourceLocator();
				sourceLocator.initializeDefaults(configuration);
			} else {
				sourceLocator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(id);
				String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null);
				if (memento == null) {
					sourceLocator.initializeDefaults(configuration);
				} else {
					sourceLocator.initializeFromMemento(memento);
				}
			}
			launch.setSourceLocator(sourceLocator);
		}
	}

	/**
	 * Set the source locator for this application
	 *
	 * @param launch
	 * @param config
	 * @throws CoreException
	 */
	protected void setSourceLocator(ILaunch launch, ILaunchConfiguration config) throws CoreException {
		setDefaultSourceLocator(launch, config);
	}

	/**
	 * Submit a job to the resource manager. Keeps track of the submission so we know when the
	 * job actually starts running. When this happens, the abstract method doCompleteJobLaunch()
	 * is invoked.
	 *
	 * @param configuration
	 * @param mode
	 * @param launch
	 * @param attrMgr
	 * @param debugger
	 * @param monitor
	 * @throws CoreException
	 */
	protected void submitJob(ILaunchConfiguration configuration, String mode, IPLaunch launch,
		AttributeManager attrMgr, IPDebugger debugger, IProgressMonitor monitor) throws CoreException {

		final IResourceManager rm = getResourceManager(configuration);
		if (rm == null) {
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_No_ResourceManager, null, 0);
		}

		JobSubmission jobSub = new JobSubmission(jobCount++, configuration, mode, launch, attrMgr, debugger);
		jobSubmissions.put(jobSub.getId(), jobSub);
		jobInfos.put(jobSub.getId(), jobSub);

		rm.submitJob(jobSub.getId(), configuration, attrMgr, monitor);

		JobStatus status = jobSub.waitFor(monitor);

		if (status == JobStatus.ERROR) {
			abort(jobSub.getError(), null, IStatus.ERROR);
		}
	}

	/**
	 * @param project
	 * @param exePath
	 * @return
	 * @throws CoreException
	 * @deprecated
	 */
	@Deprecated
	protected IBinaryObject verifyBinary(IProject project, IPath exePath) throws CoreException {
		ICExtensionReference[] parserRef = CCorePlugin.getDefault().getBinaryParserExtensions(project);
		for (int i = 0; i < parserRef.length; i++) {
			try {
				IBinaryParser parser = (IBinaryParser) parserRef[i].createExtension();
				IBinaryObject exe = (IBinaryObject) parser.getBinary(exePath);
				if (exe != null) {
					return exe;
				}
			} catch (ClassCastException e) {
			} catch (IOException e) {
			}
		}
		IBinaryParser parser = CCorePlugin.getDefault().getDefaultBinaryParser();
		try {
			return (IBinaryObject) parser.getBinary(exePath);
		} catch (ClassCastException e) {
		} catch (IOException e) {
		}
		Throwable exception = new FileNotFoundException(Messages.AbstractParallelLaunchConfigurationDelegate_Program_is_not_a_recongnized_executable);
		int code = IPTPLaunchConfigurationConstants.ERR_PROGRAM_NOT_BINARY;
		MultiStatus status = new MultiStatus(PTPCorePlugin.getUniqueIdentifier(), code, Messages.AbstractParallelLaunchConfigurationDelegate_Program_is_not_a_recongnized_executable, exception);
		status.add(new Status(IStatus.ERROR, PTPCorePlugin.getUniqueIdentifier(), code, exception == null ? "" : exception.getLocalizedMessage(), exception)); //$NON-NLS-1$
		throw new CoreException(status);
	}

	/**
	 * @param path
	 * @throws CoreException
	 */
	protected void verifyDebuggerPath(ILaunchConfiguration configuration) throws CoreException {
		String dbgPath = getDebuggerExePath(configuration);
		try {
			verifyResource(dbgPath, configuration);
		} catch (CoreException e) {
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_Debugger_path_not_found,
					new FileNotFoundException(e.getLocalizedMessage()), IStatus.INFO);
		}
	}

	/**
	 * Verify the validity of executable path.
	 * If the executable is to be copied, then no additional verification is required.
	 * Otherwise, the path must point to an existing file.
	 * @param configuration
	 * @return
	 */
	protected IPath verifyExecutablePath(ILaunchConfiguration configuration)  throws CoreException {
		if (getCopyExecutable(configuration)) {
			return new Path(getExecutablePath(configuration));
		} else {
			String exePath = getExecutablePath(configuration);
			try {
				return verifyResource(exePath, configuration);
			} catch (CoreException e) {
				abort(Messages.AbstractParallelLaunchConfigurationDelegate_Application_file_does_not_exist,
						new FileNotFoundException(e.getLocalizedMessage()),	IStatus.INFO);
				return null;
			}
		}
	}

	/**
	 * @param path
	 * @return
	 * @deprecated
	 */
	@Deprecated
	protected boolean verifyPath(String path) {
		IPath programPath = new Path(path);
		if (programPath == null || programPath.isEmpty() || !programPath.toFile().exists()) {
			return false;
		}
		return true;
	}

	/**
	 * Verify that the project exists prior to the launch.
	 *
     * @param configuration
     * @return
     * @throws CoreException
     */
    protected IProject verifyProject(ILaunchConfiguration configuration) throws CoreException {
        String proName = getProjectName(configuration);
        if (proName == null) {
   			abort(Messages.AbstractParallelLaunchConfigurationDelegate_Project_not_specified, null, IStatus.INFO);
        }

        IProject project = getProject(proName);
        if (project == null || !project.exists() || !project.isOpen()) {
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_Project_does_not_exist_or_is_not_a_project, null, IStatus.INFO);
        }

        return project;
    }

	/**
	 * @param path
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected IPath verifyResource(String path, ILaunchConfiguration configuration) throws CoreException {
		IResourceManagerControl rm = (IResourceManagerControl)getResourceManager(configuration);
		if (rm == null) {
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_No_ResourceManager, null, IStatus.ERROR);
		}
		
		IResourceManagerConfiguration conf = rm.getConfiguration();
		if (!(conf instanceof AbstractRemoteResourceManagerConfiguration)) {
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_Unsupported_resource_manager_type, null, IStatus.ERROR);
		}
		
		AbstractRemoteResourceManagerConfiguration remConf = (AbstractRemoteResourceManagerConfiguration)conf;
		IRemoteServices remoteServices = PTPRemoteCorePlugin.getDefault().getRemoteServices(remConf.getRemoteServicesId());
		if (remoteServices == null) {
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_Unknown_remote_services, null, IStatus.ERROR);
		}
		IRemoteConnectionManager connMgr = remoteServices.getConnectionManager();
		IRemoteConnection conn = connMgr.getConnection(remConf.getConnectionName());
		IRemoteFileManager fileManager = remoteServices.getFileManager(conn);
		IPath resPath = new Path(path);
		try {
			IFileStore res = fileManager.getResource(resPath, new NullProgressMonitor());
			if (!res.fetchInfo().exists()) {
				abort(NLS.bind(Messages.AbstractParallelLaunchConfigurationDelegate_Path_not_found, new Object[] {path}), null, IStatus.INFO);
			}
		} catch (IOException e) {
			abort(Messages.AbstractParallelLaunchConfigurationDelegate_Error_fetching_resource, e.getCause(), IStatus.ERROR);
		}
		return resPath;
	}

	/**
	 * Check if the copy local file is enabled. If it is, copy the executable file from
	 * the local host to the remote host.
	 *
	 * @param configuration
	 * @throws CoreException
	 */
	protected void copyExecutable(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {
		boolean copyExecutable =
			getCopyExecutable(configuration);

		if(copyExecutable) {
			// Get remote and local paths
			String remotePath = getExecutablePath(configuration);
			String localPath = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_LOCAL_EXECUTABLE_PATH,
					(String)null);

			// Check if local path is valid
			if(localPath == null) {
				// Throws exception
			}

			// Copy data
			copyFileToRemoteHost(localPath, remotePath, configuration, monitor);
		}
	}

	/**
	 * Copy a data from a path (can be a file or directory) from the remote host to
	 * the local host.
	 *
	 * @param remotePath
	 * @param localPath
	 * @param configuration
	 * @throws CoreException
	 */
	protected void copyFileFromRemoteHost(String remotePath, String localPath, ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {

		/*IResourceManagerControl rm = (IResourceManagerControl)getResourceManager(configuration);
		if (rm != null) {
			IResourceManagerConfiguration conf = rm.getConfiguration();
			if (conf instanceof AbstractRemoteResourceManagerConfiguration) {
				AbstractRemoteResourceManagerConfiguration remConf = (AbstractRemoteResourceManagerConfiguration)conf;

				IRemoteServices localServices = PTPRemoteCorePlugin.getDefault().getRemoteServices("org.eclipse.ptp.remote.core.LocalServices");
				IRemoteServices remoteServices = PTPRemoteCorePlugin.getDefault().getRemoteServices(remConf.getRemoteServicesId());
				if (remoteServices != null && localServices != null) {
					IRemoteConnectionManager lconnMgr = localServices.getConnectionManager();
					IRemoteConnection lconn = lconnMgr.getConnection(null); // Since it's a local service, doesn't matter which parameter is passed*/
					IRemoteFileManager localFileManager = getLocalFileManager(configuration);//localServices.getFileManager(lconn);

					/*IRemoteConnectionManager rconnMgr = remoteServices.getConnectionManager();
					IRemoteConnection rconn = rconnMgr.getConnection(remConf.getConnectionName());*/
					IRemoteFileManager remoteFileManager = getRemoteFileManager(configuration);//remoteServices.getFileManager(rconn);

					try {
						IFileStore rres = remoteFileManager.getResource(new Path(remotePath), monitor);

						if(!rres.fetchInfo().exists()) {
							// Local file not found!
							throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.PLUGIN_ID, 
									Messages.AbstractParallelLaunchConfigurationDelegate_Remote_resource_does_not_exist));
						}
						IFileStore lres = localFileManager.getResource(new Path(localPath), new NullProgressMonitor());

						// Copy file
						rres.copy(lres, EFS.OVERWRITE, monitor);
					} catch (IOException e) {
						throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.PLUGIN_ID, 
								Messages.AbstractParallelLaunchConfigurationDelegate_Could_not_retrieve_remote_resource_info));
					}
	/*			}
			} else {
				// FIXME: work out what to do for RM's that don't extend AbstractRemoteResourceManagerConfiguration
			}
		}*/
	}

	/**
	 * Copy a data from a path (can be a file or directory) from the local host to
	 * the remote host.
	 *
	 * @param localPath
	 * @param remotePath
	 * @param configuration
	 * @throws CoreException
	 */
	protected void copyFileToRemoteHost(String localPath, String remotePath, ILaunchConfiguration configuration,
			IProgressMonitor monitor) throws CoreException {
					IRemoteFileManager localFileManager = getLocalFileManager(configuration);

					IRemoteFileManager remoteFileManager = getRemoteFileManager(configuration);

					try {
						IFileStore lres = localFileManager.getResource(new Path(localPath), new NullProgressMonitor());
						if(!lres.fetchInfo().exists()) {
							// Local file not found!
							throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.PLUGIN_ID, 
									Messages.AbstractParallelLaunchConfigurationDelegate_Local_resource_does_not_exist));
						}
						IFileStore rres = remoteFileManager.getResource(new Path(remotePath), monitor);

						// Copy file
						lres.copy(rres, EFS.OVERWRITE, monitor);

					} catch (IOException e) {
						throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.PLUGIN_ID, 
								Messages.AbstractParallelLaunchConfigurationDelegate_Could_not_retrieve_local_resource_info));
					}
	}

	/**
	 * Verify the working directory. If no working directory is specified, the default is
	 * the location of the executable.
	 *
	 * @param configuration
	 * @return
	 * @throws CoreException
	 */
	protected String verifyWorkDirectory(ILaunchConfiguration configuration) throws CoreException {
		IPath path;
        String workPath = getWorkDirectory(configuration);
        if (workPath == null) {
        	path = verifyExecutablePath(configuration).removeLastSegments(1);
		} else {
			path = verifyResource(workPath, configuration);
		}
		return path.toString();
    }

	/**
	 * This method does the synchronization step before the job submission
	 *
	 * @param configuration
	 * @param monitor
	 */
	protected void doPreLaunchSynchronization(ILaunchConfiguration configuration,
			IProgressMonitor monitor) throws CoreException {
		boolean syncBefore = configuration.getAttribute(
				IPTPLaunchConfigurationConstants.ATTR_SYNC_BEFORE, false);
		if(!syncBefore)
			return;

		// This faction generate action objects which execute according to rules
		RuleActionFactory ruleActFactory = new RuleActionFactory(configuration, this, monitor);

		List<?> rulesList = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_SYNC_RULES, new ArrayList<String>());

		// Iterate over rules executing them
		for (Object ruleObj : rulesList) {
			ISynchronizationRule syncRule =
				RuleFactory.createRuleFromString((String)ruleObj);
			if(syncRule.isUploadRule()) {
				// Execute the action
				IRuleAction action = ruleActFactory.getAction(syncRule);
				action.run();
			}

		}
	}

	protected void doPosLaunchSynchronization(ILaunchConfiguration configuration)  throws CoreException {
		boolean syncAfter;
		syncAfter = configuration.getAttribute(
				IPTPLaunchConfigurationConstants.ATTR_SYNC_AFTER, false);
		if(!syncAfter)
			return;
		List<?> rulesList = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_SYNC_RULES, new ArrayList<String>());

		// This faction generate action objects which execute according to rules
		RuleActionFactory ruleActFactory = new RuleActionFactory(configuration, this, new NullProgressMonitor());

		for (Object ruleObj : rulesList) {
			ISynchronizationRule syncRule =
				RuleFactory.createRuleFromString((String)ruleObj);
			if(syncRule.isDownloadRule()) {
				// Execute the action
				IRuleAction action = ruleActFactory.getAction(syncRule);
				action.run();
			}
		}
	}

	/**
	 * Returns the (possible empty) list of synchronization rule objects according to the rules described in the configuration.
	 */
	protected ISynchronizationRule[] getSynchronizeRules(ILaunchConfiguration configuration) throws CoreException {
		List<?> ruleStrings = configuration.getAttribute(IPTPLaunchConfigurationConstants.ATTR_SYNC_RULES, new ArrayList<String>());
		List<ISynchronizationRule> result = new ArrayList<ISynchronizationRule>();

		for (Object ruleObj : ruleStrings) {
			String element = (String) ruleObj;
			try {
				ISynchronizationRule rule = RuleFactory.createRuleFromString(element);
				result.add(rule);
			} catch (RuntimeException e) {
				throw new CoreException(new Status(Status.ERROR,
						PTPLaunchPlugin.PLUGIN_ID,
						Messages.AbstractParallelLaunchConfigurationDelegate_Error_converting_rules));
			}
		}

		return (ISynchronizationRule[]) result.toArray(new ISynchronizationRule[result.size()]);
	}

	// Methods below implement the ILaunchProcessCallback interface

	public void addSynchronizationRule(ISynchronizationRule rule) {
		extraSynchronizationRules.add(rule);
	}

	public IRemoteFileManager getLocalFileManager(ILaunchConfiguration configuration) throws CoreException {
		IResourceManagerControl rm = (IResourceManagerControl)getResourceManager(configuration);
		if (rm != null) {
			IResourceManagerConfiguration conf = rm.getConfiguration();
			if (conf instanceof AbstractRemoteResourceManagerConfiguration) {
				IRemoteServices localServices = PTPRemoteCorePlugin.getDefault().getRemoteServices("org.eclipse.ptp.remote.LocalServices"); //$NON-NLS-1$
				if (localServices != null) {
					IRemoteConnectionManager lconnMgr = localServices.getConnectionManager();
					IRemoteConnection lconn = lconnMgr.getConnection(null); // Since it's a local service, doesn't matter which parameter is passed
					IRemoteFileManager localFileManager = localServices.getFileManager(lconn);

					return localFileManager;
				}
			}
		}

		return null;
	}

	public IRemoteFileManager getRemoteFileManager(ILaunchConfiguration configuration) throws CoreException {
		IResourceManagerControl rm = (IResourceManagerControl)getResourceManager(configuration);
		if (rm != null) {
			IResourceManagerConfiguration conf = rm.getConfiguration();
			if (conf instanceof AbstractRemoteResourceManagerConfiguration) {
				AbstractRemoteResourceManagerConfiguration remConf = (AbstractRemoteResourceManagerConfiguration)conf;

				IRemoteServices remoteServices = PTPRemoteCorePlugin.getDefault().getRemoteServices(remConf.getRemoteServicesId());
				if (remoteServices != null) {

					IRemoteConnectionManager rconnMgr = remoteServices.getConnectionManager();
					IRemoteConnection rconn = rconnMgr.getConnection(remConf.getConnectionName());
					IRemoteFileManager remoteFileManager = remoteServices.getFileManager(rconn);

					return remoteFileManager;
				}
			}
		}
		return null;
	}

	protected static String [] getEnvironmentToAppend(ILaunchConfiguration configuration) throws CoreException {
		Map<?,?> defaultEnv = null;
		Map<?,?> configEnv = configuration.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, defaultEnv);
		if (configEnv == null) {
			return null;
		}
		if (! configuration.getAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true)) {
			throw new CoreException(new Status(IStatus.ERROR, PTPLaunchPlugin.getUniqueIdentifier(), 
					Messages.AbstractParallelLaunchConfigurationDelegate_Parallel_launcher_does_not_support));
		}

		List<String> strings = new ArrayList<String>(configEnv.size());
		Iterator<?> iter= configEnv.entrySet().iterator();
		while (iter.hasNext()) {
			Entry<?,?> entry = (Entry<?, ?>) iter.next();
			String key = (String) entry.getKey();
            String value = (String) entry.getValue();
            strings.add(key+"="+value); //$NON-NLS-1$

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

}
