diff --git a/src/InputOutput/IHMImpl/Params/IHMInputOutputParamsAbstractClass.php b/src/InputOutput/IHMImpl/Params/IHMInputOutputParamsAbstractClass.php
index 3bd515c..4b431f1 100644
--- a/src/InputOutput/IHMImpl/Params/IHMInputOutputParamsAbstractClass.php
+++ b/src/InputOutput/IHMImpl/Params/IHMInputOutputParamsAbstractClass.php
@@ -52,6 +52,14 @@ abstract class IHMInputOutputParamsAbstractClass implements InputOutputInterface
 	}
 
 	/*
+	 * @brief Get Task
+	 */
+	protected function getTask($input)
+	{
+		return $input->nodeType;
+	}
+
+	/*
 	 * @brief Unmarshall the time definition from the IHM request
 	*/
 	protected function unmarshallTimeDefinition($input, $requestIndex, $ttFileIndex = -1, $ttIntIndex = -1)
@@ -210,7 +218,7 @@ abstract class IHMInputOutputParamsAbstractClass implements InputOutputInterface
 		$this->paramsData->setCompilationPath(IHMConfigClass::getCompilationPath());
 		$this->paramsData->setLocalBasePath(IHMConfigClass::getLocalBasePath());
 		$this->paramsData->setManagerFilePath(IHMConfigClass::getProcessManagerFilePath());
-		$this->paramsData->setTask($input->nodeType);
+		$this->paramsData->setTask($this->getTask($input));
 		$this->input = $input;
 
 		return $this->unmarshallRequest($input);
