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

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ptp.core.PTPCorePlugin;
import org.eclipse.ptp.core.attributes.ArrayAttribute;
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.IAttributeDefinition;
import org.eclipse.ptp.core.attributes.IllegalValueException;
import org.eclipse.ptp.core.attributes.StringAttribute;
import org.eclipse.ptp.core.elements.IPJob;
import org.eclipse.ptp.core.elements.IPQueue;
import org.eclipse.ptp.core.elements.IResourceManager;
import org.eclipse.ptp.core.elements.attributes.JobAttributes;
import org.eclipse.ptp.remote.core.IRemoteProcess;
import org.eclipse.ptp.remote.core.IRemoteProcessBuilder;
import org.eclipse.ptp.rm.core.ToolsRMPlugin;
import org.eclipse.ptp.rm.core.messages.Messages;
import org.eclipse.ptp.rm.core.rmsystem.AbstractEffectiveToolRMConfiguration;
import org.eclipse.ptp.rm.core.utils.DebugUtil;
import org.eclipse.ptp.utils.core.linux.ArgumentParser;

/**
 * Implements a job that controls the parallel application launched with a command line tool.
 * This class is different from {@link AbstractRemoteCommandJob} because it is not aimed towards parsing output of the
 * tool called by command line, but to prepare a whole launch environment for the command line tool, also supporting
 * semantics of the parallel application launcher.
 *
 * @author Daniel Felix Ferber
 */
public abstract class AbstractToolRuntimeSystemJob extends Job implements IToolRuntimeSystemJob {

	protected String jobID;
	protected String queueID;
	protected boolean debug = false;
	protected IRemoteProcess process = null;
	protected AttributeManager attrMgr;
	protected AbstractToolRuntimeSystem rtSystem;

	protected boolean terminateJobFlag = false;

	public AbstractToolRuntimeSystemJob(String jobID, String queueID, String name, AbstractToolRuntimeSystem rtSystem,
			AttributeManager attrMgr) {
		super(name);
		this.attrMgr = attrMgr;
		this.rtSystem = rtSystem;
		this.jobID = jobID;
		this.queueID = queueID;
	}

	@Override
	public Object getAdapter(Class adapter) {
		if (adapter == IToolRuntimeSystemJob.class) {
			return this;
		}
		return super.getAdapter(adapter);
	}

	public String getQueueID() {
		return queueID;
	}

	public String getJobID() {
		return jobID;
	}

	public AbstractToolRuntimeSystem getRtSystem() {
		return rtSystem;
	}

	public AttributeManager getAttrMgr() {
		return attrMgr;
	}
	
	public boolean isDebug() {
		return debug;
	}

	@Override
	protected IStatus run(IProgressMonitor monitor) {
		BooleanAttribute debugAttr = attrMgr.getAttribute(JobAttributes.getDebugFlagAttributeDefinition());
		if (debugAttr != null) {
			debug = debugAttr.getValue().booleanValue();
		}
		
		changeJobState(JobAttributes.State.STARTED);

		if (DebugUtil.RTS_JOB_TRACING_MORE) {
			System.out.println("Launch attributes:"); //$NON-NLS-1$
			String array[] = getAttrMgr().toStringArray();
			for (int i = 0; i < array.length; i++) {
				System.out.println(array[i]);
			}
		}

		try {
			DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "RTS job #{0}: handle prepare", jobID); //$NON-NLS-1$
			doPrepareExecution(monitor);
		} catch (CoreException e) {
			changeJobState(JobAttributes.State.ERROR);
			return new Status(IStatus.ERROR, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_Exception_PrepareExecution, e);
		}
		
		if (monitor.isCanceled()) {
			changeJobState(JobAttributes.State.TERMINATED);
			return new Status(IStatus.OK, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_UserCanceled);
		}

		try {
			/*
			 * Calculate command and environment.
			 */
			DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "About to run RTS job #{0}.", jobID); //$NON-NLS-1$
			List<String> command = null;
			Map<String,String> environment = null;
			String directory = null;
			try {
				AttributeManager baseSubstitutionAttributeManager = retrieveBaseSubstitutionAttributes();
				environment = retrieveEnvironment(baseSubstitutionAttributeManager);
				directory = retrieveWorkingDirectory(baseSubstitutionAttributeManager);

				AttributeManager commandSubstitutionAttributeManager = retrieveCommandSubstitutionAttributes(baseSubstitutionAttributeManager, directory, environment);
				if (isDebug()) {
					command = retrieveCreateDebugCommand(commandSubstitutionAttributeManager);
				} else {
					command = retrieveCreateLaunchCommand(commandSubstitutionAttributeManager);
				}
				if (DebugUtil.RTS_JOB_TRACING) {
					System.out.println("Available macros for environment and work directory:"); //$NON-NLS-1$
					for (IAttribute<?, ?, ?> attr : baseSubstitutionAttributeManager.getAttributes()) {
						System.out.println(MessageFormat.format("  {0}={1}", attr.getDefinition().getId(), attr.getValueAsString())); //$NON-NLS-1$
					}
					System.out.println("Available macros for command:"); //$NON-NLS-1$
					for (IAttribute<?, ?, ?> attr : commandSubstitutionAttributeManager.getAttributes()) {
						System.out.println(MessageFormat.format("  {0}={1}", attr.getDefinition().getId(), attr.getValueAsString())); //$NON-NLS-1$
					}
					System.out.println("Environment variables:"); //$NON-NLS-1$
					for (Entry<String, String> env : environment.entrySet()) {
						System.out.println(MessageFormat.format("  export {0}={1}", env.getKey(), env.getValue())); //$NON-NLS-1$
					}
					System.out.println(MessageFormat.format("Work directory: {0}", directory)); //$NON-NLS-1$
					ArgumentParser argumentParser = new ArgumentParser(command);
					System.out.println(MessageFormat.format("Command: {0}", argumentParser.getCommandLine(false))); //$NON-NLS-1$
				}
			} catch (CoreException e) {
				changeJobState(JobAttributes.State.ERROR);
				return new Status(IStatus.ERROR, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_Exception_CreateCommand, e);
			}