diff --git a/src/InputOutput/IHMImpl/Tools/IHMJobsManagerClass.php b/src/InputOutput/IHMImpl/Tools/IHMJobsManagerClass.php
index c991d27..a948c57 100644
--- a/src/InputOutput/IHMImpl/Tools/IHMJobsManagerClass.php
+++ b/src/InputOutput/IHMImpl/Tools/IHMJobsManagerClass.php
@@ -5,8 +5,7 @@
  * @details
  */
 class IHMJobsManagerClass {
-
-	protected $jobXml, $jobXmlName;
+	protected $isWSJob = false;
 
 	protected $bkgRootNode = array('condition' => 'bkgSearch-treeRootNode',
 			'request' => 'bkgPlot-treeRootNode',
@@ -26,27 +25,149 @@ class IHMJobsManagerClass {
 	}
 
 	/*
-	 * @brief Load jobs file and create it if needed
-	*/
-	protected function init()
+	 * @brief Get path to the jobs file
+	 */
+	protected function getJobsFilePath()
+	{
+		return IHMConfigClass::getUserJobsFile();
+	}
+
+	/*
+	 * @bried Send an error notification
+	 */
+	protected function sendErrorNotification($message) {
+		// Nothing to do here
+		// It used to send an email with WS
+	}
+
+	/*
+         * @brief Decode a request object file
+         */
+	public function getRequestObjectFile($id)
+	{
+		if (!file_exists($this->getRequestObjectFilePath($id)))
+			return NULL;
+		return json_decode(file_get_contents($this->getRequestObjectFilePath($id)));
+	}
+
+        /*
+	 * @brief delete a job
+	 */
+	public function deleteJob($id)
+	{
+		return $this->concurrentAccessJobsFile(array($this,'deleteJobFromId'),$id);
+	}
+
+	/*
+	 * @brief get job info about a job
+	 */
+	public function getJobInfo($id)
+	{
+		return $this->concurrentAccessJobsFile(array($this,'getJobInfoById'),$id);
+	}
+
+	/*
+	 * @brief Add a new job
+	 */
+	public function addJob($obj, $id, $folder, $running, $start, $result, $exitcode, $exectime = 0)
+	{
+		return $this->concurrentAccessJobsFile(array($this,'addNewJob'), array(
+			'obj'      => $obj,
+			'id'       => $id,
+			'folder'   => $folder,
+			'running'  => $running,
+			'start'    => $start,
+			'result'   => $result,
+			'exitcode' => $exitcode,
+			'exectime' => $exectime,
+		));
+	}
+
+	/*
+	 * @brief Update the status of a job
+	 */
+	public function updateJobStatus($id, $running, $exitcode, $exectime = 0)
 	{
-		$this->jobXmlName = IHMConfigClass::getUserJobsFile();
-		$this->jobXml = new DomDocument("1.0");
+		return $this->concurrentAccessJobsFile(array($this,'updateJobStatusById'), array(
+			'id'       => $id,
+			'running'  => $running,
+			'exitcode' => $exitcode,
+			'exectime' => $exectime,
+		));
+	}
 
-		if (!file_exists($this->jobXmlName))
+	/*
+	 * @brief Get the list of jobs with a specific status
+	 */
+	public function getJobsByStatus($status)
+	{
+		return $this->concurrentAccessJobsFile(array($this,'getJobsByStatusInDom'), $status);
+	}
+
+	/*
+	 * @brief Get jobs that use a specific working dir
+	 */
+	public function getJobsByWorkingDir($folder)
+	{
+		return $this->concurrentAccessJobsFile(array($this,'getJobsByWorkingDirInDom'), $folder);
+	}
+
+	/*
+	 * @brief Get all jobs to clean (immediate result jobs)
+	 */
+	public function getJobsToClean()
+	{
+		return $this->concurrentAccessJobsFile(array($this,'getJobsToCleanInDom'), array());
+	}
+
+	/*
+	 *
+	 */
+	protected function concurrentAccessJobsFile($callback, $additionalParams)
+	{
+		$lockFile = $this->getJobsFilePath().".lockfile";
+
+		$fp = fopen($lockFile, "w+");
+
+		if ($fp === false) {
+			$this->sendErrorNotification('Cannot open jobs manager lock file');
+			return array('success' => false, 'message' => 'Cannot open jobs manager lock file');
+		}
+
+		$res = true;
+
+		if (flock($fp, LOCK_EX))
 		{
-			$res = $this->createJobsFile();
-			if (!$res['success'])
-				return $res;
+			if (!file_exists($this->getJobsFilePath())) {
+				$res = $this->createJobsFile();
+				if (!$res) {
+					$this->sendErrorNotification('Cannot create '.$this->getJobsFilePath());
+				}
+			}
+			if ($res)
+			{
+				$dom = new DOMDocument("1.0","UTF-8");
+				$dom->preserveWhiteSpace = false;
+				$dom->formatOutput = true;
+				$res = $dom->load($this->getJobsFilePath());
+				if ($res) {
+					$func_res = call_user_func($callback,$dom,$additionalParams);
+				}
+				else {
+					$this->sendErrorNotification('Cannot load '.$this->getJobsFilePath());
+				}
+			}
 		}
+		else
+			$res = FALSE;
 
-		$res = $this->jobXml->load($this->jobXmlName);
-		if (!$res)
-			return array(
-					"success" => false,
-					"message" => "Cannot load jobs file");
+		fclose($fp);
 
-		return array("success" => true);
+		if ($res)
+			return $func_res;
+
+		$this->sendErrorNotification('Error during the concurrent access of the jobs manager file');
+		return array('success' => false, 'message' => 'Error during the concurrent access of the jobs manager file');
 	}
 
 	/*
@@ -54,36 +175,33 @@ class IHMJobsManagerClass {
 	*/
 	protected function createJobsFile()
 	{
-		$rootElement = $this->jobXml->createElement('jobs');
-		$jobsInProgress = $this->jobXml->createElement('jobsInProgress');
+		$dom = new DOMDocument("1.0","UTF-8");
+		$dom->preserveWhiteSpace = false;
+		$dom->formatOutput = true;
+
+		$rootElement = $dom->createElement('jobs');
+		$jobsInProgress = $dom->createElement('jobsInProgress');
 
 		foreach ($this->bkgRootNode as $key => $value)
 		{
-			$element = $this->jobXml->createElement("$key");
+			$element = $dom->createElement("$key");
 			$element->setAttribute('xml:id',$value);
 			$jobsInProgress->appendChild($element);
 		}
-		$jobsFinished = $this->jobXml->createElement('jobsFinished');
+		$jobsFinished = $dom->createElement('jobsFinished');
 
 		foreach ($this->resRootNode as $key => $value)
 		{
-			$element = $this->jobXml->createElement("$key");
+			$element = $dom->createElement("$key");
 			$element->setAttribute('xml:id',"$value");
 			$jobsFinished->appendChild($element);
 		}
 
 		$rootElement->appendChild($jobsInProgress);
 		$rootElement->appendChild($jobsFinished);
-		$this->jobXml->appendChild($rootElement);
-
-		$res = $this->jobXml->save($this->jobXmlName);
+		$dom->appendChild($rootElement);
 
-		if (!$res)
-			return array(
-					"success" => false,
-					"message" => "Cannot create new jobs file");
-
-		return array("success" => true);
+		return $dom->save($this->getJobsFilePath());
 	}
 
 	/*
@@ -105,16 +223,6 @@ class IHMJobsManagerClass {
 	}
 
 	/*
-	 * @brief Decode a request object file
-	*/
-	public function getRequestObjectFile($id)
-	{
-		if (!file_exists($this->getRequestObjectFilePath($id)))
-			return NULL;
-		return json_decode(file_get_contents($this->getRequestObjectFilePath($id)));
-	}
-
-	/*
 	 * @brief Delete a request object file
 	*/
 	protected function deleteRequestObjectFile($id) {
@@ -137,15 +245,11 @@ class IHMJobsManagerClass {
 	}
 
 	/*
-	 * @brief delete a job
+	 * @brief delete a job from job id
 	*/
-	public function deleteJob($id)
+	protected function deleteJobFromId($dom, $id)
 	{
-		$res = $this->init();
-		if (!$res['success'])
-			return $res;
-
-		$job = $this->jobXml->getElementById($id);
+		$job = $dom->getElementById($id);
 
 		//delete job
 		if (!$job)
@@ -179,7 +283,7 @@ class IHMJobsManagerClass {
 		$this->deleteRequestObjectFile($id);
 
 		$job->parentNode->removeChild($job);
-		$res = $this->jobXml->save($this->jobXmlName);
+		$res = $dom->save($this->getJobsFilePath());
 
 		if (!$res)
 			return array(
@@ -192,45 +296,24 @@ class IHMJobsManagerClass {
 	/*
 	 * @brief get job info about a job
 	*/
-	public function getJobInfo($id)
+	protected function getJobInfoById($dom, $id)
 	{
-		$res = $this->init();
-		if (!$res['success'])
-			return $res;
-
-		$job = $this->jobXml->getElementById($id);
-
-		$attributes = [];
-		foreach( $job->attributes as $attrName => $attrNode) {
-			$attributes[$attrName] = $attrNode->nodeValue;
-		}
+		$job = $dom->getElementById($id);
 
 		$format = 'unknown';
 		$compression = 'unknown';
-		if($job)
+		if(!$job)
 		{
+			return array(
+				'success' => false,
+				'message' => "Cannot retrieve job ".$id,
+			);
+		}
+
+		if (!$this->isWSJob) {
+			// Not used for a WS job
 			$name = $job->getAttribute('name');
-			$status = $job->getAttribute('status');
-			$jobType = $job->getAttribute('jobType');
 			$info = $job->getAttribute('info');
-			$start = $job->getAttribute('start');
-			$stop = $job->getAttribute('stop');
-			$result = $job->getAttribute('result');
-			$folder = $job->getAttribute('folder');
-			$exectime = $job->getAttribute('exectime');
-			$request_obj = $this->getRequestObjectFile($id);
-			if (isset($request_obj))
-			{
-				if (isset($request_obj->format))
-				{
-					$format = strtolower($request_obj->format);
-					if (($format == "pdf") || ($format == "ps"))
-						//auto compression for plot request
-						$compression = ".tar.gz";
-				}
-				if (isset($request_obj->compression))
-					$compression = strtolower($request_obj->compression);
-			}
 			$sendToSamp = $job->getAttribute('sendToSamp');
 			if (empty($sendToSamp)) {
 				$sendToSamp = false;
@@ -239,37 +322,57 @@ class IHMJobsManagerClass {
 				$sendToSamp = ($sendToSamp == "true");
 			}
 		}
-		return array(
+		$exectime = $job->getAttribute('exectime');
+		$status = $job->getAttribute('status');
+		$jobType = $job->getAttribute('jobType');
+		$start = $job->getAttribute('start');
+		$stop = $job->getAttribute('stop');
+		$result = $job->getAttribute('result');
+		$folder = $job->getAttribute('folder');
+		$request_obj = $this->getRequestObjectFile($id);
+		if (isset($request_obj))
+		{
+			if (isset($request_obj->format))
+			{
+				$format = strtolower($request_obj->format);
+				if (($format == "pdf") || ($format == "ps"))
+					//auto compression for plot request
+					$compression = ".tar.gz";
+			}
+			if (isset($request_obj->compression))
+				$compression = strtolower($request_obj->compression);
+		}
+
+		$result = array(
 				'success'     => true,
 				'id'          => $id,
-				'name'        => $name,
 				'status'      => $status,
-				'exectime'    => $exectime,
 				'jobType'     => $jobType,
-				'info'        => $info,
 				'start'       => $start,
 				'stop'        => $stop,
 				'folder'      => $folder,
 				'result'      => $result,
 				'format'      => $format,
 				'compression' => $compression,
-				'sendToSamp'  => $sendToSamp,
+				'exectime'    => $exectime,
 		);
+
+		if (!$this->isWSJob) {
+			$result['name'] = $name;
+			$result['info'] = $info;
+			$result['sendToSamp'] = $sendToSamp;
+		}
+
+		return $result;
 	}
 
 	/*
-	 * @brief Add a new job
-	*/
-	public function addJob($obj, $id, $folder, $running, $start, $result, $exitcode, $exectime)
+         * @brief Getjob info from request object
+        */
+        protected function getRequestInfo($obj, $start)
 	{
-		$obj = get_object_vars($obj); // Allow access to elements where the key is in dash-separated form.
-		$res = $this->init();
-		if (!$res['success'])
-			return $res;
-
 		$infos = [];
 		switch ($obj['nodeType']) {
-			// Data mining
 			case 'condition':
 				$name = 'datamining_'.time();
 				if($obj['name'] != '') {
@@ -279,7 +382,6 @@ class IHMJobsManagerClass {
 				$infos['Start date'] = $obj['startDate'];
 				$infos['Stop date'] = $obj['stopDate'];
 				break;
-
 			case 'statistics':
 				$name = 'statistics_'.time();
 				$infos['Name'] =  $obj['name']; // TODO: name toujours égal à 'test' (?)
@@ -325,7 +427,6 @@ class IHMJobsManagerClass {
 					$infos['Parameters'] = '<ul><li>' . join('</li><li>', $params) . '</li></ul>';
 				}
 				break;
-
 			case 'download':
 				$name = $obj['downloadSrc'] == '2' ? "download_fits_".time() : "download_data_".time();
 				$params = [];
@@ -340,35 +441,25 @@ class IHMJobsManagerClass {
 				$infos['Start date'] = $obj['startDate'];
 				$infos['Stop date'] = $obj['stopDate'];
 				break;
-
-			// Plot
 			case 'request':
 				$name = "request_".time();
 
 				$infos['Output'] = strtolower($obj['file-format']) . ' (' . strtolower($obj['file-output']) . ')';
-				foreach ($obj['tabs'] as $tab) {
-					if($tab->id == $obj['last-plotted-tab']) {
-						$infos['Start date'] = $tab->startDate;
-						$infos['Stop date'] = $tab->stopDate;
-
-						$strPanels = [];
-
-						foreach ($tab->panels as $panel) {
-							$strParams = '';
-							foreach ($panel->params as $param) {
-								$strParams .= $param->paramid . ($param === end($panel->params) ? '' : ', ');
-							}
-							$infos['• Panel ' . $panel->id] = $strParams;
-						}
+				$infos['Start date'] = $obj->startDate;
+				$infos['Stop date'] = $obj->stopDate;
 
-						continue;
+				foreach ($obj->panels as $panel) {
+					$strParams = '';
+					foreach ($panel->params as $param) {
+						$strParams .= $param->paramid . ($param === end($panel->params) ? '' : ', ');
 					}
+					$infos['• Panel ' . $panel->id] = $strParams;
 				}
 				break;
-
 			default:
 				$name = "unknown_".time();
 		}
+
 		$infos['Started at'] = gmdate("Y-m-d H:i:s", $start);
 
 		$strInfo = '';
@@ -376,84 +467,104 @@ class IHMJobsManagerClass {
 			$strInfo .= ($key == 'Started at' ? '<hr/>' : '') . '<b>' . $key . '</b>: ' . $info . '<br/>';
 		}
 
-		$newJob = $this->jobXml->createElement('job');
-		$newJob->setAttribute('xml:id', $id);
-		$newJob->setAttribute('jobType', $obj['nodeType']);
-		$newJob->setAttribute('name', $name);
-		$newJob->setAttribute('info', $strInfo);
-		$newJob->setAttribute('folder', $folder);
-		$newJob->setAttribute('result', $result);
-		$newJob->setAttribute('start', date('d-m-Y H:i:s', $start));
-		$newJob->setAttribute('exectime', $exectime);
-		//to know if know if it's an immediate job or not
-		$newJob->setAttribute('immediate', !$running);
+		return array($name, $strInfo);
+	}
+
+	/*
+	 * @brief Get job key
+	 */
+	protected function getJobKey($obj)
+	{
+		return $obj['nodeType'];
+	}
 
-		$sendToSamp = isset($obj['sendToSamp']) ? $obj['sendToSamp'] : FALSE;
-		if ($sendToSamp) {
-			 $newJob->setAttribute('sendToSamp', "true");
+	/*
+	 * @brief Add a new job
+	*/
+	protected function addNewJob($dom, $args)
+	{
+		$obj = get_object_vars($args['obj']); // Allow access to elements where the key is in dash-separated form.
+		$key = $this->getJobKey($obj);
+
+
+		$newJob = $dom->createElement('job');
+		$newJob->setAttribute('xml:id', $args['id']);
+		$newJob->setAttribute('jobType', $key);
+		$newJob->setAttribute('folder', $args['folder']);
+		$newJob->setAttribute('result', $args['result']);
+		$newJob->setAttribute('start', date('d-m-Y H:i:s', $args['start']));
+		//to know if know if it's an immediate job or not
+		$newJob->setAttribute('immediate', !$args['running']);
+		$newJob->setAttribute('exectime', $args['exectime']);
+		if (!$this->isWSJob) {
+			list($name, $strInfo) = $this->getRequestInfo($obj, $args['name']);
+			$newJob->setAttribute('name', $name);
+			$newJob->setAttribute('info', $strInfo);
+			$sendToSamp = isset($obj['sendToSamp']) ? $obj['sendToSamp'] : FALSE;
+			if ($sendToSamp) {
+				$newJob->setAttribute('sendToSamp', "true");
+			}
+		}
+		else {
+			$newJob->setAttribute('user', IHMConfigClass::getUserName());
+			$newJob->setAttribute('host', IHMConfigClass::getUserHost());
 		}
 
-		$key = $obj['nodeType'];
-		if ($running)
+
+		if ($args['running'])
 		{
-			$rootJobNode = $this->jobXml->getElementById($this->bkgRootNode[$key]);
+			$rootJobNode = $dom->getElementById($this->bkgRootNode[$key]);
 			if (!$rootJobNode)
 			{
-				$rootJobNode =  $this->jobXml->createElement("$key");
+				$rootJobNode =  $dom->createElement("$key");
 				$rootJobNode->setAttribute('xml:id', $this->bkgRootNode[$key]);
-				$jobsInProgress = $this->jobXml->getElementsByTagName('jobsInProgress')->item(0);
+				$jobsInProgress = $dom->getElementsByTagName('jobsInProgress')->item(0);
 				$jobsInProgress->appendChild($rootJobNode);
 			}
 		}
 		else
 		{
-			$rootJobNode = $this->jobXml->getElementById($this->resRootNode[$key]);
+			$rootJobNode = $dom->getElementById($this->resRootNode[$key]);
 			if (!$rootJobNode)
 			{
-				$rootJobNode =  $this->jobXml->createElement("$key");
+				$rootJobNode =  $dom->createElement("$key");
 				$rootJobNode->setAttribute('xml:id', $this->resRootNode[$key]);
-				$jobsFinished = $this->jobXml->getElementsByTagName('jobsFinished')->item(0);
+				$jobsFinished = $dom->getElementsByTagName('jobsFinished')->item(0);
 				$jobsFinished->appendChild($rootJobNode);
 			}
 		}
 
 		$rootJobNode->appendChild($newJob);
 		 
-		if (!$this->jobXml->save($this->jobXmlName))
+		if (!$dom->save($this->getJobsFilePath()))
 			return  array("success" => false, "message" => "Cannot save job manager file");
 
-		$this->saveRequestObjectFile($obj, $id);
+		$this->saveRequestObjectFile($obj, $args['id']);
 
-		$this->updateJobStatus($id, $running, $exitcode, $exectime);
+		$this->updateJobStatusById($dom, $args);
 
-		return  $this->getJobInfo($id);
+		return  $this->getJobInfoById($dom, $args['id']);
 	}
 
 	/*
-	 * @brief Update the status of a job
+	 * @brief Update the status of a job by id
 	*/
-	public function updateJobStatus($id, $running, $exitcode, $exectime = 0)
+	protected function updateJobStatusById($dom, $args)
 	{
-		$res = $this->init();
-		if (!$res['success'])
-			return $res;
-			
-		$this->lockService();
-		
-		$job = $this->jobXml->getElementById($id);
+		$job = $dom->getElementById($args['id']);
 
 		if (!isset($job)) {
 			return array("success" => false, "message" => "Cannot found job");
 		}
 
-		$jobstatus = $this->getJobStatus($running,$exitcode);
+		$jobstatus = $this->getJobStatus($args['running'], $args['exitcode']);
 		$job->setAttribute('status', $jobstatus);
 
-		$job->setAttribute('exectime', $exectime);
+		$job->setAttribute('exectime', $args['exectime']);
 
 		$infos = [];
 
-		if ($running) {
+		if ($args['running']) {
 			$job->setAttribute('stop', 'unknown');
 		} else if ($job->getAttribute('stop') == '' || $job->getAttribute('stop') == 'unknown') {
 			$job->setAttribute('stop', date('d-m-Y H:i:s', time()));
@@ -462,31 +573,33 @@ class IHMJobsManagerClass {
 			$interval = (new DateTime('now'))->diff($start);
 			$infos['Job duration'] = $interval->format('%Hh %Im %Ss');
 
-			$resPath = glob(USERWORKINGDIR . $job->getAttribute('folder') . '/' . $job->getAttribute('result') . '*')[0];
+			if (!$this->isWSJob) {
+				$resPath = glob(USERWORKINGDIR . $job->getAttribute('folder') . '/' . $job->getAttribute('result') . '*')[0];
 
-			if($job->getAttribute('jobType') == 'condition') {
-				$resXml = new DomDocument();
-				$resXml->load($resPath);
-				$infos['nb intervals'] = $resXml->getElementsByTagName('nbIntervals')->item(0)->nodeValue;
-			}
+				if($job->getAttribute('jobType') == 'condition') {
+					$resXml = new DomDocument();
+					$resXml->load($resPath);
+					$infos['nb intervals'] = $resXml->getElementsByTagName('nbIntervals')->item(0)->nodeValue;
+				}
 
-			$fileSize = filesize($resPath);
-			if ($fileSize < 1024) {
-				$strSize = number_format($fileSize, 2, '.', ' ') . 'b';
-			} else if($fileSize < 1024*1024) {
-				$strSize = number_format($fileSize/1024, 2, '.', ' ') . 'kb';
-			} else if($fileSize < 1024*1024*1024) {
-				$strSize = number_format($fileSize/(1024*1024), 2, '.', ' ') . 'mb';
-			} else {
-				$strSize = number_format($fileSize/(1024*1024*1024), 2, '.', ' ') . 'gb';
+				$fileSize = filesize($resPath);
+				if ($fileSize < 1024) {
+					$strSize = number_format($fileSize, 2, '.', ' ') . 'b';
+				} else if($fileSize < 1024*1024) {
+					$strSize = number_format($fileSize/1024, 2, '.', ' ') . 'kb';
+				} else if($fileSize < 1024*1024*1024) {
+					$strSize = number_format($fileSize/(1024*1024), 2, '.', ' ') . 'mb';
+				} else {
+					$strSize = number_format($fileSize/(1024*1024*1024), 2, '.', ' ') . 'gb';
+				}
+				$infos['File size'] = $strSize;
 			}
-			$infos['File size'] = $strSize;
 
-			$this->jobXml->getElementById($this->resRootNode[$job->getAttribute('jobType')])->appendChild($job);
+			$dom->getElementById($this->resRootNode[$job->getAttribute('jobType')])->appendChild($job);
 		}
 
-		if($exitcode != 0) {
-			$infos['Error code'] = $exitcode;
+		if($args['exitcode'] != 0) {
+			$infos['Error code'] = $args['exitcode'];
 		}
 
 		$strInfo = $job->getAttribute('info');
@@ -495,30 +608,22 @@ class IHMJobsManagerClass {
 		}
 		$job->setAttribute('info', $strInfo);
 
-		$res = $this->jobXml->save($this->jobXmlName);
-		
-		$this->unlockService();
+		$res = $dom->save($this->getJobsFilePath());
 		
 		if (!$res)
 			return array(
 					'success' => false,
 					'message' => "Cannot save jobs status file");
 			
-		return $this->getJobInfo($id);
+		return $this->getJobInfoById($dom, $args['id']);
 	}
 	
-	public function lockService(){}
-	public function unlockService(){}
 	/*
-	 * @brief Get the list of jobs with a specific status
+	 * @brief Get the list of jobs with a specific status in a $dom
 	*/
-	public function getJobsByStatus($status)
+	protected function getJobsByStatusInDom($dom, $status)
 	{
-		$res = $this->init();
-		if (!$res['success'])
-			return $res;
-			
-		$xp = new domxpath($this->jobXml);
+		$xp = new domxpath($dom);
 		$jobs = $xp->query("//job[@status='".$status."']");
 
 		$jobsId = array();
@@ -529,15 +634,11 @@ class IHMJobsManagerClass {
 	}
 	
 	/*
-	 * @brief Get jobs that use a specific working dir
+	 * @brief Get jobs that use a specific working dir in a $dom
 	*/
-	public function getJobsByWorkingDir($folder)
+	protected function getJobsByWorkingDirInDom($dom, $folder)
 	{
-		$res = $this->init();
-		if (!$res['success'])
-			return $res;
-			
-		$xp = new domxpath($this->jobXml);
+		$xp = new domxpath($dom);
 		$jobs = $xp->query("//job[@folder='".$folder."']");
 	
 		$jobsId = array();
@@ -548,16 +649,12 @@ class IHMJobsManagerClass {
 	}
 
 	/*
-	 * @brief Get all jobs to clean (immediate result jobs)
+	 * @brief Get all jobs to clean (immediate result jobs) in a $dom
 	*/
-	public function getJobsToClean()
+	protected function getJobsToCleanInDom($dom)
 	{
-		$res = $this->init();
-		if (!$res['success'])
-			return $res;
-
 		// Get immediate jobs
-		$xp = new domxpath($this->jobXml);
+		$xp = new domxpath($dom);
 		$jobs = $xp->query("//job[@immediate='1']");
 
 		$jobsId = array();
diff --git a/src/InputOutput/WSImpl/Config/WSConfigClass.php b/src/InputOutput/WSImpl/Config/WSConfigClass.php
index d00e878..a366fc4 100644
--- a/src/InputOutput/WSImpl/Config/WSConfigClass.php
+++ b/src/InputOutput/WSImpl/Config/WSConfigClass.php
@@ -45,22 +45,6 @@ class WSConfigClass
 			return IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$jobsFile;
 	}
 	
-	public static function lockServices()
-	{
-			touch(IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$LockFile);	
-	}
-	
-	public static function isLockedServices()
-	{
-			return file_exists(IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$LockFile);	
-	}
-	
-	public static function unlockServices()
-	{
-			if (file_exists(IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$LockFile))
-					unlink(IHMConfigClass::getDataDir().self::$wsResultDir.'/'.self::$LockFile);
-	}
-	
 	public static function getDataSetInfoDir()
 	{
 			return IHMConfigClass::getGenericDataPath().self::$dataSetInfoDir.'/';
diff --git a/src/InputOutput/WSImpl/Params/DownloadImpl/WSInputOutputParamsDownloadClass.php b/src/InputOutput/WSImpl/Params/DownloadImpl/WSInputOutputParamsDownloadClass.php
index aac3351..613675e 100644
--- a/src/InputOutput/WSImpl/Params/DownloadImpl/WSInputOutputParamsDownloadClass.php
+++ b/src/InputOutput/WSImpl/Params/DownloadImpl/WSInputOutputParamsDownloadClass.php
@@ -15,6 +15,15 @@ class WSInputOutputParamsDownloadClass extends IHMInputOutputParamsAbstractClass
 		$this->paramManager     = new IHMParamManagerClass();
 		$this->jobsManager      = new WSJobsManagerClass();
 	}
+
+	/*
+         * @brief Get Task
+         */
+	protected function getTask($input)
+	{
+		return WSInputOutputClass::getService();
+	}
+
 	/*
 	 * @brief method to unmarshall a download request
 	*/
@@ -71,7 +80,7 @@ class WSInputOutputParamsDownloadClass extends IHMInputOutputParamsAbstractClass
 		
 		foreach ($input->list as $param)
 		{
-			$paramInfo = $this->paramManager->addExistingParam($param->paramid, $this->paramsData, $param->template_args);
+			$paramInfo = $this->paramManager->addExistingParam($param->paramid, $this->paramsData/*, $param->template_args*/);
 		//	$this->paramManager->applyRangesAndIndexes($this->paramsData, $param, FALSE, $paramInfo);
 
 			$downloadNode->addParam($paramInfo['id'],$paramInfo['indexes'],$paramInfo['calib_infos']);
@@ -137,7 +146,7 @@ class WSInputOutputParamsDownloadClass extends IHMInputOutputParamsAbstractClass
 	/*
 	 * @brief Unmarshall the time definition from the WS request
 	*/
-	protected function unmarshallTimeDefinition($input, $requestIndex)
+	protected function unmarshallTimeDefinition($input, $requestIndex, $ttFileIndex = -1, $ttIntIndex = -1)
 	{
 		$requestNodes = $this->paramsData->getRequestNodes();
 		$timesNode = $requestNodes[$requestIndex]->getTimesNode();
@@ -156,15 +165,18 @@ class WSInputOutputParamsDownloadClass extends IHMInputOutputParamsAbstractClass
 	protected function addToJobsFile($data,$resultKey)
 	{
 		$waitingResult = $data->getWaitingResult($resultKey);
-		
-		return $this->jobsManager->addJob(
+
+		$result = $this->jobsManager->addJob(
 				$this->input,
 				$data->getId(),
 				$this->getWorkingDirName(),
 				$data->getStatus() == ProcessStatusEnumClass::RUNNING,
 				$data->getStart(),
 				$waitingResult,
-				$data->getErrorCode()); 
+				$data->getErrorCode(),
+				$data->getExecTime());
+
+		return $result;
 	}
 	
 	protected function getDatasetIdFromParamInfo($paramId)
diff --git a/src/InputOutput/WSImpl/Params/PlotImpl/WSInputOutputParamsPlotClass.php b/src/InputOutput/WSImpl/Params/PlotImpl/WSInputOutputParamsPlotClass.php
index 0b826fb..0a64798 100644
--- a/src/InputOutput/WSImpl/Params/PlotImpl/WSInputOutputParamsPlotClass.php
+++ b/src/InputOutput/WSImpl/Params/PlotImpl/WSInputOutputParamsPlotClass.php
@@ -14,6 +14,14 @@ class WSInputOutputParamsPlotClass extends IHMInputOutputParamsAbstractClass
 		$this->paramManager     = new IHMParamManagerClass();
 		$this->jobsManager      = new WSJobsManagerClass();
 	}	
+
+	/*
+	 * @brief Get Task
+	 */
+	protected function getTask($input)
+	{
+		return WSInputOutputClass::getService();
+	}
 	
 	/*
 	 * @brief method to unmarshall a plot request
@@ -170,7 +178,8 @@ class WSInputOutputParamsPlotClass extends IHMInputOutputParamsAbstractClass
 				$data->getStatus() == ProcessStatusEnumClass::RUNNING,
 				$data->getStart(),
 				$waitingResult,
-				$data->getErrorCode()); 
+				$data->getErrorCode(),
+				$data->getExecTime()); 
 	}
 	
 	/*
diff --git a/src/InputOutput/WSImpl/Tools/WSJobsManagerClass.php b/src/InputOutput/WSImpl/Tools/WSJobsManagerClass.php
index eb7897d..c872d75 100644
--- a/src/InputOutput/WSImpl/Tools/WSJobsManagerClass.php
+++ b/src/InputOutput/WSImpl/Tools/WSJobsManagerClass.php
@@ -23,211 +23,25 @@ class WSJobsManagerClass extends IHMJobsManagerClass {
 	*/
 	function __construct()
 	{
+		$this->isWSJob = TRUE;
 	}
 
-	/*
-	 * @brief Load jobs file and create it if needed
-	*/
-	protected function init()
-	{
-		$this->jobXmlName = WSConfigClass::getWsJobsFile();
-		$this->jobXml = new DomDocument("1.0");
-
-		if (!file_exists($this->jobXmlName))
-		{
-			$res = $this->createJobsFile();
-			if (!$res['success']) {
-				error_log("WebServices Error : Cannot create WSjobs.xml", 1, email);
-				return $res;
-			}
-		}
-
-		while (WSConfigClass::isLockedServices())
-			 sleep(1);
-
-		$res = $this->jobXml->load($this->jobXmlName);
-		if (!$res) {
-			error_log("WebServices Error : Cannot load WSjobs.xml", 1, email);
-			return array(
-					"success" => false,
-					"message" => "Cannot load jobs file");
-			}
-			 
-		return array("success" => true);
-	}
- 
-	/*
-	 * @brief get job info about a job
-	*/
-	public function getJobInfo($id)
-	{
-		$res = $this->init();
-		if (!$res['success'])
-			return $res;
-
-		$job = $this->jobXml->getElementById($id);
-		$format = 'unknown';
-		$compression = 'unknown';
-		if($job)
-		{
-		//	$name = $job->getAttribute('name');
-			$status = $job->getAttribute('status');
-			$jobType = $job->getAttribute('jobType');
-		//	$info = $job->getAttribute('info');
-			$start = $job->getAttribute('start');
-			$stop = $job->getAttribute('stop');
-			$result = $job->getAttribute('result');
-			$folder = $job->getAttribute('folder');
-			$request_obj = $this->getRequestObjectFile($id);
-			if (isset($request_obj))
-			{
-				if (isset($request_obj->fileformat))
-				{
-					$format = strtolower($request_obj->format);
-					if (($format == "pdf") || ($format == "ps"))
-						//auto compression for plot request
-						$compression = ".tar.gz";
-						
-					// if ($format == "ascii") $format = 'txt';
-				}
-				if (isset($request_obj->compression))
-					$compression = strtolower($request_obj->compression);
-			}
-		}
-		return array(
-				'success'     => true,
-				'id'          => $id,
-			//	'name'        => $name,
-				'status'      => $status,
-				'jobType'     => $jobType,
-			//	'info'        => $info,
-				'start'       => $start,
-				'stop'        => $stop,
-				'folder'      => $folder,
-				'result'      => $result,
-				'format'      => $format,
-				'compression' => $compression
-		);
-	}
-	
-	public function lockService(){
-		if (!WSConfigClass::isLockedServices())
-				WSConfigClass::lockServices();
-	}
-	
-	public function unlockService(){ 
-		if (WSConfigClass::isLockedServices())
-			WSConfigClass::unlockServices();
-	}
-	/*
-	 * @brief Add a new job
-	*/
-	public function addJob($obj, $id, $folder,
-			$running, $start, $result, $exitcode)
-	{
-		$res = $this->init();
-
-		if (!$res['success'])
-			return $res;
-
-		$this->lockService();
-					 	
-		$key = WSInputOutputClass::getService();
-		
-		$newJob = $this->jobXml->createElement('job');
-
-		$newJob->setAttribute('xml:id', $id);
- 		$newJob->setAttribute('jobType', $key);
-
-		$newJob->setAttribute('result', $result);
-		$newJob->setAttribute('folder', $folder);
-		$newJob->setAttribute('start', date('d-m-Y H:i:s', $start));
-		$newJob->setAttribute('user', IHMConfigClass::getUserName());
-		$newJob->setAttribute('host', IHMConfigClass::getUserHost());
+	protected function getJobsFilePath()
+        {
+                return WSConfigClass::getWsJobsFile();
+        }
 
-		if ($running)
-		{
-			$rootJobNode = $this->jobXml->getElementById($this->bkgRootNode[$key]);
-			if (!$rootJobNode)
-			{
-				$rootJobNode =  $this->jobXml->createElement("$key");
-				$rootJobNode->setAttribute('xml:id', $this->bkgRootNode[$key]);
-				$jobsInProgress = $this->jobXml->getElementsByTagName('jobsInProgress')->item(0);
-				$jobsInProgress->appendChild($rootJobNode);
-			}
-		}
-		else
-		{
-			$rootJobNode = $this->jobXml->getElementById($this->resRootNode[$key]);
-			if (!$rootJobNode)
-			{
-				$rootJobNode =  $this->jobXml->createElement("$key");
-				$rootJobNode->setAttribute('xml:id', $this->resRootNode[$key]);
-				$jobsFinished = $this->jobXml->getElementsByTagName('jobsFinished')->item(0);
-				$jobsFinished->appendChild($rootJobNode);
-			}
-		}
-
-		$rootJobNode->appendChild($newJob);
-		
-		if (!$this->jobXml->save($this->jobXmlName)) {
-			$this->unlockService();
-			return  array("success" => false, "message" => "Cannot save job manager file");
-		}
-		$this->unlockService();
-		$this->saveRequestObjectFile($obj, $id);
-		
-		$res = $this->updateJobStatus($id, $running, $exitcode);
-
-		return  $res;
-		
+	protected function sendErrorNotification($message) {
+		error_log("WebServices Error : ".$message);
+		error_log("WebServices Error : ".$message, email);
 	}
 
-	
 	/*
-	 * @brief delete a job
-	*/
-	public function deleteJob($id)
+	 * @brief Get job key
+	 */
+	protected function getJobKey($obj)
 	{
-		$res = $this->init();
-		if (!$res['success'])
-			return $res;
-
-		$job = $this->jobXml->getElementById($id);
-
-		//delete job
-		if (!$job)
-			return array('success' => false, 'message' => "Job not reachable");
-
-		$folder = $job->getAttribute('folder');
-
-		//be sure that it's an AMDA working dir before deletion...
-		$fullFolderPath = IHMConfigClass::getRequestPath().$folder.'/';
- 
-		if ((isset($folder)) &&
-		($folder != "") &&
-		is_dir($fullFolderPath) &&
-		(preg_match("/DD[0-9A-Za-z]*_/",$folder) ||
-		 preg_match("/Plot[0-9]*_/",$folder)))
-		{
-			foreach (glob($fullFolderPath.'*') as $filename)
-			{
-				if (is_dir($filename) && (basename($filename) == 'params'))
-				{
-					//recursive deletion only for "params" dir (a full recursive deletion is probably too dangerous...)
-					foreach (glob($filename.'/*') as $paramname)
-						unlink($paramname);
-					rmdir($filename);
-				}
-				else
-					unlink($filename);
-			}
-			rmdir($fullFolderPath);
-		}
-
-		$this->deleteRequestObjectFile($id);
-			
-		return array('success' => true, 'id' => $id);
+		return WSInputOutputClass::getService();
 	}
 	
 	public function getResultFromProcessId($id)
diff --git a/src/Request/ProcessRequestImpl/ProcessRequestClass.php b/src/Request/ProcessRequestImpl/ProcessRequestClass.php
index 56f5976..79c1f51 100644
--- a/src/Request/ProcessRequestImpl/ProcessRequestClass.php
+++ b/src/Request/ProcessRequestImpl/ProcessRequestClass.php
@@ -96,7 +96,7 @@ class ProcessRequestClass extends RequestAbstractClass
 				$this->requestData->setErrorMsg($processInfo['errormsg']);
 			} 
 			$this->requestData->setExecTime($processInfo['exectime']);
-			$processMgr->deleteProcess($processInfo['id'], $result['success']);
+			$processMgr->deleteProcess($processInfo['id']);
 		}
 
 		$this->requestData->setStart($processInfo['runningstart']);
--
libgit2 0.21.2