			try {
				DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "RTS job #{0}: handle before execution", jobID); //$NON-NLS-1$
				doBeforeExecution(monitor);
			} catch (CoreException e) {
				changeJobState(JobAttributes.State.ERROR);
				return new Status(IStatus.ERROR, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_Exception_BeforeExecution, e);
			}

			if (monitor.isCanceled()) {
				changeJobState(JobAttributes.State.TERMINATED);
				return new Status(IStatus.OK, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_UserCanceled);
			}

			/*
			 * Execute remote command for the job.
			 */
			try {
				IRemoteProcessBuilder processBuilder = rtSystem.createProcessBuilder(command, directory);
				processBuilder.environment().putAll(environment);
				DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "RTS job #{0}: start", jobID); //$NON-NLS-1$
				process = processBuilder.start();
			} catch (IOException e) {
				changeJobState(JobAttributes.State.ERROR);
				return new Status(IStatus.ERROR, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_Exception_ExecuteCommand, e);
			}

			try {
				DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "RTS job #{0}: handle start", jobID); //$NON-NLS-1$
				doExecutionStarted(monitor);
			} catch (CoreException e) {
				changeJobState(JobAttributes.State.ERROR);
				return new Status(IStatus.ERROR, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_Exception_ExecutionStarted, e);
			}

			if (monitor.isCanceled()) {
				changeJobState(JobAttributes.State.TERMINATED);
				return new Status(IStatus.OK, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_UserCanceled);
			}

			changeJobState(JobAttributes.State.RUNNING);

			try {
				DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "RTS job #{0}: wait to finish", jobID); //$NON-NLS-1$
				doWaitExecution(monitor);
			} catch (CoreException e) {
				changeJobState(JobAttributes.State.ERROR);
				return new Status(IStatus.ERROR, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_Exception_WaitExecution, e);
			}

			if (monitor.isCanceled()) {
				changeJobState(JobAttributes.State.TERMINATED);
				return new Status(IStatus.OK, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_UserCanceled);
			}

			DebugUtil.trace(DebugUtil.RTS_JOB_TRACING, "RTS job #{0}: exit value {1}", jobID, process.exitValue()); //$NON-NLS-1$


			//			try {
			//				DebugUtil.trace(DebugUtil.COMMAND_TRACING, "RTS job #{0}: wait to finish", jobID); //$NON-NLS-1$
			//				process.waitFor();
			//			} catch (InterruptedException e) {
			//				changeJobState(JobAttributes.State.ERROR);
			//				return new Status(IStatus.ERROR, Activator.getDefault().getBundle().getSymbolicName(), "Failed while terminating the command.", e);
			//			}

			try {
				DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "RTS job #{0}: handle finish", jobID); //$NON-NLS-1$
				doExecutionFinished(monitor);
			} catch (CoreException e) {
				changeJobState(JobAttributes.State.ERROR);
				return new Status(IStatus.ERROR, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), Messages.AbstractToolRuntimeSystemJob_Exception_ExecutionFinished, e);
			}

			changeJobState(JobAttributes.State.TERMINATED);

			return new Status(IStatus.OK, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), NLS.bind(Messages.AbstractToolRuntimeSystemJob_Success, process.exitValue()));

		} finally {
			DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "RTS job #{0}: cleanup", jobID); //$NON-NLS-1$
			final IResourceManager rm = PTPCorePlugin.getDefault().getUniverse().getResourceManager(rtSystem.getRmID());
			if (rm != null) {
				final IPQueue queue = rm.getQueueById(getQueueID());
				if (queue != null) {
					final IPJob ipJob = queue.getJobById(getJobID());
					if (ipJob != null) {
						switch (ipJob.getState()) {
						case TERMINATED:
						case ERROR:
							break;
						case PENDING:
						case RUNNING:
						case STARTED:
						case SUSPENDED:
						case UNKNOWN:
							changeJobState(JobAttributes.State.TERMINATED);
							break;
						}
					}
				}
			}
			doExecutionCleanUp(monitor);
		}
	}

	abstract protected void doPrepareExecution(IProgressMonitor monitor) throws CoreException;

	abstract protected void doExecutionCleanUp(IProgressMonitor monitor);

	abstract protected void doWaitExecution(IProgressMonitor monitor) throws CoreException;

	abstract protected void doExecutionFinished(IProgressMonitor monitor) throws CoreException;

	abstract protected void doExecutionStarted(IProgressMonitor monitor) throws CoreException;

	abstract protected void doBeforeExecution(IProgressMonitor monitor) throws CoreException;

	abstract protected void doTerminateJob();

	/**
	 * Change the state of the job state.
	 * @param newState
	 */
	protected void changeJobState(JobAttributes.State newState) {
		EnumeratedAttribute<JobAttributes.State> state = JobAttributes.getStateAttributeDefinition().create(newState);
		AttributeManager attrManager = new AttributeManager();
		attrManager.addAttribute(state);
		rtSystem.changeJob(jobID, attrManager);
	}

	/**
	 * Retrieve the working directory for the launch.
	 * @param baseSubstitutionAttributeManager
	 * @return
	 */
	protected String retrieveWorkingDirectory(AttributeManager baseSubstitutionAttributeManager) {
		/*
		 * TODO Return IPath instead of string
		 */
		String workdir = attrMgr.getAttribute(JobAttributes.getWorkingDirectoryAttributeDefinition()).getValue();
		String newWorkdir = replaceVariables(workdir, baseSubstitutionAttributeManager);
		if (! workdir.equals(newWorkdir)) {
			DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "Changed work directory from {0} to {1}", workdir, newWorkdir); //$NON-NLS-1$
			workdir = newWorkdir;
		}
		return workdir;
	}

	/**
	 * Retrieve the environment variables.
	 * @param baseSubstitutionAttributeManager
	 */
	protected Map<String,String> retrieveEnvironment(AttributeManager baseSubstitutionAttributeManager) throws CoreException {
		HashMap<String, String> environmentMap = new HashMap<String, String>();

		/*
		 * First, get environment from the attribute manager.
		 */
		retrieveEnvironmentFromAttrMrg(environmentMap);

		/*
		 * Then, get extra environment variables that are specific for the tool.
		 */
		HashMap<String, String> extraEnvironmentMap = doRetrieveToolEnvironment();
		if (extraEnvironmentMap != null) {
			environmentMap.putAll(extraEnvironmentMap);
		}

		/*
		 * Do substitution on each environment variable.
		 */
		for (Iterator<Entry<String, String>> iterator = environmentMap.entrySet().iterator(); iterator.hasNext();) {
			Entry<String, String> env = iterator.next();
			String value = env.getValue();
			String newValue = replaceVariables(value, baseSubstitutionAttributeManager);
			if (! value.equals(newValue)) {
				DebugUtil.trace(DebugUtil.RTS_JOB_TRACING_MORE, "Changed environment '{0}={1}' to '{0}={2}", env.getKey(), value, newValue); //$NON-NLS-1$
				env.setValue(newValue);
			}
		}

		return environmentMap;
	}

	/**
	 * Retrieve additional environment variables that are specific for the tool.
	 */
	abstract protected HashMap<String, String> doRetrieveToolEnvironment() throws CoreException;

	private void retrieveEnvironmentFromAttrMrg(
			HashMap<String, String> environmentMap) {
		ArrayAttribute<String> environmentAttribute = getAttrMgr().getAttribute(JobAttributes.getEnvironmentAttributeDefinition());
		if (environmentAttribute != null) {
			List<String> environment = environmentAttribute.getValue();
			for (String entry : environment) {
				int i = entry.indexOf('=');
				String key = entry.substring(0, i);
				String value = entry.substring(i+1);
				environmentMap.put(key, value);
			}
		}
	}

	/**
	 * Retrieve attributes used to expand macros.
	 * @return
	 * @throws CoreException
	 */
	protected AttributeManager retrieveBaseSubstitutionAttributes() throws CoreException {
		AttributeManager newAttributeManager = new AttributeManager(getAttrMgr().getAttributes());

		/*
		 * First, add all default attributes that are default attributes for the launch.
		 * If they are not present in the launch attributes, then use default value.
		 */
		for (IAttributeDefinition<?, ?, ?> attributeDefinition : getDefaultSubstitutionAttributes()) {
			IAttribute<?, ?, ?> attribute = newAttributeManager.getAttribute(attributeDefinition.getId());
			if (attribute == null) {
				// Create one with default value.
				try {
					newAttributeManager.addAttribute(attributeDefinition.create());
				} catch (IllegalValueException e) {
					throw new CoreException(new Status(IStatus.ERROR, ToolsRMPlugin.getDefault().getBundle().getSymbolicName(), NLS.bind(Messages.AbstractToolRuntimeSystemJob_Exception_DefaultAttributeValue, attributeDefinition.getName()), e));
				}
			}
		}

		/*
		 * Then, add attributes that are specific for the tool.
		 */
		IAttribute<?,?,?> extraAttributes[] = doRetrieveToolBaseSubstitutionAttributes();
		if (extraAttributes != null) {
			newAttributeManager.addAttributes(extraAttributes);
		}

		return newAttributeManager;
	}

	/**
	 * Retrieve additional attributes to expand macros that are specific for the tool.
	 */
	abstract protected IAttribute<?, ?, ?>[] doRetrieveToolBaseSubstitutionAttributes() throws CoreException;

	/**
	 * A list of all attributes definitions from the launch configuration that can be used to expand macros.
	 * @return
	 */
	protected IAttributeDefinition<?, ?, ?>[] getDefaultSubstitutionAttributes() {
		return new IAttributeDefinition[]{
				JobAttributes.getEnvironmentAttributeDefinition(),
				JobAttributes.getExecutableNameAttributeDefinition(),
				JobAttributes.getExecutablePathAttributeDefinition(),
				JobAttributes.getJobIdAttributeDefinition(),
				JobAttributes.getNumberOfProcessesAttributeDefinition(),
				JobAttributes.getProgramArgumentsAttributeDefinition(),
				JobAttributes.getQueueIdAttributeDefinition(),
				JobAttributes.getSubIdAttributeDefinition(),
				JobAttributes.getUserIdAttributeDefinition(),
				JobAttributes.getWorkingDirectoryAttributeDefinition()
		};
	}

	final protected AttributeManager retrieveCommandSubstitutionAttributes(
			AttributeManager baseSubstitutionAttributeManager,
			String directory, Map<String, String> environment) {
		AttributeManager newAttributeManager = new AttributeManager(baseSubstitutionAttributeManager.getAttributes());

		/*
		 * Add attributes that are specific for the tool.
		 */
		IAttribute<?,?,?> extraAttributes[] = doRetrieveToolCommandSubstitutionAttributes(baseSubstitutionAttributeManager, directory, environment);
		if (extraAttributes != null) {
			newAttributeManager.addAttributes(extraAttributes);
		}

		return newAttributeManager;
	}


	abstract protected IAttribute<?, ?, ?>[] doRetrieveToolCommandSubstitutionAttributes(
			AttributeManager baseSubstitutionAttributeManager,
			String directory, Map<String, String> environment);

	protected List<String> retrieveCreateLaunchCommand(AttributeManager substitutionAttributeManager) throws CoreException {
		/*
		 * Create launch command. If there is no launch command, simply launch the executable.
		 */
		AbstractEffectiveToolRMConfiguration effectiveConfiguration = getRtSystem().retrieveEffectiveToolRmConfiguration();
		List<String> command = new ArrayList<String>();
		if (! effectiveConfiguration.hasLaunchCmd()) {
			// Fall back to calling the executable.
			StringAttribute execPath = getAttrMgr().getAttribute(JobAttributes.getExecutablePathAttributeDefinition());
			ArrayAttribute<String> arguments = getAttrMgr().getAttribute(JobAttributes.getProgramArgumentsAttributeDefinition());
			command.add(execPath.getValue());
			command.addAll(arguments.getValue());
		} else {
			// Use the tool to launch executable
			String launchCommand = effectiveConfiguration.getLaunchCmd();
			Assert.isNotNull(launchCommand);
			Assert.isTrue(launchCommand.trim().length() > 0);
			launchCommand = replaceVariables(launchCommand, substitutionAttributeManager);
			ArgumentParser argumentParser = new ArgumentParser(launchCommand);
			command = argumentParser.getTokenList();
		}
		return command;
	}

	protected List<String> retrieveCreateDebugCommand(AttributeManager substitutionAttributeManager) throws CoreException {
		/*
		 * Create debug command. If there is no debug command, simply launch the executable.
		 */
		AbstractEffectiveToolRMConfiguration effectiveConfiguration = getRtSystem().retrieveEffectiveToolRmConfiguration();
		List<String> command = new ArrayList<String>();
		if (! effectiveConfiguration.hasDebugCmd()) {
			// Fall back to calling the executable.
			StringAttribute execPath = getAttrMgr().getAttribute(JobAttributes.getExecutablePathAttributeDefinition());
			ArrayAttribute<String> arguments = getAttrMgr().getAttribute(JobAttributes.getProgramArgumentsAttributeDefinition());
			command.add(execPath.getValue());
			command.addAll(arguments.getValue());
		} else {
			// Use the tool to launch executable
			String debugCommand = effectiveConfiguration.getDebugCmd();
			Assert.isNotNull(debugCommand);
			Assert.isTrue(debugCommand.trim().length() > 0);
			debugCommand = replaceVariables(debugCommand, substitutionAttributeManager);
			ArgumentParser argumentParser = new ArgumentParser(debugCommand);
			command = argumentParser.getTokenList();
		}
		return command;
	}

	/*
	 * Pattern to fined variables according these rules:
	 * Starts with "${" and ends with "}"
	 * The content is a name and a set of parameters separated by ":"
	 * In the parameters, "\" may be used to quote following chars: '\', '}' and ':'
	 *
	 * TODO move this patter substitution code into the attribute manager
	 * TODO enable the attribute manager to do substitution -> have this feature available on entire PTP.
	 */
	static final Pattern variablePattern = Pattern.compile(("/$/{(/w+)("+"(?:(?:////)|(?:///})|[^/}])*"+")/}").replace('/','\\')); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	static final Pattern parameterPattern = Pattern.compile(":((?:(?:////)|(?:///:)|(?:///})|[^:])*)".replace('/', '\\')); //$NON-NLS-1$

	/**
	 * Performs substitution of variables using attributes from the attribute manager as variables.
	 * @param input the string with variables.
	 * @param substitutionAttributeManager
	 * @return The string after substitution of variables.
	 */
	protected String replaceVariables(String input, AttributeManager substitutionAttributeManager) {
		StringBuffer output = new StringBuffer();
		Matcher matcher = variablePattern.matcher(input);

		int lastPos = 0;
		while (matcher.find()) {
			int startPos = matcher.start();
			int endPos = matcher.end();
			String name = matcher.group(1);
			String parameterList = matcher.group(2);
			String variable = matcher.group();
			output.append(input.substring(lastPos, startPos));

			/*
			 * Resolve variable.
			 */
			String resolvedValue = null;
			IAttribute<?,?,?> attribute = substitutionAttributeManager.getAttribute(name);
			if (attribute != null) {
				if (attribute instanceof ArrayAttribute<?>) {
					/*
					 * Retrieve parameters or use defaults.
					 */
					String optStartStr = ""; //$NON-NLS-1$
					String optEndStr = ""; //$NON-NLS-1$
					String startStr = ""; //$NON-NLS-1$
					String endStr = ""; //$NON-NLS-1$
					String separatorStr = " "; //$NON-NLS-1$
					Matcher paramMatcher = parameterPattern.matcher(parameterList);
					if (paramMatcher.find()) {
						startStr = paramMatcher.group(1);
						if (paramMatcher.find()) {
							separatorStr = paramMatcher.group(1);
							if (paramMatcher.find()) {
								endStr = paramMatcher.group(1);
								if (paramMatcher.find()) {
									optStartStr = paramMatcher.group(1);
									if (paramMatcher.find()) {
										optEndStr = paramMatcher.group(1);
									}
								}
							}
						}
					}

					/*
					 * Build content.
					 */
					ArrayAttribute<?> array_attr = (ArrayAttribute<?>) attribute;
					StringBuffer buffer = new StringBuffer();
					boolean first = true;
					List<?> array = array_attr.getValue();
					if (array.size() > 0) {
						buffer.append(optStartStr);
					}
					buffer.append(startStr);
					for (Object element : array) {
						if (first) {
							first = false;
						} else {
							buffer.append(separatorStr);
						}
						assert element != null;
						buffer.append(element);
					}
					buffer.append(endStr);
					if (array.size() > 0) {
						buffer.append(optEndStr);
					}
					resolvedValue = buffer.toString();
				} else {
					resolvedValue = attribute.getValueAsString();
				}
			}

			/*
			 * If failed to resolve variable, keep it on the string. Else replace by its value.
			 */
			if (resolvedValue == null) {
				output.append(variable);
			} else {
				// Recursive macro substitution
				resolvedValue = replaceVariables(resolvedValue, substitutionAttributeManager);
				output.append(resolvedValue);
			}
			lastPos = endPos;
		}
		output.append(input.substring(lastPos));
		String result = output.toString();
		return result;
	}

	public void terminate() {
		terminateJobFlag = true;
		if (process != null) {
			process.destroy();
		}
		doTerminateJob();
	}

	@Override
	protected void canceling() {
		terminate();
		super.canceling();
	}
}
