Index: trunk/zoo-project/zoo-kernel/Makefile.in
===================================================================
--- trunk/zoo-project/zoo-kernel/Makefile.in	(revision 961)
+++ trunk/zoo-project/zoo-kernel/Makefile.in	(revision 962)
@@ -45,5 +45,5 @@
 
 service_callback.o: service_callback.c
-	g++ -fPIC ${XML2CFLAGS} ${GDAL_CFLAGS} ${JSON_CFLAGS} ${CFLAGS} -c service_callback.c
+	gcc -fPIC ${XML2CFLAGS} ${GDAL_CFLAGS} ${JSON_CFLAGS} ${CFLAGS} -c service_callback.c
 
 request_parser.o: request_parser.c request_parser.h
Index: trunk/zoo-project/zoo-kernel/configure.ac
===================================================================
--- trunk/zoo-project/zoo-kernel/configure.ac	(revision 961)
+++ trunk/zoo-project/zoo-kernel/configure.ac	(revision 962)
@@ -85,9 +85,9 @@
 		[], [AC_MSG_ERROR([could not find function in json-c library])])
 	CPPFLAGS="$CPPFLAGS_SAVE"
-	JSON_FILE="service_json.o"
+	JSON_FILE="service_json.o service_callback.o"
 	JSON_ENABLED="-DJSON"
 	if test "x$CALLBACK_ACTIVATED" == "xyes"
 	then
-		CALLBACK_FILE="service_callback.o"
+		CALLBACK_FILE=""
 		CALLBACK_USE="-DUSE_CALLBACK"
 	fi
Index: trunk/zoo-project/zoo-kernel/oas.cfg
===================================================================
--- trunk/zoo-project/zoo-kernel/oas.cfg	(revision 961)
+++ trunk/zoo-project/zoo-kernel/oas.cfg	(revision 962)
@@ -1,23 +1,15 @@
 [openapi]
-rootUrl=https://demo.mapmint.com/wps3/
+use_content=false
+rootUrl=https://myserver/ogc-api
 links=/,/api,/conformance,/processes
-paths=/root,/api,/conformance,/processes,/processes/{id},/processes/{id}/jobs,/processes/{id}/jobs/{jobID},/processes/{id}/jobs/{jobID}/result
+paths=/root,/api,/conformance,/processes,/processes/{id},/processes/{id}/jobs,/processes/{id}/jobs/{jobID},/processes/{id}/jobs/{jobID}/results
 parameters=id,jobID,resultID
-header_parameters=oas-header1,oas-header2
-version=3.0.1
-
-[oas-header1]
-in=header
-name=Prefer
-type=string
-required=false
-enum=respond-async
-
-[oas-header2]
-in=header
-name=Prefer
-type=string
-required=false
-enum=return=representation,return=minimal
+version=3.0.2
+license_name=OGC license
+license_url=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/LICENSE
+full_html_support=false
+partial_html_support=true
+wsUrl=wss://demo.mapmint.com:4430/
+publisherUrl=http://127.0.0.1/cgi-bin3/publish.py?jobid=
 
 [/]
@@ -32,10 +24,21 @@
 tags=Home
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/root.yaml
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/LandingPage.yaml
+
+[/index.html]
+rel=alternate
+type=text/html
 
 [/api]
-rel=service
+rel=service-desc
 type=application/openapi+json;version=3.0
 title=the API definition
+
+[/api.html]
+rel=service-doc
+type=text/hml
+
+[api.html]
+href=https://demo.mapmint.com/swagger-ui/ogc-api-processes/
 
 [api]
@@ -55,8 +58,12 @@
 method=get
 title=information about standards that this API conforms to
-abstract==list all requirements classes specified in a standard (e.g., WPS REST/JSON Binding Core) that the server conforms to
+abstract=list all requirements classes specified in a standard (e.g., WPS REST/JSON Binding Core) that the server conforms to
 tags=Conformance
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/req-classes.yaml
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/ConformanceDeclaration.yaml
+
+[/conformance.html]
+rel=alternate
+type=text/hml
 
 [/processes]
@@ -71,5 +78,9 @@
 tags=GetCapabilities
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/processCollection.yaml
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/ProcessList.yaml
+
+[/processes.html]
+rel=alternate
+type=text/hml
 
 [processes/{id}]
@@ -79,5 +90,6 @@
 tags=ProcessDescription
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/process.yaml
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/ProcessDescription.yaml
+ecode=404
 parameters=/components/parameters/id
 
@@ -95,6 +107,7 @@
 tags=JobList
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/jobCollection.yaml
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/JobList.yaml
 parameters=/components/parameters/id
+ecode=404,500
 method_1=post
 title_1=execute a job
@@ -102,6 +115,9 @@
 tags_1=Execute Endpoint
 tags_description_1=
-schema_1=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/result.yaml
-parameters_1=/components/parameters/id,/components/parameters/oas-header1
+schema_1=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/ExecuteSync.yaml
+parameters_1=/components/parameters/id
+ecode_1=400,404,500
+eschema_1=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/ExecuteAsync.yaml
+ep=,/components/parameters/oas-header1
 
 [requestBody]
@@ -116,4 +132,5 @@
 
 [processes/{id}/jobs/{jobID}]
+length=2
 method=get
 title=The status of a job.
@@ -121,13 +138,22 @@
 tags=GetStatus
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/statusInfo.yaml
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/Status.yaml
 parameters=/components/parameters/id,/components/parameters/jobID
-
-[/processes/{id}/jobs/{jobID}/result]
+method_1=delete
+title_1=Cancel a job
+abstract_1=Cancel the job execution.
+tags_1=Dismiss
+tags_description_1=Cencel a job execution
+schema_1=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/Status.yaml
+parameters_1=/components/parameters/id,/components/parameters/jobID
+ecode_1=404,500
+
+
+[/processes/{id}/jobs/{jobID}/results]
 rel=canonical
 type=application/json
 title=Get Result
 
-[processes/{id}/jobs/{jobID}/result]
+[processes/{id}/jobs/{jobID}/results]
 method=get
 title=The result of a job execution.
@@ -135,6 +161,7 @@
 tags=GetResult
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/result.yaml
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/Results.yaml
 parameters=/components/parameters/id,/components/parameters/jobID
+ecode=404,500
 ep=,/components/parameters/oas-header2
 
@@ -151,5 +178,6 @@
 tags_description=
 schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/valueType.yaml
-parameters=/components/parameters/id,/components/parameters/jobID,/components/parameters/resultID,/components/parameters/oas-header2
+parameters=/components/parameters/id,/components/parameters/jobID,/components/parameters/resultID
+ep=,/components/parameters/oas-header2
 
 
@@ -184,13 +212,83 @@
 required=false
 
-[conformTo]
-rootUrl=http://www.opengis.net/spec/WPS/2.0/req/service/binding/rest-json/
+[conformsTo]
+rootUrl=http://www.opengis.net/spec/ogcapi-processes/1.0/conf/
+rootUrl0=http://www.opengis.net/spec/WPS/2.0/req/service/binding/rest-json/
 link=core
 link_1=oas30
 link_2=json
-length=3
+link_3=job-list
+link_4=dismiss
+link_5=callback
+length=6
 
 [exception]
 abstract=Exception
 type=application/json
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/exception.yaml
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/NotFound.yaml
+default_schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/ServerError.yaml
+
+[responses]
+length=5
+code=404
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/NotFound.yaml
+type=application/json
+title=NotFound
+code_1=500
+schema_1=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/ServerError.yaml
+type_1=application/json
+title_1=ServerError
+code_2=400
+schema_2=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/InvalidParameter.yaml
+type_2=appliction/json
+title_2=InvalidParameter
+code_3=405
+schema_3=https://github.com/opengeospatial/wps-rest-binding/blob/master/core/openapi/responses/NotAllowed.yaml
+type_3=appliction/json
+title_3=NotAllowed
+code_4=406
+schema_4=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/responses/NotSupported.yaml
+type_4=appliction/json
+title_4=NotSupported
+
+[callbacks]
+length=3
+state=jobSuccess
+uri=successUri
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/result.yaml
+type=application/json
+title=Results received successfully
+state_1=jobInProgress
+uri_1=inProgressUri
+schema_1=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/statusInfo.yaml
+type_1=application/json
+title_1=Results received successfully
+state_2=jobFailed
+uri_2=failedUrii
+schema_2=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/exception.yaml
+type_2=application/json
+title_2=Exception received successfully
+
+[links_title]
+self=View this document in JSON.
+alternate=View the alternative version in HTML.
+conformance=View the specifications that the link’s context conforms to.
+service-desc=View the service description.
+service-doc=View service documentation.
+processes=View the list of processes the API offers.
+results=View the results of a process.
+status=View the current status of a job execution.
+execute=View the execution endpoint of a process.
+
+[provider_alt]
+addressDeliveryPoint=streetAddress
+addressCity=addressLocality
+addressAdministrativeArea=addressRegion
+addressPostalCode=postalCode
+addressCountry=addressCountry
+addressElectronicMailAddress=email
+phoneVoice=telephone
+phoneFacsimile=faxNumber
+hoursOfService=hoursAvailable
+contactInstructions=contactOption
+
Index: trunk/zoo-project/zoo-kernel/otbZooWatcher.cxx
===================================================================
--- trunk/zoo-project/zoo-kernel/otbZooWatcher.cxx	(revision 961)
+++ trunk/zoo-project/zoo-kernel/otbZooWatcher.cxx	(revision 962)
@@ -45,5 +45,8 @@
     {
       int progressPercent = static_cast<int>(m_Process->GetProgress() * 100);
-      updateStatus(m_Conf,progressPercent,m_Comment.c_str());
+      if(progressPercent>iCounter){
+	updateStatus(m_Conf,progressPercent,m_Comment.c_str());
+	iCounter=progressPercent;
+      }
     }
 }
@@ -56,4 +59,5 @@
   m_TimeProbe.Start();
 #endif
+  iCounter=-1;
 }
 
Index: trunk/zoo-project/zoo-kernel/otbZooWatcher.h
===================================================================
--- trunk/zoo-project/zoo-kernel/otbZooWatcher.h	(revision 961)
+++ trunk/zoo-project/zoo-kernel/otbZooWatcher.h	(revision 962)
@@ -87,4 +87,7 @@
   maps* m_Conf;
 
+  /** Counter */
+  int iCounter;
+
 };
 
Index: trunk/zoo-project/zoo-kernel/request_parser.c
===================================================================
--- trunk/zoo-project/zoo-kernel/request_parser.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/request_parser.c	(revision 962)
@@ -317,5 +317,6 @@
 		    if (strncasecmp (tmpx2, "http://", 7) != 0 &&
 			strncasecmp (tmpx2, "ftp://", 6) != 0 &&
-			strncasecmp (tmpx2, "https://", 8) != 0)
+			strncasecmp (tmpx2, "https://", 8) != 0 &&
+			strncasecmp (tmpx2, "file://", 7) != 0)
 		      {
 			char emsg[1024];
Index: trunk/zoo-project/zoo-kernel/response_print.c
===================================================================
--- trunk/zoo-project/zoo-kernel/response_print.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/response_print.c	(revision 962)
@@ -2719,15 +2719,5 @@
   }
   if(res==SERVICE_FAILED){
-    map *lenv;
-    lenv=getMapFromMaps(m,"lenv","message");
-    char *tmp0;
-    if(lenv!=NULL){
-      tmp0=(char*)malloc((strlen(lenv->value)+strlen(_("Unable to run the Service. The message returned back by the Service was the following: "))+1)*sizeof(char));
-      sprintf(tmp0,_("Unable to run the Service. The message returned back by the Service was the following: %s"),lenv->value);
-    }
-    else{
-      tmp0=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
-      sprintf(tmp0,"%s",_("Unable to run the Service. No more information was returned back by the Service."));
-    }
+    char* tmp0=produceErrorMessage(m);
     errorException(m,tmp0,"InternalError",NULL);
     free(tmp0);
Index: trunk/zoo-project/zoo-kernel/server_internal.c
===================================================================
--- trunk/zoo-project/zoo-kernel/server_internal.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/server_internal.c	(revision 962)
@@ -952,6 +952,8 @@
       free(res);
     }
-  else
-    addToMap(statusInfo,"Status","Failed");  
+  else{
+    addToMap(statusInfo,"Status","Failed");
+    addToMap(statusInfo,"NotFound",pid);
+  }
   free(fbkpid);
 }
@@ -992,19 +994,33 @@
 void runGetStatus(maps* conf,char* pid,char* req){
   map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  map* e_type = getMapFromMaps (conf, "lenv", "executionType");
   char *sid=getStatusId(conf,pid);
   if(sid==NULL){
-    errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
-		    "NoSuchJob", pid);
+    if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
+      errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
+		      "NoSuchJob", pid);
+    else{
+      setMapInMaps(conf,"lenv","error","true");
+      setMapInMaps(conf,"lenv","code","NoSuchJob");
+      setMapInMaps(conf,"lenv","message",_("The JobID from the request does not match any of the Jobs running on this server"));
+    }
   }else{
     map* statusInfo=createMap("JobID",pid);
-    if(isRunning(conf,pid)>0){		
+    if(isRunning(conf,pid)>0){
       if(strncasecmp(req,"GetResult",strlen(req))==0){
-	errorException (conf, _("The result for the requested JobID has not yet been generated. The service is currently running."),
-			"ResultNotReady", pid);
+	if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
+	  errorException (conf, _("The result for the requested JobID has not yet been generated. The service is currently running."),
+			  "ResultNotReady", pid);
+	else{
+	  setMapInMaps(conf,"lenv","error","true");
+	  setMapInMaps(conf,"lenv","code","ResultNotReady");
+	  setMapInMaps(conf,"lenv","message",_("The result for the requested JobID has not yet been generated. The service is currently running."));
+	}
 	return;
       }
-      else
+      else{
 	if(strncasecmp(req,"GetStatus",strlen(req))==0){
 	  addToMap(statusInfo,"Status","Running");
+	  setMapInMaps(conf,"lenv","status","Running");
 	  char* tmpStr=_getStatus(conf,pid);
 	  if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
@@ -1015,8 +1031,11 @@
 	    addToMap(statusInfo,"PercentCompleted",tmpStr1);
 	    addToMap(statusInfo,"Message",tmpStr0);
+	    setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
+	    setMapInMaps(conf,"lenv","Message",tmpStr0);
 	    free(tmpStr0);
 	    free(tmpStr1);
 	  }
 	}
+      }
     }
     else{
@@ -1043,4 +1062,9 @@
 	if(strncasecmp(req,"GetStatus",strlen(req))==0){
 	  readFinalRes(conf,pid,statusInfo);
+	  if(e_type==NULL || strncasecmp(e_type->value,"json",4)==0){
+	    map* pmStatus=getMap(statusInfo,"status");	    
+	    if(pmStatus!=NULL)
+	      setMapInMaps(conf,"lenv","status",pmStatus->value);    
+	  }
 	  char* tmpStr=_getStatus(conf,pid);
 	  if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
@@ -1051,4 +1075,6 @@
 	    addToMap(statusInfo,"PercentCompleted",tmpStr1);
 	    addToMap(statusInfo,"Message",tmpStr0);
+	    setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
+	    setMapInMaps(conf,"lenv","Message",tmpStr0);
 	    free(tmpStr0);
 	    free(tmpStr1);
@@ -1057,5 +1083,8 @@
     }
     free(sid);
-    printStatusInfo(conf,statusInfo,req);
+    if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
+      printStatusInfo(conf,statusInfo,req);
+    else
+      setMapInMaps(conf,"lenv","error","false");
     freeMap(&statusInfo);
     free(statusInfo);
@@ -1072,8 +1101,16 @@
 void runDismiss(maps* conf,char* pid){
   map* r_inputs = getMapFromMaps (conf, "main", "tmpPath");
+  map* e_type = getMapFromMaps (conf, "lenv", "executionType");
   char *sid=getStatusId(conf,pid);
   if(sid==NULL){
-    errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
-		    "NoSuchJob", pid);
+    if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
+      errorException (conf, _("The JobID from the request does not match any of the Jobs running on this server"),
+		      "NoSuchJob", pid);
+    else{
+      setMapInMaps(conf,"lenv","error","true");
+      setMapInMaps(conf,"lenv","code","NoSuchJob");
+      setMapInMaps(conf,"lenv","message",_("The JobID from the request does not match any of the Jobs running on this server"));
+    }
+    return;
   }else{
     // We should send the Dismiss request to the target host if it differs
@@ -1115,24 +1152,48 @@
 	  sprintf(fileName,"%s/%s",r_inputs->value,dp->d_name);
 	  if(zUnlink(fileName)!=0){
-	    errorException (conf, 
-			    _("The job cannot be removed, a file cannot be removed"),
-			    "NoApplicableCode", NULL);
+	    if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
+	      errorException (conf, 
+			      _("The job cannot be removed, a file cannot be removed"),
+			      "NoApplicableCode", NULL);
+	    else{
+	            setMapInMaps(conf,"lenv","error","true");
+		    setMapInMaps(conf,"lenv","code","NoApplicableCode");
+		    setMapInMaps(conf,"lenv","message",_("The job cannot be removed, a file cannot be removed"));
+	    }
 	    return;
 	  }
-	}
-      }
-    }
+	  
+	}
+      }
+    }
+    map* pmStatusFile=getMapFromMaps(conf,"lenv","file.statusFile");
+    if(pmStatusFile!=NULL && zUnlink(pmStatusFile->value)!=0){
+	if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0)
+	  errorException (conf, 
+			  _("The job cannot be removed, a file cannot be removed"),
+			  "NoApplicableCode", NULL);
+	else{
+	  setMapInMaps(conf,"lenv","error","true");
+		    setMapInMaps(conf,"lenv","code","NoApplicableCode");
+		    setMapInMaps(conf,"lenv","message",_("The job cannot be removed, a file cannot be removed"));
+	}
+	return;
+      }
 #ifdef RELY_ON_DB
     removeService(conf,pid);
 #endif
-    /* No need to call 7_1 when an execution is dismissed.
-      fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
-      invokeCallback(conf,NULL,NULL,7,1);
-      fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
-    */
-    map* statusInfo=createMap("JobID",pid);
-    addToMap(statusInfo,"Status","Dismissed");
-    printStatusInfo(conf,statusInfo,"Dismiss");
-    free(statusInfo);
+    if(e_type==NULL || strncasecmp(e_type->value,"json",4)!=0){
+      /* No need to call 7_1 when an execution is dismissed.
+	 fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
+	 invokeCallback(conf,NULL,NULL,7,1);
+	 fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
+      */
+      map* statusInfo=createMap("JobID",pid);
+      addToMap(statusInfo,"Status","Dismissed");
+      printStatusInfo(conf,statusInfo,"Dismiss");
+      free(statusInfo);
+    }else{
+      setMapInMaps(conf,"lenv","error","false");
+    }
   }
   return;
@@ -1249,4 +1310,24 @@
 }
 
+/**
+ * Create a string containing the basic error message.
+ *
+ * @param pmConf the main configuration maps pointer
+ * @return a new char* containing the error message (ressource should be freed)
+ */
+char* produceErrorMessage(maps* pmConf){
+  char *pacTmp;
+  map *pmLenv=getMapFromMaps(pmConf,"lenv","message");
+  if(pmLenv!=NULL){
+    pacTmp=(char*)malloc((strlen(pmLenv->value)+strlen(_("Unable to run the Service. The message returned back by the Service was the following: "))+1)*sizeof(char));
+    sprintf(pacTmp,_("Unable to run the Service. The message returned back by the Service was the following: %s"),pmLenv->value);
+  }
+  else{
+    pacTmp=(char*)malloc((strlen(_("Unable to run the Service. No more information was returned back by the Service."))+1)*sizeof(char));
+    sprintf(pacTmp,"%s",_("Unable to run the Service. No more information was returned back by the Service."));
+  }
+  return pacTmp;
+}
+
 #ifdef WIN32
 /**
Index: trunk/zoo-project/zoo-kernel/server_internal.h
===================================================================
--- trunk/zoo-project/zoo-kernel/server_internal.h	(revision 961)
+++ trunk/zoo-project/zoo-kernel/server_internal.h	(revision 962)
@@ -60,5 +60,7 @@
   void dumpMapsValuesToFiles(maps**,maps**);
   void runDismiss(maps*,char*);
+  int isRunning(maps*,char*);
   void runGetStatus(maps*,char*,char*);
+  void readFinalRes(maps*,char*,map*);
 
   int isValidLang(maps*,const char*);
@@ -67,4 +69,5 @@
   int readServiceFile (maps *, char *, service **, char *);
   int createRegistry (maps*,registry **,char *);
+  char* produceErrorMessage(maps*);
 
   int zoo_path_compare(char* path1, char* path2);
Index: trunk/zoo-project/zoo-kernel/service.h
===================================================================
--- trunk/zoo-project/zoo-kernel/service.h	(revision 961)
+++ trunk/zoo-project/zoo-kernel/service.h	(revision 962)
@@ -185,4 +185,8 @@
  */
 #define SERVICE_FAILED 4
+/**
+ * The global dismissed status for a service
+ */
+#define SERVICE_DISMISSED 5
 
 /**
Index: trunk/zoo-project/zoo-kernel/service_callback.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_callback.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/service_callback.c	(revision 962)
@@ -27,7 +27,5 @@
  */
 
-#include "service_json.h"
 #include "service_internal_ms.h"
-#include "sqlapi.h"
 #include <pthread.h>
 #include <libxml/tree.h>
@@ -42,4 +40,8 @@
 
 #include "service_callback.h"
+#include "service_json.h"
+#include "sqlapi.h"
+#include <ulinet.h>
+
 
 #ifdef __cplusplus
@@ -66,4 +68,8 @@
    */
   int cStep=0;
+  /**
+   * Maximum value of PercentCompleted
+   */
+  int maxProgress=0;
   /**
    * Is there any ongoing HTTP request
@@ -112,5 +118,171 @@
     return false;
   }
-
+  /**
+   * Practically invoke the callback, meaning sending the HTTP POST request.
+   * 
+   * @param args local_params containing all the variables required
+   */
+  void* _invokeBasicCallback(void* args){
+#ifdef CALLBACK_DEBUG
+    fprintf(stderr,"************************* From thread %d %s %d: REQUEST CONFIGURE (%s)\n",pthread_self(),__FILE__,__LINE__,arg->url->value);
+    fflush(stderr);
+#endif
+    local_params* arg=(local_params*)args;
+    if(arg->state<cStep){
+#ifdef CALLBACK_DEBUG
+      fprintf(stderr,"************************* From thread %d %s %d: REQUEST CANCELLED (%s) EXIT!\n",pthread_self(),__FILE__,__LINE__,arg->url->value);
+      fflush(stderr);
+#endif
+      freeMaps(&arg->conf);
+      free(arg->conf);
+      freeMap(&arg->url);
+      free(arg->url);
+      pthread_exit(NULL);
+      return NULL;
+    }
+    HINTERNET hInternet,res1;
+    const struct tm *tm;
+    size_t len;
+    char *tmp1;
+    map *tmpStatus;
+    map* pmTmp=getMapFromMaps(arg->conf,"lenv","status");
+    hInternet=InternetOpen("ZooWPSClient\0",
+			   INTERNET_OPEN_TYPE_PRECONFIG,
+			   NULL,NULL, 0);
+    if(!CHECK_INET_HANDLE(hInternet)){
+      InternetCloseHandle (&hInternet);
+      return NULL;
+    }
+    const char* jsonStr=json_object_to_json_string_ext(arg->res,JSON_C_TO_STRING_PLAIN);
+    while( arg->state != SERVICE_SUCCEEDED && arg->state != SERVICE_FAILED && isOngoing>0 ){
+      zSleep(100);
+    }
+    if(arg->state==SERVICE_STARTED && pmTmp!=NULL){
+      if(maxProgress<=atoi(pmTmp->value)){
+	maxProgress=atoi(pmTmp->value);
+      }else{
+#ifdef CALLBACK_DEBUG
+	fprintf(stderr,"************************* From thread %d %s %d: REQUEST CANCELLED (%s) EXIT!\n",pthread_self(),__FILE__,__LINE__,arg->url->value);
+	fflush(stderr);
+#endif
+	freeMaps(&arg->conf);
+	free(arg->conf);
+	freeMap(&arg->url);
+	free(arg->url);
+	pthread_exit(NULL);
+	return NULL;
+      }
+    }else
+      maxProgress=101;
+    isOngoing=1;
+    maps* tmpConf=createMaps("main");
+    tmpConf->content=createMap("memory","load");
+
+    hInternet.waitingRequests[0] = zStrdup(arg->url->value);
+    res1 = InternetOpenUrl (&hInternet,
+			    hInternet.waitingRequests[0], 
+			    (char*)jsonStr, strlen(jsonStr),
+			    INTERNET_FLAG_NO_CACHE_WRITE,
+			    0,tmpConf);
+    AddHeaderEntries(&hInternet,arg->conf);
+    AddMissingHeaderEntry(&hInternet.ihandle[hInternet.nb-1],"Content-Type","application/json");
+#ifdef CALLBACK_DEBUG
+    curl_easy_setopt(hInternet.ihandle[hInternet.nb-1].handle, CURLOPT_VERBOSE, 1);
+#endif
+    if(hInternet.ihandle[hInternet.nb-1].header!=NULL)
+      curl_easy_setopt(hInternet.ihandle[hInternet.nb-1].handle,CURLOPT_HTTPHEADER,hInternet.ihandle[hInternet.nb-1].header);
+    processDownloads(&hInternet);
+    freeMaps(&tmpConf);
+    free(tmpConf);
+#ifdef CALLBACK_DEBUG
+    char *tmp = (char *) malloc ((hInternet.ihandle[0].nDataLen + 1)
+				 * sizeof (char));
+    if (tmp == NULL)
+      {
+	setMapInMaps(arg->conf,"lenv","message",_("Unable to allocate memory"));
+	setMapInMaps(arg->conf,"lenv","code","InternalError");
+	return NULL;
+      }
+    size_t bRead;
+    InternetReadFile (hInternet.ihandle[0],
+		      (LPVOID) tmp,
+		      hInternet.
+		      ihandle[0].nDataLen,
+		      &bRead);
+    tmp[hInternet.ihandle[0].nDataLen] = 0;
+    fprintf(stderr,"************************* From thread %d %s %d: REQUEST END \n%s",pthread_self(),__FILE__,__LINE__,tmp);
+    fflush(stderr);
+    free(tmp);
+#endif
+    json_object_put(arg->res);
+    InternetCloseHandle(&hInternet);
+    isOngoing=0;
+    freeMaps(&arg->conf);
+    free(arg->conf);
+    freeMap(&arg->url);
+    if(arg->url!=NULL)
+      free(arg->url);
+    pthread_exit(NULL);
+  }
+
+  /**
+   * Invoke the callback in case there is a [subscriber] section containing one
+   * or more url parameter.
+   * 
+   * @param conf the maps containing the main configuration file definitions
+   * @param state the service state SERVICE_SUCCEEDED / STARTED / FAILED
+   * @return bool true in case of success, false in other cases
+   */
+  bool invokeBasicCallback(maps* conf,int state){
+    map* url=getMapFromMaps(conf,"subscriber","inProgressUri");
+    if(state==SERVICE_SUCCEEDED)
+      url=getMapFromMaps(conf,"subscriber","successUri");
+    else
+      if(state==SERVICE_FAILED)
+	url=getMapFromMaps(conf,"subscriber","failedUri");
+    if(url==NULL)
+      return false;
+    map* url0=createMap("url",url->value);
+    map* sname=getMapFromMaps(conf,"lenv","identifier");
+    if(sname!=NULL && isProhibited(conf,sname->value))
+      return false;
+    if(state<cStep)
+      return true;
+    if(cStep!=state || isOngoing==0){
+      json_object *res=NULL;
+      if(state==SERVICE_SUCCEEDED || state==SERVICE_FAILED){
+	maps* pmsTmp=getMaps(conf,"lenv");
+	setMapInMaps(conf,"lenv","no-write","true");
+	map* pmTmp=getMapFromMaps(conf,"lenv","usid");
+	if(pmTmp!=NULL){
+	  map* pmResponse=getMapFromMaps(conf,"lenv","jsonStr");
+	  res=parseJson(conf,pmResponse->value);
+	}
+      }else
+	res=createStatus(conf,state);
+      if(local_arguments==NULL)
+	local_arguments=(local_params**)malloc(sizeof(local_params*));
+      else
+	local_arguments=(local_params**)realloc(local_arguments,(nbThreads+1)*sizeof(local_params*));
+      local_arguments[nbThreads]=(local_params*)malloc(MAPS_SIZE+MAP_SIZE+sizeof(json_object*)+(2*sizeof(int)));	
+      local_arguments[nbThreads]->conf=dupMaps(&conf);
+      local_arguments[nbThreads]->url=url0;
+      local_arguments[nbThreads]->res=res;
+      local_arguments[nbThreads]->step=0;
+      local_arguments[nbThreads]->state=state;
+      cStep=state;
+      if(myThreads==NULL)
+	myThreads=(pthread_t*)malloc((nbThreads+1)*sizeof(pthread_t));
+      else
+	myThreads=(pthread_t*)realloc(myThreads,(nbThreads+1)*sizeof(pthread_t));
+      if(pthread_create(&myThreads[nbThreads], NULL, _invokeBasicCallback, (void*)local_arguments[nbThreads])==-1){
+	setMapInMaps(conf,"lenv","message",_("Unable to create a new thread"));
+	return false;
+      }
+      nbThreads++;
+    }
+    return true;
+  }
+  
   /**
    * Practically invoke the callback, meaning sending the HTTP POST request.
@@ -336,5 +508,5 @@
 	      map* tmpMap=getMapArray(curs->content,"value",ii);
 	      char tmpStr[100];
-	      sprintf(tmpStr,"%d",strlen(tmpMap->value));
+	      sprintf(tmpStr,"%ld",strlen(tmpMap->value));
 	      setMapArray(curs->content,"size",ii,tmpStr);
 	      tmpMap=getMapArray(curs->content,"mimeType",ii);
@@ -570,16 +742,18 @@
 	      jsStr=json_object_new_string(tmp2->value);
 	      json_object_object_add(res2,"target_path",jsStr);
-	      json_object *res4=json_object_object_get(res1,tmp0->value);
-	      if(json_object_is_type(res4,json_type_null)){
-		json_object_object_add(res1,tmp0->value,res2);
-	      }else{
-		if(json_object_is_type(res4,json_type_object) && !json_object_is_type(res4, json_type_array)){
-		  json_object *res3=json_object_new_array();
-		  json_object_array_add(res3,json_object_get(res4));
-		  json_object_array_add(res3,res2);
-		  json_object_object_del(res1,tmp0->value);
-		  json_object_object_add(res1,tmp0->value,res3);
-		}else
-		  json_object_array_add(res4,res2);
+	      json_object *res4=NULL;
+	      if(json_object_object_get_ex(res1,tmp0->value,&res4)!=FALSE){
+		if(json_object_is_type(res4,json_type_null)){
+		  json_object_object_add(res1,tmp0->value,res2);
+		}else{
+		  if(json_object_is_type(res4,json_type_object) && !json_object_is_type(res4, json_type_array)){
+		    json_object *res3=json_object_new_array();
+		    json_object_array_add(res3,json_object_get(res4));
+		    json_object_array_add(res3,res2);
+		    json_object_object_del(res1,tmp0->value);
+		    json_object_object_add(res1,tmp0->value,res3);
+		  }else
+		    json_object_array_add(res4,res2);
+		}
 	      }
 	    }
@@ -866,4 +1040,7 @@
    */
   void cleanupCallbackThreads(){
+    while( isOngoing>0 ){
+      zSleep(100);
+    }
     int i=0;
     for(i=0;i<nbThreads;i++){
Index: trunk/zoo-project/zoo-kernel/service_callback.h
===================================================================
--- trunk/zoo-project/zoo-kernel/service_callback.h	(revision 961)
+++ trunk/zoo-project/zoo-kernel/service_callback.h	(revision 962)
@@ -32,7 +32,4 @@
 #pragma once
 
-#include <ulinet.h>
-#include <stdio.h>
-#include <ctype.h>
 #include <service.h>
 
@@ -41,4 +38,5 @@
 #endif
 
+  bool invokeBasicCallback(maps*,int);
   bool invokeCallback(maps*,maps*,maps*,int,int);
   void cleanupCallbackThreads();
Index: trunk/zoo-project/zoo-kernel/service_internal.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/service_internal.c	(revision 962)
@@ -412,5 +412,6 @@
     free(fbkpid);
     char* stat=getStatusId(conf,lid);
-    setMapInMaps(conf,"lenv","lid",stat);
+    if(stat!=NULL)
+      setMapInMaps(conf,"lenv","lid",stat);
     removeShmLock(conf,1);
     return NULL;
@@ -470,4 +471,5 @@
       fflush(fstatus);
       fclose(fstatus);
+      invokeBasicCallback(conf,SERVICE_STARTED);
     }
     if(stat!=NULL){
Index: trunk/zoo-project/zoo-kernel/service_internal_otb.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal_otb.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/service_internal_otb.c	(revision 962)
@@ -122,8 +122,12 @@
   map* tmp=NULL;
   int res=-1;
+  int saved_stdout = zDup (fileno (stdout));
+  zDup2 (fileno (stderr), fileno (stdout));
   std::vector<std::string> list = ApplicationRegistry::GetAvailableApplications();
   if (list.size() == 0){
     map* tmps=createMap("text","No OTB Application found.");
     addToMap(tmps,"code","InternalError");
+    zDup2 (saved_stdout, fileno (stdout));
+    zClose(saved_stdout);
     printExceptionReportResponse(m,tmps);
     freeMap(&tmps);
@@ -142,4 +146,6 @@
 	  map* tmps=createMap("text",tmpS);
 	  addToMap(tmps,"code","InternalError");
+	  zDup2 (saved_stdout, fileno (stdout));
+	  zClose(saved_stdout);
 	  printExceptionReportResponse(m,tmps);
 	  freeMap(&tmps);
@@ -460,4 +466,6 @@
 	  catch(std::exception& err){
 	    setMapInMaps(m,"lenv","message",err.what());
+	    zDup2 (saved_stdout, fileno (stdout));
+	    zClose(saved_stdout);
 	    return SERVICE_FAILED;
 	    
@@ -479,5 +487,7 @@
   }
   m_WatcherList.clear();
-
+  fflush(stdout);
+  zDup2 (saved_stdout, fileno (stdout));
+  zClose(saved_stdout);
   return res;
 }
Index: trunk/zoo-project/zoo-kernel/service_internal_python.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 962)
@@ -446,5 +446,5 @@
     Py_DECREF(name);
     tmp=tmp->next;
-  }  
+  }
   return (PyDictObject*) res;
 }
@@ -572,5 +572,5 @@
     }
     else{
-      if(PyDict_GetItem(res,name)==NULL){
+      if(PyDict_GetItem(res,name)==NULL && strlen(tmp->value)>0){
 	PyObject* value=PyString_FromString(tmp->value);
 	if(PyDict_SetItem(res,name,value)<0){
Index: trunk/zoo-project/zoo-kernel/service_json.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_json.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/service_json.c	(revision 962)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- *  Copyright 2017-2019 GeoLabs SARL. All rights reserved.
+ *  Copyright 2017-2020 GeoLabs SARL. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -223,4 +223,8 @@
       if(tmpMap1!=NULL){
 	json_object_object_add(prop2,"name",json_object_new_string(tmpMap1->value));
+	char *tmp=(char*)malloc((strlen(tmpMap1->value)+35)*sizeof(char));
+	sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmpMap1->value);
+	json_object_object_add(prop2,"reference",json_object_new_string(tmp));
+	free(tmp);
 	json_object_object_add(prop1,"dataType",prop2);
       }
@@ -371,12 +375,16 @@
       tmpMap=getMap(in->content,"abstract");
       if(tmpMap!=NULL)
-	json_object_object_add(input,"abstract",json_object_new_string(tmpMap->value));
+	json_object_object_add(input,"description",json_object_new_string(tmpMap->value));
       if(strcmp(io,"input")==0){
 	tmpMap=getMap(in->content,"minOccurs");
 	if(tmpMap!=NULL)
-	  json_object_object_add(input,"minOccurs",json_object_new_string(tmpMap->value));
+	  json_object_object_add(input,"minOccurs",json_object_new_int(atoi(tmpMap->value)));
 	tmpMap=getMap(in->content,"maxOccurs");
-	if(tmpMap!=NULL)
-	  json_object_object_add(input,"maxOccurs",json_object_new_string(tmpMap->value));
+	if(tmpMap!=NULL){
+	  if(strncasecmp(tmpMap->value,"unbounded",9)==0)
+	    json_object_object_add(input,"maxOccurs",json_object_new_string(tmpMap->value));
+	  else
+	    json_object_object_add(input,"maxOccurs",json_object_new_int(atoi(tmpMap->value)));
+	}
       }
       if(in->format!=NULL){
@@ -439,5 +447,10 @@
     json_object* doc=(json_object*) doc0;
     json_object* nc=(json_object*) nc0;
-    json_object *res=json_object_new_object();
+    json_object *res;
+    if(doc!=NULL)
+      res=json_object_new_object();
+    else
+      res=(json_object*) nc0;
+      
     map* tmpMap0=getMapFromMaps(m,"lenv","level");
     char* rUrl=serv->name;
@@ -486,5 +499,5 @@
       tmpMap=getMap(serv->content,"abstract");
       if(tmpMap!=NULL){
-	json_object_object_add(res,"abstract",json_object_new_string(tmpMap->value));
+	json_object_object_add(res,"description",json_object_new_string(tmpMap->value));
       }
       tmpMap=getMap(serv->content,"processVersion");
@@ -498,5 +511,6 @@
 	else
 	  json_object_object_add(res,"version",json_object_new_string(tmpMap->value));
-      }
+      }else
+	json_object_object_add(res,"version",json_object_new_string("1.0.0"));
       int limit=4;
       int i=0;
@@ -517,5 +531,13 @@
       json_object *res1=json_object_new_array();
       json_object *res2=json_object_new_object();
-      json_object_object_add(res2,"rel",json_object_new_string("canonical"));
+      json_object *res3=json_object_new_object();
+      map* pmTmp=getMapFromMaps(m,"lenv","requestType");
+      if(pmTmp!=NULL && strncasecmp(pmTmp->value,"desc",4)==0)
+	json_object_object_add(res2,"rel",json_object_new_string("process-desc"));
+      else{
+	json_object_object_add(res2,"rel",json_object_new_string("execute"));
+	json_object_object_add(res3,"rel",json_object_new_string("alternate"));
+	json_object_object_add(res3,"type",json_object_new_string("text/html"));
+      }
       json_object_object_add(res2,"type",json_object_new_string("application/json"));
       json_object_object_add(res2,"title",json_object_new_string("Process Description"));
@@ -525,12 +547,22 @@
       if(doc==NULL){
 	json_object_object_add(res2,"title",json_object_new_string("Execute End Point"));
+	json_object_object_add(res3,"title",json_object_new_string("Execute End Point"));
 	char* tmpStr1=zStrdup(tmpStr);
 	tmpStr=(char*) realloc(tmpStr,(strlen(tmpStr)+6)*sizeof(char));
-	sprintf(tmpStr,"%sjobs/",tmpStr1);
+	sprintf(tmpStr,"%sjobs",tmpStr1);
 	free(tmpStr1);
+	char* tmpStr3=(char*) malloc((strlen(tmpStr)+6)*sizeof(char));
+	sprintf(tmpStr3,"%s.html",tmpStr);
+	json_object_object_add(res3,"href",json_object_new_string(tmpStr3));
+	free(tmpStr3);
       }
       json_object_object_add(res2,"href",json_object_new_string(tmpStr));
       free(tmpStr);
       json_object_array_add(res1,res2);
+      tmpUrl=getMapFromMaps(m,"openapi","partial_html_support");
+      if(tmpUrl!=NULL && strncasecmp(tmpUrl->value,"true",4)==0)
+	json_object_array_add(res1,res3);
+      else
+	json_object_put(res3);
       json_object_object_add(res,"links",res1);
     }
@@ -551,7 +583,4 @@
     if(doc!=NULL)
       json_object_array_add(doc,res);
-    else
-      json_object_object_add(nc,"process",json_object_get(res));
-
   }
 
@@ -577,5 +606,5 @@
       if(strcmp(tmp->value,"OperationNotSupported")==0 ||
 	 strcmp(tmp->value,"NoApplicableCode")==0)
-	exceptionCode="501 Not Implemented";
+	exceptionCode="500 Not Implemented";
       else
 	if(strcmp(tmp->value,"MissingParameterValue")==0 ||
@@ -586,29 +615,37 @@
 	  exceptionCode="400 Bad request";
 	else
-	  if(strcmp(tmp->value,"NotFound")==0)
+	  if(strcmp(tmp->value,"NotFound")==0 ||
+	     strcmp(tmp->value,"NoSuchProcess")==0 ||
+	     strcmp(tmp->value,"NoSuchJob")==0 ||
+	     strcmp(tmp->value,"ResultNotReady")==0)
 	    exceptionCode="404 Not Found";
 	  else
-	    exceptionCode="501 Internal Server Error";
+	    exceptionCode="500 Internal Server Error";
       json_object_object_add(res,"code",json_object_new_string(tmp->value));
     }
-    else
-      exceptionCode="501 Internal Server Error";
-    printHeaders(m);
+    else{
+      exceptionCode="500 Internal Server Error";
+      json_object_object_add(res,"code",json_object_new_string("NoApplicableCode"));
+    }
+    if(getMapFromMaps(m,"lenv","no-headers")==NULL)
+      printHeaders(m);
 
     tmp=getMapFromMaps(m,"lenv","status_code");
     if(tmp!=NULL)
       exceptionCode=tmp->value;
-    if(m!=NULL){
-      map *tmpSid=getMapFromMaps(m,"lenv","sid");
-      if(tmpSid!=NULL){
-	if( getpid()==atoi(tmpSid->value) ){
+    if(getMapFromMaps(m,"lenv","no-headers")==NULL){
+      if(m!=NULL){
+	map *tmpSid=getMapFromMaps(m,"lenv","sid");
+	if(tmpSid!=NULL){
+	  if( getpid()==atoi(tmpSid->value) ){
+	    printf("Status: %s\r\n\r\n",exceptionCode);
+	  }
+	}
+	else{
 	  printf("Status: %s\r\n\r\n",exceptionCode);
 	}
-      }
-      else{
+      }else{
 	printf("Status: %s\r\n\r\n",exceptionCode);
       }
-    }else{
-      printf("Status: %s\r\n\r\n",exceptionCode);
     }
     tmp=getMap(s,"text");
@@ -620,4 +657,7 @@
       json_object_object_add(res,"description",json_object_new_string(tmp->value));
     const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
+    if(getMapFromMaps(m,"lenv","jsonStr")==NULL)
+      setMapInMaps(m,"lenv","jsonStr",jsonStr);
+    maps* pmsTmp=getMaps(m,"lenv");
     printf(jsonStr);
     if(m!=NULL)
@@ -876,5 +916,5 @@
    * @param outputs the produced maps
    */
-  void parseJRequest(maps* conf, service* s,json_object* req,maps** inputs,maps** outputs){
+  void parseJRequest(maps* conf, service* s,json_object* req, map* request_inputs, maps** inputs,maps** outputs){
     elements* io=s->inputs;
 
@@ -890,5 +930,39 @@
 	parseJIO(conf,req,s->outputs,outputs,"outputs");
       }
-    }      
+      json_io=NULL;
+      if(json_object_object_get_ex(req,"mode",&json_io)!=FALSE){
+	addToMap(request_inputs,"mode",json_object_get_string(json_io));
+	setMapInMaps(conf,"request","mode",json_object_get_string(json_io));
+      }
+      json_io=NULL;
+      if(json_object_object_get_ex(req,"response",&json_io)!=FALSE){
+	addToMap(request_inputs,"response",json_object_get_string(json_io));
+	setMapInMaps(conf,"request","response",json_object_get_string(json_io));
+      }
+      json_io=NULL;
+      if(json_object_object_get_ex(req,"subscriber",&json_io)!=FALSE){
+	maps* subscribers=createMaps("subscriber");
+	json_object* json_subscriber=NULL;
+	if(json_object_object_get_ex(json_io,"successUri",&json_subscriber)!=FALSE){
+	  subscribers->content=createMap("successUri",json_object_get_string(json_subscriber));
+	}
+	if(json_object_object_get_ex(json_io,"inProgressUri",&json_subscriber)!=FALSE){
+	  if(subscribers->content==NULL)
+	    subscribers->content=createMap("inProgressUri",json_object_get_string(json_subscriber));
+	  else
+	    addToMap(subscribers->content,"inProgressUri",json_object_get_string(json_subscriber));
+	}
+	if(json_object_object_get_ex(json_io,"failedUri",&json_subscriber)!=FALSE){
+	  if(subscribers->content==NULL)
+	    subscribers->content=createMap("failedUri",json_object_get_string(json_subscriber));
+	  else
+	    addToMap(subscribers->content,"failedUri",json_object_get_string(json_subscriber));
+	}
+	addMapsToMaps(&conf,subscribers);
+	freeMaps(&subscribers);
+	free(subscribers);
+      }
+    }
+    
   }
 
@@ -934,8 +1008,8 @@
 	    if (jerr != json_tokener_success) {
 	      fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
-	      return res;
+	      return NULL;
 	    }
 	    if (tok->char_offset < slen){
-	      return res;
+	      return NULL;
 	    }
 	    json_object_object_add(cjob,"infos",jobj);
@@ -951,5 +1025,5 @@
     return res;
   }
-
+  
   /**
    * Print the result of an execution
@@ -958,10 +1032,23 @@
    * @param s service pointer to metadata
    * @param result outputs of the service
-   * @param res the status of executino SERVICE_FAILED/SERVICE_SUCCEEDED
+   * @param res the status of execution SERVICE_FAILED/SERVICE_SUCCEEDED
    * @return the JSON object pointer to the result
    */
   json_object* printJResult(maps* conf,service* s,maps* result,int res){
-    printHeaders(conf);
     json_object* eres1=json_object_new_object();
+    if(res==SERVICE_FAILED){
+      char* pacTmp=produceErrorMessage(conf);
+      map* pamTmp=createMap("message",pacTmp);
+      free(pacTmp);
+      map* pmTmp=getMapFromMaps(conf,"lenv","code");
+      if(pmTmp!=NULL)
+	addToMap(pamTmp,"code",pmTmp->value);
+      printExceptionReportResponseJ(conf,pamTmp);
+      freeMap(&pamTmp);
+      free(pamTmp);
+      return NULL;
+    }
+    if(getMapFromMaps(conf,"lenv","no-headers")==NULL)
+      printHeaders(conf);
     json_object* eres=json_object_new_array();
     maps* resu=result;
@@ -970,5 +1057,8 @@
       json_object* res1=json_object_new_object();
       json_object_object_add(res1,"id",json_object_new_string(resu->name));
-      map* tmpMap=NULL;
+      map* tmpMap=getMap(resu->content,"mimeType");
+      json_object* res3=json_object_new_object();
+      if(tmpMap!=NULL)
+	json_object_object_add(res3,"mimeType",json_object_new_string(tmpMap->value));
       if((tmpMap=getMap(resu->content,"value"))!=NULL ||
 	 (getMap(resu->content,"generated_file"))!=NULL){
@@ -994,7 +1084,31 @@
 		return eres1;		
 	      }
+	      json_object_object_add(res3,"encoding",json_object_new_string("utf-8"));
 	      json_object_object_add(res2,"inlineValue",jobj);
-	    }else
-	      json_object_object_add(res2,"inlineValue",json_object_new_string(tmpMap->value));
+	    }else{
+	      map* tmp1=getMapFromMaps(conf,"main","tmpPath");
+	      map *gfile=getMap(resu->content,"generated_file");
+	      if(gfile!=NULL){
+		gfile=getMap(resu->content,"expected_generated_file");
+		if(gfile==NULL){
+		  gfile=getMap(resu->content,"generated_file");
+		}
+		FILE* pfData=fopen(gfile->value,"rb");
+		if(pfData!=NULL){
+		  zStatStruct f_status;
+		  int s=zStat(gfile->value, &f_status);
+		  char* pcaTmp=(char*)malloc((f_status.st_size+1)*sizeof(char));
+		  fread(pcaTmp,1,f_status.st_size,pfData);
+		  pcaTmp[f_status.st_size]=0;	    
+		  fclose(pfData);
+		  json_object_object_add(res2,"inlineValue",json_object_new_string(base64(pcaTmp,f_status.st_size)));
+		  json_object_object_add(res3,"encoding",json_object_new_string("base64"));
+		  free(pacTmp);
+		}
+	      }else{
+		json_object_object_add(res3,"encoding",json_object_new_string("utf-8"));
+		json_object_object_add(res2,"inlineValue",json_object_new_string(tmpMap->value));
+	      }
+	    }
 	  }
 	  else{
@@ -1098,4 +1212,5 @@
 	}
 	json_object_object_add(res1,"value",res2);	
+	json_object_object_add(res1,"format",res3);	
 	json_object_array_add(eres,res1);
       }
@@ -1108,23 +1223,29 @@
     map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
     map *sessId = getMapFromMaps (conf, "lenv", "usid");
-    char tmp[1024];
-    sprintf(tmp,"%s/%s_%s.json",
+    char *pacTmp=(char*)malloc((strlen(tmpPath->value)+strlen(cIdentifier->value)+strlen(sessId->value)+8)*sizeof(char));
+    sprintf(pacTmp,"%s/%s_%s.json",
 	    tmpPath->value,cIdentifier->value,sessId->value);
-    FILE* foutput=fopen(tmp,"w+");
-    if(foutput!=NULL){
-      fclose(foutput);
-      char tmpUrl[1024];
+    zStatStruct zsFStatus;
+    int iS=zStat(pacTmp, &zsFStatus);
+    if(iS==0 && zsFStatus.st_size>0){
       map* tmpPath1 = getMapFromMaps (conf, "main", "tmpUrl");
-      sprintf(tmpUrl,"%s/%s_%s.json",tmpPath1->value,
+      char* pacTmpUrl=(char*)malloc((strlen(tmpPath1->value)+strlen(cIdentifier->value)+strlen(sessId->value)+8)*sizeof(char));;
+      sprintf(pacTmpUrl,"%s/%s_%s.json",tmpPath1->value,
 	      cIdentifier->value,sessId->value);
-      setMapInMaps(conf,"headers","Location",tmpUrl);
-    }
+      if(getMapFromMaps(conf,"lenv","gs_location")==NULL)
+	setMapInMaps(conf,"headers","Location",pacTmpUrl);
+      free(pacTmpUrl);
+    }
+    free(pacTmp);
     if(res==3){
-      setMapInMaps(conf,"headers","Status","201 Created");
+      map* mode=getMapFromMaps(conf,"request","mode");
+      if(mode!=NULL && strncasecmp(mode->value,"async",5)==0)
+	setMapInMaps(conf,"headers","Status","201 Created");
+      else
+	setMapInMaps(conf,"headers","Status","200 Ok");
     }
     else{
       setMapInMaps(conf,"headers","Status","500 Issue running your service");
     }
-
     return eres1;
   }
@@ -1144,4 +1265,7 @@
     map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
     map *sessId = getMapFromMaps (conf, "lenv", "usid");
+    if(sessId==NULL){
+      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
+    }
     char *Url0=(char*) malloc((strlen(tmpPath->value)+
 			       strlen(cIdentifier->value)+
@@ -1153,8 +1277,13 @@
 	    cIdentifier->value,
 	    sessId->value);
-    setMapInMaps(conf,"headers","Location",Url0);
+    if(getMapFromMaps(conf,"lenv","gs_location")==NULL)
+      setMapInMaps(conf,"headers","Location",Url0);
     json_object* val=json_object_new_object();
-    json_object_object_add(val,"Title",
+    json_object_object_add(val,"title",
 			   json_object_new_string(_("Status location")));
+    json_object_object_add(val,"rel",
+			   json_object_new_string(_("status")));
+    json_object_object_add(val,"type",
+			   json_object_new_string(_("application/json")));
     json_object_object_add(val,"href",json_object_new_string(Url0));
     json_object_array_add(res,val);
@@ -1164,11 +1293,15 @@
 			   strlen(cIdentifier->value)+strlen(sessId->value)+
 			   25)*sizeof(char));
-      sprintf(Url0,"%s/processes/%s/jobs/%s/result",
+      sprintf(Url0,"%s/processes/%s/jobs/%s/results",
 	      tmpPath->value,
 	      cIdentifier->value,
 	      sessId->value);
       json_object* val1=json_object_new_object();
-      json_object_object_add(val1,"Title",
+      json_object_object_add(val1,"title",
 			     json_object_new_string(_("Result location")));
+      json_object_object_add(val1,"rel",
+			     json_object_new_string(_("results")));
+      json_object_object_add(val1,"type",
+			     json_object_new_string(_("application/json")));
       json_object_object_add(val1,"href",json_object_new_string(Url0));
       json_object_array_add(res,val1);
@@ -1204,8 +1337,7 @@
       return NULL;
     }
-    free(tmp1);
-    tmp1=(char*) malloc((strlen(tmpPath->value)+
+    tmp1=(char*) realloc(tmp1,(strlen(tmpPath->value)+
 			 strlen(cIdentifier->value)+
-			 strlen(sessId->value)+20)*sizeof(char));
+			 strlen(sessId->value)+21)*sizeof(char));
     int needResult=0;
     char *message, *rstatus;
@@ -1214,24 +1346,67 @@
 	    cIdentifier->value,
 	    sessId->value);
-    
     return tmp1;
   }
+
+  char* getResultPath(maps* conf,char* jobId){
+    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
+    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
+    char *pacUrl=(char*) malloc((strlen(tmpPath->value)+
+				 strlen(cIdentifier->value)+
+				 strlen(jobId)+8)*sizeof(char));
+    sprintf(pacUrl,"%s/%s_%s.json",tmpPath->value,
+	    cIdentifier->value,jobId);
+    return pacUrl;
+  }
+
+  json_object* parseJson(maps* conf,char* myString){
+    json_object *pajObj = NULL;
+    enum json_tokener_error jerr;
+    struct json_tokener* tok=json_tokener_new();
+    int slen = 0;
+    do {
+      slen = strlen(myString);
+      pajObj = json_tokener_parse_ex(tok, myString, slen);
+    } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
+    if (jerr != json_tokener_success) {
+      setMapInMaps(conf,"lenv","message",json_tokener_error_desc(jerr));
+      fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
+      return NULL;
+    }
+    if (tok->char_offset < slen){
+      return NULL;
+    }
+    return pajObj;
+  }
   
-  /**
-   * Create the status file 
-   *
-   * @param conf the maps containing the settings of the main.cfg file
-   * @param status an integer (SERVICE_ACCEPTED,SERVICE_STARTED...)
-   * @return an integer (0 in case of success, 1 in case of failure)
-   */
-  int createStatusFile(maps* conf,int status){
+  json_object* json_readFile(maps* conf,char* filePath){
+    json_object *pajObj = NULL;
+    zStatStruct zsFStatus;
+    int iS=zStat(filePath, &zsFStatus);
+    if(iS==0 && zsFStatus.st_size>0){
+      FILE* cdat=fopen(filePath,"rb");
+      if(cdat!=NULL){
+	char* pacMyString=(char*)malloc((zsFStatus.st_size+1)*sizeof(char));
+	fread(pacMyString,1,zsFStatus.st_size,cdat);
+	pacMyString[zsFStatus.st_size]=0;
+	fclose(cdat);
+	pajObj=parseJson(conf,pacMyString);
+	free(pacMyString);
+      }
+      else
+	return NULL;
+    }else
+      return NULL;
+    return pajObj;
+  }
+  
+  json_object* createStatus(maps* conf,int status){
     int needResult=0;
-    const char *message, *rstatus;
-    char* tmp1=json_getStatusFilePath(conf);
+    const char *rstatus;
+    char *message;
     // Create statusInfo JSON object
     // cf. https://github.com/opengeospatial/wps-rest-binding/blob/master/core/
     //     openapi/schemas/statusInfo.yaml
     json_object* res=json_object_new_object();
-    json_object_object_add(res,"status",json_object_new_string("successful"));
     switch(status){
     case SERVICE_ACCEPTED:
@@ -1244,4 +1419,10 @@
       {
 	message=_("ZOO-Kernel is currently running your service!");
+	map* pmStatus=getMapFromMaps(conf,"lenv","status");
+	if(pmStatus!=NULL)
+	  setMapInMaps(conf,"lenv","PercentCompleted",pmStatus->value);
+	pmStatus=getMapFromMaps(conf,"lenv","message");
+	if(pmStatus!=NULL)
+	  setMapInMaps(conf,"lenv","gs_message",pmStatus->value);
 	rstatus="running";
 	break;
@@ -1257,10 +1438,36 @@
 	message=_("ZOO-Kernel successfully run your service!");
 	rstatus="successful";
+	setMapInMaps(conf,"lenv","PercentCompleted","100");
 	needResult=1;
 	break;
       }
+    case SERVICE_DISMISSED:
+      {
+	message=_("ZOO-Kernel successfully dismissed your service!");
+	rstatus="dismissed";
+	needResult=1;
+	break;
+      }
     default:
       {
-	message=_("ZOO-Kernel failed to run your service!");
+	map* pmTmp=getMapFromMaps(conf,"lenv","force");
+	if(pmTmp==NULL || strncasecmp(pmTmp->value,"false",5)==0){
+	  char* pacTmp=json_getStatusFilePath(conf);
+	  json_object* pjoStatus=json_readFile(conf,pacTmp);
+	  free(pacTmp);
+	  if(pjoStatus!=NULL){
+	    json_object* pjoMessage=NULL;
+	    if(json_object_object_get_ex(pjoStatus,"message",&pjoMessage)!=FALSE){
+	      message=(char*)json_object_get_string(pjoMessage);
+	    }
+	  }
+	  // TODO: Error
+	}else{
+	  map* mMap=getMapFromMaps(conf,"lenv","gs_message");
+	  if(mMap!=NULL)
+	    setMapInMaps(conf,"lenv","message",mMap->value);
+	  message=produceErrorMessage(conf);
+	  needResult=-1;
+	}
 	rstatus="failed";
 	break;
@@ -1269,11 +1476,62 @@
     setMapInMaps(conf,"lenv","message",message);
     setMapInMaps(conf,"lenv","status",rstatus);
-	
-    map* mess=getMapFromMaps(conf,"lenv","message");
-    if(mess!=NULL)
-      json_object_object_add(res,"message",json_object_new_string(mess->value));
-
-    createStatusLinks(conf,needResult,res);
-    
+
+    map *sessId = getMapFromMaps (conf, "lenv", "usid");
+    if(sessId!=NULL){
+      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
+      if(sessId==NULL)
+	sessId = getMapFromMaps (conf, "lenv", "usid");
+    }else
+      sessId = getMapFromMaps (conf, "lenv", "gs_usid");
+    if(sessId!=NULL)
+      json_object_object_add(res,"jobID",json_object_new_string(sessId->value));
+    json_object_object_add(res,"status",json_object_new_string(rstatus));
+    map* mMap=getMapFromMaps(conf,"lenv","gs_message");
+    if(mMap==NULL)
+      json_object_object_add(res,"message",json_object_new_string(message));
+    else{
+      json_object_object_add(res,"message",json_object_new_string(mMap->value));
+      if((mMap=getMapFromMaps(conf,"lenv","PercentCompleted"))!=NULL)
+	json_object_object_add(res,"progress",json_object_new_int(atoi(mMap->value)));
+    }
+    if(status!=SERVICE_DISMISSED)
+      createStatusLinks(conf,needResult,res);
+    else{
+      json_object* res1=json_object_new_array();
+      map *tmpPath = getMapFromMaps (conf, "openapi", "rootUrl");
+      map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
+      char *Url0=(char*) malloc((strlen(tmpPath->value)+
+				 strlen(cIdentifier->value)+
+				 17)*sizeof(char));
+      sprintf(Url0,"%s/processes/%s/jobs",	      
+	      tmpPath->value,
+	      cIdentifier->value);
+      json_object* val=json_object_new_object();
+      json_object_object_add(val,"title",
+			     json_object_new_string(_("The job list for the current process")));
+      json_object_object_add(val,"rel",
+			     json_object_new_string(_("parent")));
+      json_object_object_add(val,"type",
+			     json_object_new_string(_("application/json")));
+      json_object_object_add(val,"href",json_object_new_string(Url0));
+      json_object_array_add(res1,val);
+      free(Url0);
+      json_object_object_add(res,"links",res1);
+    }
+    if(needResult<0)
+      free(message);
+    return res;
+  }
+  
+  /**
+   * Create the status file 
+   *
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param status an integer (SERVICE_ACCEPTED,SERVICE_STARTED...)
+   * @return an integer (0 in case of success, 1 in case of failure)
+   */
+  int createStatusFile(maps* conf,int status){
+    json_object* res=createStatus(conf,status);
+    char* tmp1=json_getStatusFilePath(conf);
     FILE* foutput1=fopen(tmp1,"w+");
     if(foutput1!=NULL){
@@ -1303,16 +1561,19 @@
     map* tmpMap=getMapFromMaps(conf,"lenv","gs_usid");
     if(tmpMap!=NULL){
-	char* tmpStr=_getStatus(conf,tmpMap->value);
-	if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
-	  char *tmpStr1=zStrdup(tmpStr);
-	  char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
-	  free(tmpStr);
-	  tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
-	  setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
-	  setMapInMaps(conf,"lenv","gs_message",tmpStr0);
-	  free(tmpStr0);
-	  free(tmpStr1);
-	}
-      }
+      char* tmpStr=_getStatus(conf,tmpMap->value);
+      if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
+	char *tmpStr1=zStrdup(tmpStr);
+	char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
+	free(tmpStr);
+	tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
+	setMapInMaps(conf,"lenv","PercentCompleted",tmpStr1);
+	setMapInMaps(conf,"lenv","gs_message",tmpStr0);
+	free(tmpStr0);
+	free(tmpStr1);
+	return 0;
+      }else{
+	  
+      }
+    }
   }
 
@@ -1371,8 +1632,8 @@
 
     json_object *res4=json_object_new_object();
-    tmpMap=getMapFromMaps(conf,"main","license_name");
+    tmpMap=getMapFromMaps(conf,"openapi","license_name");
     if(tmpMap!=NULL){
       json_object_object_add(res4,"name",json_object_new_string(tmpMap->value));
-      tmpMap=getMapFromMaps(conf,"main","license_url");
+      tmpMap=getMapFromMaps(conf,"openapi","license_url");
       if(tmpMap!=NULL){
 	json_object_object_add(res4,"url",json_object_new_string(tmpMap->value));      
@@ -1384,4 +1645,64 @@
   }
 
+  // addResponse(pmUseContent,cc3,vMap,tMap,"200","successful operation");
+  void addResponse(const map* useContent,json_object* res,const map* pmSchema,const map* pmType,const char* code,const char* msg){
+    json_object *cc=json_object_new_object();
+    if(pmSchema!=NULL)
+      json_object_object_add(cc,"$ref",json_object_new_string(pmSchema->value));
+    if(useContent!=NULL && strncasecmp(useContent->value,"true",4)!=0){
+	json_object_object_add(res,code,cc);
+    }else{
+	json_object *cc0=json_object_new_object();
+	if(pmSchema!=NULL)
+	  json_object_object_add(cc0,"schema",cc);
+	json_object *cc1=json_object_new_object();
+	if(pmType!=NULL)
+	  json_object_object_add(cc1,pmType->value,cc0);
+	else
+	  json_object_object_add(cc1,"application/json",cc0);
+	json_object *cc2=json_object_new_object();
+	json_object_object_add(cc2,"content",cc1);
+	json_object_object_add(cc2,"description",json_object_new_string(msg));
+	json_object_object_add(res,code,cc2);
+    }
+  }
+
+  void addParameter(maps* conf,const char* oName,const char* fName,const char* in,json_object* res){
+    maps* tmpMaps1=getMaps(conf,oName);
+    json_object *res8=json_object_new_object();
+    if(tmpMaps1!=NULL){
+      map* tmpMap=getMap(tmpMaps1->content,"title");
+      if(tmpMap!=NULL)
+	json_object_object_add(res8,"x-internal-summary",json_object_new_string(tmpMap->value));
+      tmpMap=getMap(tmpMaps1->content,"abstract");
+      if(tmpMap!=NULL)
+	json_object_object_add(res8,"description",json_object_new_string(tmpMap->value));
+      tmpMap=getMap(tmpMaps1->content,"example");
+      if(tmpMap!=NULL)
+	json_object_object_add(res8,"example",json_object_new_string(tmpMap->value));
+      tmpMap=getMap(tmpMaps1->content,"required");
+      if(tmpMap!=NULL){
+	if(strcmp(tmpMap->value,"true")==0)
+	  json_object_object_add(res8,"required",json_object_new_boolean(TRUE));
+	else
+	  json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
+      }
+      else
+	json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
+      json_object_object_add(res8,"in",json_object_new_string(in));
+      json_object_object_add(res8,"name",json_object_new_string(fName));
+      json_object *res6=json_object_new_object();
+      tmpMap=getMap(tmpMaps1->content,"type");
+      if(tmpMap!=NULL)
+	json_object_object_add(res6,"type",json_object_new_string(tmpMap->value));
+      else
+	json_object_object_add(res6,"type",json_object_new_string("string"));
+	
+      json_object_object_add(res8,"schema",res6);
+	
+    }	
+    json_object_object_add(res,fName,res8);    
+  }
+  
   /**
    * Produce the JSON object for api parameter
@@ -1397,104 +1718,38 @@
     char *tmps12 = strtok_r (tmpMap2->value, ",", &saveptr12);
     while(tmps12!=NULL){
-      char* tmpId=(char*) malloc((strlen(tmps12)+3)*sizeof(char));
-      sprintf(tmpId,"{%s}",tmps12);
-      tmpMaps1=getMaps(conf,tmpId);
-      json_object *res8=json_object_new_object();
-      if(tmpMaps1!=NULL){
-	map* tmpMap=getMap(tmpMaps1->content,"title");
-	if(tmpMap!=NULL)
-	  json_object_object_add(res8,"x-internal-summary",json_object_new_string(tmpMap->value));
-	tmpMap=getMap(tmpMaps1->content,"abstract");
-	if(tmpMap!=NULL)
-	  json_object_object_add(res8,"description",json_object_new_string(tmpMap->value));
-	tmpMap=getMap(tmpMaps1->content,"example");
-	if(tmpMap!=NULL)
-	  json_object_object_add(res8,"example",json_object_new_string(tmpMap->value));
-	tmpMap=getMap(tmpMaps1->content,"required");
-	if(tmpMap!=NULL){
-	  if(strcmp(tmpMap->value,"true")==0)
-	    json_object_object_add(res8,"required",json_object_new_boolean(TRUE));
-	  else
-	    json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
-	}
-	else
-	  json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
-	json_object_object_add(res8,"in",json_object_new_string("path"));
-	json_object_object_add(res8,"name",json_object_new_string(tmps12));
-	json_object *res6=json_object_new_object();
-	json_object *res7=json_object_new_object();
-	tmpMap=getMap(tmpMaps1->content,"type");
-	if(tmpMap!=NULL)
-	  json_object_object_add(res6,"type",json_object_new_string(tmpMap->value));
-	else
-	  json_object_object_add(res6,"type",json_object_new_string("string"));
-	
-	json_object_object_add(res8,"schema",res6);
-	
-      }
-	
-      json_object_object_add(res9,tmps12,res8);
+      char* pacId=(char*) malloc((strlen(tmps12)+3)*sizeof(char));
+      sprintf(pacId,"{%s}",tmps12);
+      addParameter(conf,pacId,tmps12,"path",res9);
+      free(pacId);
       tmps12 = strtok_r (NULL, ",", &saveptr12);
     }    
     tmpMap2=getMapFromMaps(conf,"openapi","header_parameters");
-    char *saveptr13;
-    char *tmps13 = strtok_r (tmpMap2->value, ",", &saveptr13);
-    while(tmps13!=NULL){
-      char* tmpId=zStrdup(tmps13);
-      maps *tmpMaps2=getMaps(conf,tmpId);
-      json_object *res8=json_object_new_object();
-      if(tmpMaps2!=NULL){
-	map* tmpMap=getMap(tmpMaps2->content,"title");
-	if(tmpMap!=NULL)
-	  json_object_object_add(res8,"x-internal-summary",json_object_new_string(tmpMap->value));
-	tmpMap=getMap(tmpMaps2->content,"abstract");
-	if(tmpMap!=NULL)
-	  json_object_object_add(res8,"description",json_object_new_string(tmpMap->value));
-	tmpMap=getMap(tmpMaps2->content,"example");
-	if(tmpMap!=NULL)
-	  json_object_object_add(res8,"example",json_object_new_string(tmpMap->value));
-	tmpMap=getMap(tmpMaps2->content,"required");
-	if(tmpMap!=NULL){
-	  if(strcmp(tmpMap->value,"true")==0)
-	    json_object_object_add(res8,"required",json_object_new_boolean(TRUE));
-	  else
-	    json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
-	}
-	else
-	  json_object_object_add(res8,"required",json_object_new_boolean(FALSE));
-	json_object_object_add(res8,"in",json_object_new_string("header"));
-	tmpMap=getMap(tmpMaps2->content,"name");
-	if(tmpMap!=NULL)
-	  json_object_object_add(res8,"name",json_object_new_string(tmpMap->value));
-	json_object *res6=json_object_new_object();
-	json_object *res7=json_object_new_object();
-	tmpMap=getMap(tmpMaps2->content,"type");
-	if(tmpMap!=NULL)
-	  json_object_object_add(res6,"type",json_object_new_string(tmpMap->value));
-	else
-	  json_object_object_add(res6,"type",json_object_new_string("string"));
-
-	{
-	  tmpMap=getMap(tmpMaps2->content,"enum");
-	  if(tmpMap!=NULL){
-	    char *saveptr11;
-	    char *tmps11 = strtok_r (tmpMap->value, ",", &saveptr11);
-	    json_object *res71=json_object_new_array();
-	    while(tmps11!=NULL){		
-	      json_object_array_add(res71,json_object_new_string(tmps11));
-	      tmps11 = strtok_r (NULL, ",", &saveptr11);
-	    }
-	    json_object_object_add(res6,"enum",res71);				  
-	  }
-	}
-	
-	json_object_object_add(res8,"schema",res6);
-	
-      }
-	
-      json_object_object_add(res9,tmpId,res8);
-      tmps13 = strtok_r (NULL, ",", &saveptr13);
-    } 
-    json_object_object_add(res,"parameters",res9);    
+    if(tmpMap2!=NULL){
+      char *saveptr13;
+      char *tmps13 = strtok_r (tmpMap2->value, ",", &saveptr13);
+      while(tmps13!=NULL){
+	char* pacId=zStrdup(tmps13);
+	addParameter(conf,pacId,pacId,"header",res9);
+	free(pacId);
+	tmps13 = strtok_r (NULL, ",", &saveptr13);
+      }
+    }
+    json_object_object_add(res,"parameters",res9);
+    maps* pmResponses=getMaps(conf,"responses");
+    if(pmResponses!=NULL){
+      json_object *cc=json_object_new_object();
+      map* pmLen=getMap(pmResponses->content,"length");
+      int iLen=atoi(pmLen->value);
+      map* pmUseContent=getMapFromMaps(conf,"openapi","use_content");
+      for(int i=0;i<iLen;i++){
+	map* cMap=getMapArray(pmResponses->content,"code",i);
+	map* vMap=getMapArray(pmResponses->content,"schema",i);
+	map* tMap=getMapArray(pmResponses->content,"type",i);
+	map* tMap0=getMapArray(pmResponses->content,"title",i);
+	if(vMap!=NULL)
+	  addResponse(pmUseContent,cc,vMap,tMap,cMap->value,(tMap0==NULL)?"successful operation":tMap0->value);
+      }
+      json_object_object_add(res,"responses",cc);
+    }
   }
 
@@ -1504,5 +1759,5 @@
     json_object_object_add(res,"components",res1);
   }
-
+  
   /**
    * Produce the JSON object for /api
@@ -1512,8 +1767,8 @@
    */
   void produceApi(maps* conf,json_object* res){
+    // TODO: add 401 Gone for dismiss request
     json_object *res9=json_object_new_object();
     json_object *res10=json_object_new_object();
     maps* tmpMaps1=getMaps(conf,"{id}");
-
     produceApiComponents(conf,res);
     json_object *res4=json_object_new_object();
@@ -1562,62 +1817,40 @@
 	    json_object *responses=json_object_new_object();
 	    json_object *cc3=json_object_new_object();
+	    map* pmUseContent=getMapFromMaps(conf,"openapi","use_content");
 	    vMap=getMapArray(tmpMaps->content,"schema",i);
 	    if(vMap!=NULL){
-	      json_object *cc=json_object_new_object();
-	      json_object_object_add(cc,"$ref",json_object_new_string(vMap->value));
-	      json_object *cc0=json_object_new_object();
-	      json_object_object_add(cc0,"schema",cc);
-	      json_object *cc1=json_object_new_object();
-	      map* tmpMap3=getMapFromMaps(conf,tmps,"type");
-	      if(tmpMap3!=NULL)
-		json_object_object_add(cc1,tmpMap3->value,cc0);
-	      else
-		json_object_object_add(cc1,"application/json",cc0);
-	      json_object *cc2=json_object_new_object();
-	      json_object_object_add(cc2,"content",cc1);
-	      json_object_object_add(cc2,"description",json_object_new_string("successful operation"));
-	      if(i==1)
-		json_object_object_add(cc3,"201",cc2);
-	      else
-		json_object_object_add(cc3,"200",cc2);
+	      map* tMap=getMapArray(tmpMaps->content,"type",i);
+	      addResponse(pmUseContent,cc3,vMap,tMap,"200","successful operation");
+	      vMap=getMapArray(tmpMaps->content,"eschema",i);
+	      if(vMap!=NULL && cMap!=NULL && strncasecmp(cMap->value,"post",4)==0)
+		addResponse(pmUseContent,cc3,vMap,tMap,"201","successful operation");
 	    }else{
-	      json_object *cc1=json_object_new_object();
-	      map* tmpMap3=getMapFromMaps(conf,tmps,"type");
-	      if(tmpMap3!=NULL)
-		json_object_object_add(cc1,tmpMap3->value,json_object_new_object());
-	      else
-		json_object_object_add(cc1,"application/json",json_object_new_object());
-	      json_object *cc2=json_object_new_object();
-	      json_object_object_add(cc2,"content",cc1);
-	      json_object_object_add(cc2,"description",json_object_new_string("successful operation"));
-	      if(i==1)
-		json_object_object_add(cc3,"201",cc2);
-	      else
-		json_object_object_add(cc3,"200",cc2);
+	      map* tMap=getMapFromMaps(conf,tmps,"type");
+	      map* pMap=createMap("ok","true");
+	      addResponse(pMap,cc3,vMap,tMap,"200","successful operation");
+	      if(cMap!=NULL && strncasecmp(cMap->value,"post",4)==0)
+		addResponse(pmUseContent,cc3,vMap,tMap,"201","successful operation");
 	    }
-	    if(strstr(tmps,"{id}")!=NULL){
-	      vMap=getMapFromMaps(conf,"exception","schema");
-	      json_object *cc=json_object_new_object();
-	      json_object_object_add(cc,"$ref",json_object_new_string(vMap->value));
-	      json_object *cc01=json_object_new_array();
-	      json_object_array_add(cc01,cc);
-
-	      json_object *cc0=json_object_new_object();
-	      json_object_object_add(cc0,"schema",cc);
-	      json_object *cc1=json_object_new_object();
-	      map* tmpMap3=getMapFromMaps(conf,"exception","type");
-	      if(tmpMap3!=NULL)
-		json_object_object_add(cc1,tmpMap3->value,cc0);
-	      else
-		json_object_object_add(cc1,"application/json",cc0);
-
-	      json_object *cc2=json_object_new_object();
-	      json_object_object_add(cc2,"content",cc1);
-	      if(strstr(tmps,"{jobID}")==NULL)
-		json_object_object_add(cc2,"description",json_object_new_string("The process with id {id} does not exist."));
-	      else
-		json_object_object_add(cc2,"description",json_object_new_string("The process with id {id} or job with id {jobID} does not exist."));
-	      json_object_object_add(cc3,"404",cc2);
-	      json_object_object_add(cc3,"default",cc2);
+	    vMap=getMapArray(tmpMaps->content,"ecode",i);
+	    if(vMap!=NULL){
+	      char *saveptr0;
+	      char *tmps1 = strtok_r (vMap->value, ",", &saveptr0);
+	      while(tmps1!=NULL){
+		char* tmpStr=(char*)malloc((strlen(tmps1)+24)*sizeof(char));
+		sprintf(tmpStr,"#/components/responses/%s",tmps1);
+		vMap=createMap("ok",tmpStr);
+		map* pMap=createMap("ok","false");
+		//TODO: fix successful operation with correct value
+		addResponse(pMap,cc3,vMap,NULL,tmps1,"successful operation");
+		tmps1 = strtok_r (NULL, ",", &saveptr0);
+	      }
+	    }else{
+	      if(strstr(tmps,"{id}")!=NULL){
+		vMap=getMapFromMaps(conf,"exception","schema");
+		map* tMap=getMapFromMaps(conf,"exception","type");
+		if(vMap!=NULL)
+		  addResponse(pmUseContent,cc3,vMap,tMap,"404",
+			      (strstr(tmps,"{jobID}")==NULL)?"The process with id {id} does not exist.":"The process with id {id} or job with id {jobID} does not exist.");
+	      }
 	    }
 	    json_object_object_add(methodc,"responses",cc3);
@@ -1640,5 +1873,5 @@
 	      json_object_object_add(methodc,"parameters",cc2);
 	    }
-	    if(i==1){
+	    if(i==1 && cMap!=NULL && strncasecmp(cMap->value,"post",4)==0){
 	      maps* tmpMaps1=getMaps(conf,"requestBody");
 	      if(tmpMaps1!=NULL){
@@ -1663,5 +1896,55 @@
 		  json_object_object_add(methodc,"requestBody",cc2);
 
+		}		
+	      }
+	      // TODO: callbacks
+	      tmpMaps1=getMaps(conf,"callbacks");
+	      if(tmpMaps1!=NULL){
+		map* pmTmp2=getMap(tmpMaps1->content,"length");
+		int iLen=atoi(pmTmp2->value);
+		json_object *pajRes=json_object_new_object();
+		for(int i=0;i<iLen;i++){
+		  map* pmState=getMapArray(tmpMaps1->content,"state",i);
+		  map* pmUri=getMapArray(tmpMaps1->content,"uri",i);
+		  map* pmSchema=getMapArray(tmpMaps1->content,"schema",i);
+		  map* pmType=getMapArray(tmpMaps1->content,"type",i);
+		  map* pmTitle=getMapArray(tmpMaps1->content,"title",i);
+		  json_object *pajSchema=json_object_new_object();
+		  if(pmSchema!=NULL)
+		    json_object_object_add(pajSchema,"$ref",json_object_new_string(pmSchema->value));
+		  json_object *pajType=json_object_new_object();
+		  json_object_object_add(pajType,"schema",pajSchema);
+		  json_object *pajContent=json_object_new_object();
+		  if(pmType!=NULL)
+		    json_object_object_add(pajContent,pmType->value,pajType);
+		  else		  
+		    json_object_object_add(pajContent,"application/json",pajType);
+		  json_object *pajRBody=json_object_new_object();
+		  json_object_object_add(pajRBody,"content",pajContent);
+		  
+		  json_object *pajDescription=json_object_new_object();
+		  if(pmTitle!=NULL)
+		    json_object_object_add(pajDescription,"description",json_object_new_string(pmTitle->value));
+		  json_object *pajResponse=json_object_new_object();
+		  json_object_object_add(pajResponse,"200",pajDescription);
+
+		  json_object *pajPost=json_object_new_object();
+		  json_object_object_add(pajPost,"requestBody",pajRBody);
+		  json_object_object_add(pajPost,"responses",pajResponse);
+
+		  json_object *pajMethod=json_object_new_object();
+		  json_object_object_add(pajMethod,"post",pajPost);
+
+		  
+		  char* pacUri=(char*) malloc((strlen(pmUri->value)+29)*sizeof(char));
+		  sprintf(pacUri,"{$request.body#/subscriber/%s}",pmUri->value);
+
+		  json_object *pajFinal=json_object_new_object();
+		  json_object_object_add(pajFinal,pacUri,pajMethod);
+
+		  json_object_object_add(pajRes,pmState->value,pajFinal);
+
 		}
+		json_object_object_add(methodc,"callbacks",pajRes);
 	      }
 	    }
Index: trunk/zoo-project/zoo-kernel/service_json.h
===================================================================
--- trunk/zoo-project/zoo-kernel/service_json.h	(revision 961)
+++ trunk/zoo-project/zoo-kernel/service_json.h	(revision 962)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- *  Copyright 2014 GeoLabs SARL. All rights reserved.
+ *  Copyright 2014-2020 GeoLabs SARL. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -50,8 +50,13 @@
   void printGetCapabilitiesForProcessJ(registry*, maps*,void*,void*,service*);
   void printExceptionReportResponseJ(maps*,map*);
-  void parseJRequest(maps*,service* s,json_object*,maps**,maps**);
+  void parseJRequest(maps*,service* s,json_object*,map*,maps**,maps**);
   json_object*  printJResult(maps*,service*,maps*,int);
   json_object* printJobList(maps*);
   int createStatusFile(maps*,int);
+  json_object* createStatus(maps*,int);
+  char* json_getStatusFilePath(maps*);
+  json_object* parseJson(maps*,char*);
+  json_object* json_readFile(maps*,char*);
+  char* getResultPath(maps*,char*);
   int json_getStatusFile(maps*);
   void produceApi(maps*,json_object*);
Index: trunk/zoo-project/zoo-kernel/sqlapi.c
===================================================================
--- trunk/zoo-project/zoo-kernel/sqlapi.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/sqlapi.c	(revision 962)
@@ -33,4 +33,5 @@
 #include <fcgi_stdio.h>
 #include "sqlapi.h"
+#include "service_callback.h"
 
 /**
@@ -375,7 +376,11 @@
   map *msg=getMapFromMaps(conf,"lenv","message");
   map *schema=getMapFromMaps(conf,"database","schema");
-  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(msg->value)+strlen(p->value)+strlen(sid->value)+64+1)*sizeof(char));
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(msg->value)+strlen(p->value)+strlen(sid->value)+62+1)*sizeof(char));
   sprintf(sqlQuery,"UPDATE %s.services set status=$$%s$$,message=$$%s$$ where uuid=$$%s$$;",schema->value,p->value,msg->value,sid->value);
   if( zoo_DS == NULL || zoo_DS[zoo_ds_nb-1]==NULL ){
+    if(getMapFromMaps(conf,"lenv","file.log")==NULL){
+      free(sqlQuery);
+      return 1;
+    }
     init_sql(conf);
     zoo_ds_nb++;
@@ -384,4 +389,5 @@
   cleanUpResultSet(conf,zoo_ds_nb-1);
   free(sqlQuery);
+  invokeBasicCallback(conf,SERVICE_STARTED);
   return 0;
 }
@@ -398,6 +404,6 @@
   int created=-1;
   map *schema=getMapFromMaps(conf,"database","schema");
-  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
-  sprintf(sqlQuery,"select status||'|'||message from %s.services where uuid=$$%s$$;",schema->value,pid);
+  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+104+1)*sizeof(char));  
+  sprintf(sqlQuery,"select CASE WHEN message is null THEN '-1' ELSE status||'|'||message END from %s.services where uuid=$$%s$$;",schema->value,pid);
   if( zoo_ds_nb==
 #ifdef META_DB
Index: trunk/zoo-project/zoo-kernel/zoo_loader.c
===================================================================
--- trunk/zoo-project/zoo-kernel/zoo_loader.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/zoo_loader.c	(revision 962)
@@ -105,5 +105,4 @@
        int len=0;
        while((r=fread(buffer,sizeof(char),1,cgiIn))>0){
-	 fprintf(stderr,"%s",buffer);
 	 buffer[1]=0;
 	 if(res==NULL){
Index: trunk/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 961)
+++ trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 962)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- *  Copyright 2008-2013 GeoLabs SARL. All rights reserved.
+ *  Copyright 2008-2020 GeoLabs SARL. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -63,10 +63,10 @@
 #include <string.h>
 
-#include "service.h"
-
 #include "service_internal.h"
 #include "server_internal.h"
 #include "response_print.h"
 #include "request_parser.h"
+#include "service.h"
+
 #ifdef USE_JSON
 #include "caching.h"
@@ -106,5 +106,5 @@
 #endif
 
-#ifdef USE_CALLBACK
+#if defined(USE_CALLBACK) || defined(USE_JSON)
 #include "service_callback.h"
 #endif
@@ -417,6 +417,12 @@
 	     _("Unable to parse the ZCFG file: %s."),
 	     zcfg);
+  
   map* errormap = createMap("text", tmp01);
-  addToMap(errormap,"code", code);
+  map* tmpMap=getMapFromMaps(m,"lenv","executionType");
+  char* errorCode=(char*)code;
+  if(tmpMap!=NULL && strncasecmp(tmpMap->value,"json",4)==0)
+    errorCode="NoSuchProcess";
+
+  addToMap(errormap,"code", errorCode);
   addToMap(errormap,"locator", locator);
   funcError(m,errormap);
@@ -685,4 +691,5 @@
   fflush (stdout);
   zDup2 (saved_stdout, fileno (stdout));
+  zClose(saved_stdout);
   free (orig);
   return 0;
@@ -1870,10 +1877,20 @@
 #endif
   }
-  
+
+  int eres = SERVICE_STARTED;
+  int cpid = zGetpid ();
+  maps* bmap=NULL;
+  char *fbkp, *fbkpid, *fbkpres, *fbkp1, *flog;
+  FILE *f0, *f1;
+  HINTERNET hInternet;
+  service *s1;
+  maps *request_output_real_format = NULL;
+  maps *request_input_real_format = NULL;
+
   setMapInMaps(m,"lenv","executionType","xml");
-  if((strlen(cgiQueryString)>0 && cgiQueryString[0]=='/') && strstr(cgiAccept,"json")!=NULL){
-  //
-  // OGC API - Processing starts here
-  //
+  if((strlen(cgiQueryString)>0 && cgiQueryString[0]=='/') /*&& strstr(cgiAccept,"json")!=NULL*/){
+    //
+    // OGC API - Processing starts here
+    //
 #ifndef USE_JSON
     errorException (m, _("OGC API - Processing is not supported by this ZOO-Kernel."), "InternalError", NULL);
@@ -1904,5 +1921,24 @@
     addMapsToMaps(&m,m1);
     setMapInMaps(m,"lenv","executionType","json");
-
+    map* pmTmp0=getMapFromMaps(m,"openapi","full_html_support");
+    dumpMap(pmTmp0);
+    if(strstr(cgiQueryString,".html")==NULL && strstr(cgiAccept,"text/html")!=NULL && pmTmp0!=NULL && strncasecmp(pmTmp0->value,"true",4)==0){
+      map* pmTmpUrl=getMapFromMaps(m,"openapi","rootUrl");
+      char* pacTmpUrl=NULL;
+      if(strcmp(cgiQueryString,"/")!=0){
+	 pacTmpUrl=(char*)malloc((strlen(cgiQueryString)+strlen(pmTmpUrl->value)+6)*sizeof(char));
+	 sprintf(pacTmpUrl,"%s%s.html",pmTmpUrl->value,cgiQueryString);
+      }
+      else{
+	pacTmpUrl=(char*)malloc((strlen(pmTmpUrl->value)+6)*sizeof(char));
+	sprintf(pacTmpUrl,"%s/index.html",pmTmpUrl->value);
+      }
+      setMapInMaps(m,"headers","Location",pacTmpUrl);
+      printHeaders(m);
+      printf("Status: 302 Moved permanently \r\n\r\n");
+      fflush(stdout);
+      free(pacTmpUrl);
+      return 1;
+    }
     json_object *res=json_object_new_object();
     setMapInMaps(m,"headers","Content-Type","application/json;charset=UTF-8");
@@ -1917,20 +1953,58 @@
       for(int kk=0;kk<4;kk++){
 	maps* tmpMaps=getMaps(m,urls[kk]);
-	json_object *res2;
 	if(tmpMaps!=NULL){
+	  json_object *res2;
 	  res2=mapToJson(tmpMaps->content);
 	  char* tmpStr=(char*) malloc((strlen(tmpUrl->value)+strlen(urls[kk])+2)*sizeof(char));
 	  sprintf(tmpStr,"%s%s",tmpUrl->value,urls[kk]);
 	  json_object_object_add(res2,"href",json_object_new_string(tmpStr));
+	  free(tmpStr);
 	  json_object_array_add(res1,res2);
+
+	  map* pmTmp=getMap(tmpMaps->content,"title");
+	  char *pacTitle=NULL;
+	  if(pmTmp!=NULL)
+	    pacTitle=zStrdup(pmTmp->value);
+	  char* pacTmp=(char*) malloc((strlen(urls[kk])+6)*sizeof(char));
+	  sprintf(pacTmp,"%s.html",urls[kk]);
+	  tmpMaps=getMaps(m,pacTmp);
+	  if(tmpMaps==NULL && strncasecmp(pacTmp,"/.html",6)==0)
+	    tmpMaps=getMaps(m,"/index.html");
+	  if(tmpMaps!=NULL){
+	    json_object *res3;
+	    res3=mapToJson(tmpMaps->content);
+	    if(getMap(tmpMaps->content,"title")==NULL && pacTitle!=NULL){
+	      json_object_object_add(res3,"title",json_object_new_string(pacTitle));
+	    }
+	    char* tmpStr=NULL;
+	    if(strncasecmp(pacTmp,"/.html",6)==0){
+	      tmpStr=(char*) malloc((strlen(tmpUrl->value)+12)*sizeof(char));
+	      sprintf(tmpStr,"%s/index.html",tmpUrl->value);
+	    }else{
+	      tmpStr=(char*) malloc((strlen(tmpUrl->value)+strlen(urls[kk])+6)*sizeof(char));
+	      sprintf(tmpStr,"%s%s.html",tmpUrl->value,urls[kk]);
+	    }
+	    json_object_object_add(res3,"href",json_object_new_string(tmpStr));
+	    free(tmpStr);
+	    json_object_array_add(res1,res3);
+	  }
+	  free(pacTmp);
+	  if(pacTitle!=NULL)
+	    free(pacTitle);	  
 	}
       }
+      map* pmTmp=getMapFromMaps(m,"identification","title");
+      if(pmTmp!=NULL)
+	json_object_object_add(res,"title",json_object_new_string(pmTmp->value));
+      pmTmp=getMapFromMaps(m,"identification","abstract");
+      if(pmTmp!=NULL)
+	json_object_object_add(res,"description",json_object_new_string(pmTmp->value));
       json_object_object_add(res,"links",res1);
     }else if(strcmp(cgiQueryString,"/conformance")==0){
       /* - /conformance url */
-      map* rootUrl=getMapFromMaps(m,"conformTo","rootUrl");
+      map* rootUrl=getMapFromMaps(m,"conformsTo","rootUrl");
       json_object *res1=json_object_new_array();
-      map* length=getMapFromMaps(m,"conformTo","length");
-      maps* tmpMaps=getMaps(m,"conformTo");
+      map* length=getMapFromMaps(m,"conformsTo","length");
+      maps* tmpMaps=getMaps(m,"conformsTo");
       for(int kk=0;kk<atoi(length->value);kk++){
 	map* tmpMap1=getMapArray(tmpMaps->content,"link",kk);
@@ -1942,15 +2016,23 @@
 	}
       }
-      json_object_object_add(res,"conformTo",res1);
-    }else if(strcmp(cgiQueryString,"/api")==0){
-      /* - /api url */
-      produceApi(m,res);
+      json_object_object_add(res,"conformsTo",res1);
+    }else if(strncasecmp(cgiQueryString,"/api",4)==0){
+      if(strstr(cgiQueryString,".html")==NULL)
+	produceApi(m,res);
+      else{	
+	char* pacTmp=(char*)malloc(9*sizeof(char));
+	sprintf(pacTmp,"%s",cgiQueryString+1);
+	map* pmTmp=getMapFromMaps(m,pacTmp,"href");
+	free(pacTmp);
+	if(pmTmp!=NULL)
+	  setMapInMaps(m,"headers","Location",pmTmp->value);
+      }	
     }else if(strcmp(cgiQueryString,"/processes")==0 || strcmp(cgiQueryString,"/processes/")==0){
       /* - /processes */
+      setMapInMaps(m,"lenv","requestType","desc");
       json_object *res3=json_object_new_array();
       int saved_stdout = zDup (fileno (stdout));
       zDup2 (fileno (stderr), fileno (stdout));
-
-      if (int res =		  
+      if (int res0 =		  
           recursReaddirF (m, NULL, res3, NULL, ntmp, NULL, saved_stdout, 0,
 			  printGetCapabilitiesForProcessJ) < 0)
@@ -1959,6 +2041,6 @@
       zDup2 (saved_stdout, fileno (stdout));
       zClose(saved_stdout);
-      
-      json_object_object_add(res,"processes",res3);
+      res=res3;
+      //json_object_object_add(res,"processes",res3);
     }else{
       service* s1=NULL;
@@ -1984,4 +2066,5 @@
 	    orig[strlen(orig)-1]=0;
 	  json_object* res1=json_object_new_object();
+	  setMapInMaps(m,"lenv","requestType","GetCapabilities");
 	  int t=fetchServicesForDescription(NULL, m, orig,
 					    printGetCapabilitiesForProcessJ,
@@ -1991,6 +2074,6 @@
 	  if(t==1){
 	    /*map* error=createMap("code","BadRequest");
-	    addToMap(error,"message",_("Failed to acces the requested service"));
-	    printExceptionReportResponseJ(m,error);*/
+	      addToMap(error,"message",_("Failed to acces the requested service"));
+	      printExceptionReportResponseJ(m,error);*/
 	    return 1;
 	  }
@@ -2003,5 +2086,4 @@
 	  int cnt=0;
 	  for(int j=11;j<len1;j++){
-	    fprintf(stderr,"%s %c\n",cIdentifier,cgiQueryString[j]);
 	    cIdentifier[cnt]=cgiQueryString[j];
 	    cIdentifier[cnt+1]=0;
@@ -2009,5 +2091,4 @@
 	  }
 	  char tmps1[1024];
-
 	  map* import = getMapFromMaps (m, IMPORTSERVICE, cIdentifier); 
 	  if (import != NULL && import->value != NULL) { 
@@ -2023,4 +2104,5 @@
 	    if (strstr (cIdentifier, ".") != NULL)
 	      {
+		setMapInMaps (m, "lenv", "oIdentifier", cIdentifier);
 		char *identifier = zStrdup (cIdentifier);
 		parseIdentifier (m, ntmp, identifier, tmps1);
@@ -2071,5 +2153,5 @@
 		map* error=createMap("code","InternalError");
 		addToMap(error,"message",_("Unable to allocate memory"));
-		//setMapInMaps(conf,"lenv","status_code","404 Bad Request");
+		setMapInMaps(m,"lenv","status_code","404 Bad Request");
 		printExceptionReportResponseJ(m,error);
 
@@ -2091,49 +2173,166 @@
 	      free(zooRegistry);
 	    }
+	    fflush(stderr);
 	    fflush (stdout);
 	    zDup2 (saved_stdout, fileno (stdout));
+	    zClose (saved_stdout);
 	    if (t < 0)
 	      {
-		char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
-		sprintf (tmpMsg,
-			 _
-			 ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
-			 r_inputs->value);
-		map* error=createMap("code","InvalidParameterValue");
-		addToMap(error,"message",tmpMsg);
-		//setMapInMaps(conf,"lenv","status_code","404 Bad Request");
-		printExceptionReportResponseJ(m,error);
-
-		//errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
-		free (tmpMsg);
-		free (s1);
-		freeMaps (&m);
-		free (m);
-		free (REQUEST);
-		free (SERVICE_URL);
-		return 0;
+		r_inputs = getMapFromMaps (m, "lenv", "oIdentifier");
+		if(r_inputs!=NULL){
+		  char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
+		  sprintf (tmpMsg,
+			   _
+			   ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
+			   r_inputs->value);
+		  map* error=createMap("code","NoSuchProcess");
+		  addToMap(error,"message",tmpMsg);
+		  //setMapInMaps(conf,"lenv","status_code","404 Bad Request");
+		  printExceptionReportResponseJ(m,error);
+
+		  //errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
+		  free (tmpMsg);
+		  free (s1);
+		  freeMaps (&m);
+		  free (m);
+		  free (REQUEST);
+		  free (SERVICE_URL);
+		  return 0;
+		}
 	      }
-	    zClose (saved_stdout);
-	  
 #ifdef META_DB
 	  }
 #endif
-	  if(strstr(cgiQueryString,"/jobs/")!=NULL && strlen(strstr(cgiQueryString,"/jobs/"))>6){
+	  if(strstr(cgiQueryString,"/jobs/")!=NULL && strlen(strstr(cgiQueryString,"/jobs/"))>6) {
 	    /* - /jobs/{jobID} and /jobs/{jobID}/result urls */
-	    if(strstr(cgiQueryString,"/result")!=NULL && strlen(strstr(cgiQueryString,"/result"))>=7){
-	      fprintf(stderr,"For GetResult %s %d \n",__FILE__,__LINE__);
+	    if(strstr(cgiQueryString,"/results")!=NULL){
+	      // In case the service has run, then forward request to target result file
+	      char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
+	      jobId[strlen(jobId)-8]=0;
+	      char *sid=getStatusId(m,jobId);
+	      if(sid==NULL){
+		map* error=createMap("code","NoSuchJob");
+		addToMap(error,"message",_("The JobID from the request does not match any of the Jobs running on this server"));
+		printExceptionReportResponseJ(m,error);
+		return 1;
+	      }else{
+		if(isRunning(m,jobId)>0){
+		  map* error=createMap("code","ResultNotReady");
+		  addToMap(error,"message",_("The job is still running."));
+		  printExceptionReportResponseJ(m,error);
+		  return 1;
+		}else{
+		  char *Url0=getResultPath(m,jobId);
+		  map *cIdentifier = getMapFromMaps (m, "lenv", "oIdentifier");
+		  zStatStruct f_status;
+		  int s=zStat(Url0, &f_status);
+		  if(s==0 && f_status.st_size>0){
+		    if(f_status.st_size>15){
+		      json_object* pjoTmp=json_readFile(m,Url0);
+		      json_object* pjoCode=NULL;
+		      json_object* pjoMessage=NULL;
+		      if(pjoTmp!=NULL &&
+			 json_object_object_get_ex(pjoTmp,"code",&pjoCode)!=FALSE &&
+			 json_object_object_get_ex(pjoTmp,"description",&pjoMessage)!=FALSE){
+			map* error=createMap("code",json_object_get_string(pjoCode));
+			addToMap(error,"message",json_object_get_string(pjoMessage));
+			printExceptionReportResponseJ(m,error);
+			return 1;			
+		      }else{
+
+			map* tmpPath = getMapFromMaps (m, "main", "tmpUrl");
+			Url0=(char*) realloc(Url0,(strlen(tmpPath->value)+
+						   strlen(cIdentifier->value)+
+						   strlen(jobId)+8)*sizeof(char));
+			sprintf(Url0,"%s/%s_%s.json",tmpPath->value,
+				cIdentifier->value,jobId);
+			setMapInMaps(m,"headers","Location",Url0);
+		      }
+		      free(Url0);
+		    }else{
+		      // Service Failed
+		      map* statusInfo=createMap("JobID",jobId);
+		      readFinalRes(m,jobId,statusInfo);
+		      {
+			map* pmStatus=getMap(statusInfo,"status");
+			if(pmStatus!=NULL)
+			  setMapInMaps(m,"lenv","status",pmStatus->value);
+		      }
+		      char* tmpStr=_getStatus(m,jobId);
+		      if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
+			char *tmpStr1=zStrdup(tmpStr);
+			char *tmpStr0=zStrdup(strstr(tmpStr,"|")+1);
+			free(tmpStr);
+			tmpStr1[strlen(tmpStr1)-strlen(tmpStr0)-1]='\0';
+			addToMap(statusInfo,"PercentCompleted",tmpStr1);
+			addToMap(statusInfo,"Message",tmpStr0);
+			setMapInMaps(m,"lenv","PercentCompleted",tmpStr1);
+			setMapInMaps(m,"lenv","Message",tmpStr0);
+			free(tmpStr0);
+			free(tmpStr1);
+		      }
+		      map* error=createMap("code","NoApplicableCode");
+		      addToMap(error,"message",_("The service failed to execute."));
+		      printExceptionReportResponseJ(m,error);
+		      return 1;
+		    }
+
+		  }else{
+		    map* error=createMap("code","NoSuchJob");
+		    addToMap(error,"message",_("The JobID seem to be running on this server but not for this process id"));
+		    printExceptionReportResponseJ(m,error);
+		    return 1;
+		  }
+		}
+	      }
 	    }else{
 	      char* tmpUrl=strstr(cgiQueryString,"/jobs/");
 	      if(tmpUrl!=NULL && strlen(tmpUrl)>6){
-		char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
-		setMapInMaps(m,"lenv","gs_usid",jobId);
-		json_getStatusFile(m);
-		free(jobId);
-		return 1;	      
+		if(strncasecmp(cgiRequestMethod,"DELETE",6)==0){
+		  char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
+		  setMapInMaps(m,"lenv","gs_usid",jobId);
+		  setMapInMaps(m,"lenv","file.statusFile",json_getStatusFilePath(m));
+		  runDismiss(m,jobId);
+		  map* pmError=getMapFromMaps(m,"lenv","error");
+		  if(pmError!=NULL && strncasecmp(pmError->value,"true",4)==0){
+		    printExceptionReportResponseJ(m,getMapFromMaps(m,"lenv","code"));
+		    return 1;
+		  }
+		  else{
+		    setMapInMaps(m,"lenv","gs_location","false");
+		    res=createStatus(m,SERVICE_DISMISSED);
+		  }
+		}else{
+		  char* jobId=zStrdup(strstr(cgiQueryString,"/jobs/")+6);
+		  runGetStatus(m,jobId,"GetStatus");
+		  map* pmError=getMapFromMaps(m,"lenv","error");
+		  if(pmError!=NULL && strncasecmp(pmError->value,"true",4)==0){
+		    printExceptionReportResponseJ(m,getMapFromMaps(m,"lenv","code"));
+		    return 1;
+		  }else{
+		    map* pmStatus=getMapFromMaps(m,"lenv","status");
+		    setMapInMaps(m,"lenv","gs_location","false");
+		    setMapInMaps(m,"lenv","gs_usid",jobId);
+		    if(pmStatus!=NULL && strncasecmp(pmStatus->value,"Failed",6)==0)
+		      res=createStatus(m,SERVICE_FAILED);
+		    else
+		      if(pmStatus!=NULL  && strncasecmp(pmStatus->value,"Succeeded",9)==0)
+			res=createStatus(m,SERVICE_SUCCEEDED);
+		      else
+			if(pmStatus!=NULL  && strncasecmp(pmStatus->value,"Running",7)==0){
+			  map* tmpMap=getMapFromMaps(m,"lenv","Message");
+			  if(tmpMap!=NULL)
+			    setMapInMaps(m,"lenv","gs_message",tmpMap->value);
+			  res=createStatus(m,SERVICE_STARTED);
+			}
+			else
+			  res=createStatus(m,SERVICE_FAILED);
+		  }
+		  free(jobId);
+		}
 	      }
 	    }
 	  }else{
 	    /* - /jobs url */
-	    fprintf(stderr,"For Execute or Job list %s %d \n",__FILE__,__LINE__);
 	    if(strcasecmp(cgiRequestMethod,"get")==0){
 	      /* - /jobs List (GET) */
@@ -2141,6 +2340,5 @@
 	    }else if(strcasecmp(cgiRequestMethod,"post")==0){
 	      /* - /jobs Execution (POST) */
-	      int eres = SERVICE_STARTED;
-
+	      eres = SERVICE_STARTED;
 	      initAllEnvironment(m,request_inputs,ntmp,"jrequest");
 	      map* req=getMapFromMaps(m,"renv","jrequest");
@@ -2156,19 +2354,31 @@
 	      } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
 	      if (jerr != json_tokener_success) {
+		map* pamError=createMap("code","InvalidParameterValue");
+		const char* pcTmpErr=json_tokener_error_desc(jerr);
+		const char* pccErr=_("ZOO-Kernel cannot parse your POST data: %s");
+		char* pacMessage=(char*)malloc((strlen(pcTmpErr)+strlen(pccErr)+1)*sizeof(char));
+		sprintf(pacMessage,pccErr,pcTmpErr);
+		addToMap(pamError,"message",pacMessage);
+		printExceptionReportResponseJ(m,pamError);
 		fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
 		return 1;
 	      }
 	      if (tok->char_offset < slen){
+		map* pamError=createMap("code","InvalidParameterValue");
+		const char* pcTmpErr="None";
+		const char* pccErr=_("ZOO-Kernel cannot parse your POST data: %s");
+		char* pacMessage=(char*)malloc((strlen(pcTmpErr)+strlen(pccErr)+1)*sizeof(char));
+		sprintf(pacMessage,pccErr,pcTmpErr);
+		addToMap(pamError,"message",pacMessage);
+		printExceptionReportResponseJ(m,pamError);
+		fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
 		return 1;
 	      }
-	      fprintf(stderr,"%s %d \n",__FILE__,__LINE__);
-	      // Success, use jobj here.
-	      maps* inputs_real_format=NULL, *outputs_real_format= NULL;
-	      parseJRequest(m,s1,jobj,&inputs_real_format,&outputs_real_format);
+	      //maps* inputs_real_format=NULL, *outputs_real_format= NULL;
+	      parseJRequest(m,s1,jobj,request_inputs,&request_input_real_format,&request_output_real_format);
 	      map* preference=getMapFromMaps(m,"renv","HTTP_PREFER");
-	      if(preference!=NULL && strcasecmp(preference->value,"respond-async")==0){
-		fprintf(stderr,"Asynchronous call!\n");
-		char *fbkp, *fbkpid, *fbkpres, *fbkp1, *flog;
-		FILE *f0, *f1;
+	      map* mode=getMap(request_inputs,"mode");
+	      if((preference!=NULL && strcasecmp(preference->value,"respond-async")==0) ||
+		 (mode!=NULL && strncasecmp(mode->value,"async",5)==0)) {
 		int pid;
 #ifdef DEBUG
@@ -2204,4 +2414,5 @@
 		    eres = SERVICE_ACCEPTED;
 		    createStatusFile(m,eres);
+		    //invokeBasicCallback(m,SERVICE_ACCEPTED);
 		    printHeaders(m);
 		    printf("Status: 201 Created \r\n\r\n");
@@ -2215,4 +2426,5 @@
 		    // process answer to http client.
 		    //
+		    map* oid = getMapFromMaps (m, "lenv", "oIdentifier");
 		    map* usid = getMapFromMaps (m, "lenv", "uusid");
 		    map* tmpm = getMapFromMaps (m, "lenv", "osid");
@@ -2228,5 +2440,5 @@
 			       strlen (usid->value) + 7) * sizeof (char));                    
 		    sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
-		    maps* bmap = createMaps("status");
+		    bmap = createMaps("status");
 		    bmap->content=createMap("usid",usid->value);
 		    addToMap(bmap->content,"sid",tmpm->value);
@@ -2248,5 +2460,5 @@
 		    fbkp =
 		      (char *)
-		      malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+		      malloc ((strlen (r_inputs->value) + strlen (oid->value) +
 			       strlen (usid->value) + 7) * sizeof (char));
 		    sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
@@ -2259,15 +2471,15 @@
 		    fbkp =
 		      (char *)
-		      malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+		      malloc ((strlen (r_inputs->value) + strlen (oid->value) +
 			       strlen (usid->value) + 7) * sizeof (char));
-		    sprintf (fbkp, "%s/%s_%s.xml", r_inputs->value, r_inputs1->value,
+		    sprintf (fbkp, "%s/%s_%s.json", r_inputs->value, oid->value,
 			     usid->value);
 		    setMapInMaps (m, "lenv", "file.responseInit", fbkp);
 		    flog =
 		      (char *)
-		      malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+		      malloc ((strlen (r_inputs->value) + strlen (oid->value) +
 			       strlen (usid->value) + 13) * sizeof (char));
 		    sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
-			     r_inputs1->value, usid->value);
+			     oid->value, usid->value);
 		    setMapInMaps (m, "lenv", "file.log", flog);
 #ifdef DEBUG
@@ -2291,16 +2503,12 @@
 		    invokeCallback(m,NULL,NULL,0,0);
 #endif
-		    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
-		    fflush(stderr);
-		    
-		    createStatusFile(m,eres);
-		    	  
-		  
+		    invokeBasicCallback(m,SERVICE_STARTED);
+		    createStatusFile(m,SERVICE_STARTED);
 		    fbkp1 =
 		      (char *)
-		      malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+		      malloc ((strlen (r_inputs->value) + strlen (oid->value) +
 			       strlen (usid->value) + 15) * sizeof (char));
 		    sprintf (fbkp1, "%s/%s_final_%s.json", r_inputs->value,
-			     r_inputs1->value, usid->value);
+			     oid->value, usid->value);
 		    setMapInMaps (m, "lenv", "file.responseFinal", fbkp1);
 
@@ -2317,32 +2525,31 @@
 		    sprintf (flenv, "%s/%s_lenv.cfg", r_inputs->value, usid->value);
 		    maps* lenvMaps=getMaps(m,"lenv");
-		    dumpMapsToFile(lenvMaps,flenv,0);
+		    dumpMapsToFile(lenvMaps,flenv,1);
 		    free(flenv);
 
 		    map* testMap=getMapFromMaps(m,"main","memory");
-		    loadHttpRequests(m,inputs_real_format);
+		    loadHttpRequests(m,request_input_real_format);
+		    dumpMaps(request_input_real_format);
 		    loadServiceAndRun (&m, s1, request_inputs,
-				       &inputs_real_format,
-				       &outputs_real_format, &eres);
+				       &request_input_real_format,
+				       &request_output_real_format, &eres);
+		    setMapInMaps(m,"lenv","force","true");
 		    createStatusFile(m,eres);
-		    res=printJResult(m,s1,outputs_real_format,eres);
-		    char tmpUrl0[1024];
-		    const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
-		    printf(jsonStr);
-		    printf("\n");
-		    return 1;
-
+		    setMapInMaps(m,"lenv","force","false");
+		    setMapInMaps(m,"lenv","no-headers","true");
+		    fflush(stdout);
+		    rewind(stdout);
+		    res=printJResult(m,s1,request_output_real_format,eres);
+		    const char* jsonStr0=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
+		    if(getMapFromMaps(m,"lenv","jsonStr")==NULL)
+		      setMapInMaps(m,"lenv","jsonStr",jsonStr0);
+		    invokeBasicCallback(m,eres);
 		  }
 	      }else{
-		loadHttpRequests(m,inputs_real_format);
-		loadServiceAndRun (&m,s1,request_inputs,&inputs_real_format,&outputs_real_format,&eres);
-		res=printJResult(m,s1,outputs_real_format,eres);
-	      
-		printHeaders(m);
-		printf("Status: 201 Created \r\n\r\n");
-		const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
-		printf(jsonStr);
-		printf("\n");
-		return 1;
+		loadHttpRequests(m,request_input_real_format);
+		loadServiceAndRun (&m,s1,request_inputs,
+				   &request_input_real_format,
+				   &request_output_real_format,&eres);
+		res=printJResult(m,s1,request_output_real_format,eres);
 	      }
 
@@ -2353,184 +2560,358 @@
 	}
     }
-    printHeaders(m);
-    printf("Status: 200 OK \r\n\r\n");
-    const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
-    printf(jsonStr);
-    printf("\n");
-    return 1;
-#endif
-  }
-
-  //
-  // WPS 1.0.0 and 2.0.0 starts here
-  //
-  //Check for minimum inputs
-  map* version=getMap(request_inputs,"version");
-  if(version==NULL)
-    version=getMapFromMaps(m,"main","version");
-  setMapInMaps(m,"main","rversion",version->value);
-  int vid=getVersionId(version->value);
-  if(vid<0)
-    vid=0;
-  map* err=NULL;
-  const char **vvr=(const char**)requests[vid];
-  checkValidValue(request_inputs,&err,"request",vvr,1);
-  const char *vvs[]={
-    "WPS",
-    NULL
-  };
-  if(err!=NULL){
+    if(res!=NULL){
+      if(getMapFromMaps(m,"lenv","no-headers")==NULL){
+	printHeaders(m);
+	printf("Status: 200 OK \r\n\r\n");
+      }
+      const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
+      printf(jsonStr);
+      printf("\n");
+      fflush(stdout);
+    }
+    //return 1;
+#endif
+  }else{
+
+    //
+    // WPS 1.0.0 and 2.0.0 starts here
+    //
+    //Check for minimum inputs
+    map* version=getMap(request_inputs,"version");
+    if(version==NULL)
+      version=getMapFromMaps(m,"main","version");
+    setMapInMaps(m,"main","rversion",version->value);
+    int vid=getVersionId(version->value);
+    if(vid<0)
+      vid=0;
+    map* err=NULL;
+    const char **vvr=(const char**)requests[vid];
+    checkValidValue(request_inputs,&err,"request",vvr,1);
+    const char *vvs[]={
+      "WPS",
+      NULL
+    };
+    if(err!=NULL){
+      checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
+      printExceptionReportResponse (m, err);
+      freeMap(&err);
+      free(err);
+      if (count (request_inputs) == 1)
+	{
+	  freeMap (&request_inputs);
+	  free (request_inputs);
+	}
+      freeMaps (&m);
+      free (m);
+      return 1;
+    }
     checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
-    printExceptionReportResponse (m, err);
-    freeMap(&err);
-    free(err);
-    if (count (request_inputs) == 1)
-      {
-	freeMap (&request_inputs);
-	free (request_inputs);
-      }
-    freeMaps (&m);
-    free (m);
-    return 1;
-  }
-  checkValidValue(request_inputs,&err,"service",(const char**)vvs,1);
-
-  const char *vvv[]={
-    "1.0.0",
-    "2.0.0",
-    NULL
-  };
-  r_inputs = getMap (request_inputs, "Request");
-  if(r_inputs!=NULL)
-    REQUEST = zStrdup (r_inputs->value);
-  int reqId=-1;
-  if (strncasecmp (REQUEST, "GetCapabilities", 15) != 0){
-    checkValidValue(request_inputs,&err,"version",(const char**)vvv,1);
-    int j=0;
-    for(j=0;j<nbSupportedRequests;j++){
-      if(requests[vid][j]!=NULL && requests[vid][j+1]!=NULL){
-	if(j<nbReqIdentifier && strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
-	  checkValidValue(request_inputs,&err,"identifier",NULL,1);
-	  reqId=j+1;
-	  break;
-	}
-	else
-	  if(j>=nbReqIdentifier && j<nbReqIdentifier+nbReqJob && 
-	     strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
-	    checkValidValue(request_inputs,&err,"jobid",NULL,1);
+
+    const char *vvv[]={
+      "1.0.0",
+      "2.0.0",
+      NULL
+    };
+    r_inputs = getMap (request_inputs, "Request");
+    if(r_inputs!=NULL)
+      REQUEST = zStrdup (r_inputs->value);
+    int reqId=-1;
+    if (strncasecmp (REQUEST, "GetCapabilities", 15) != 0){
+      checkValidValue(request_inputs,&err,"version",(const char**)vvv,1);
+      int j=0;
+      for(j=0;j<nbSupportedRequests;j++){
+	if(requests[vid][j]!=NULL && requests[vid][j+1]!=NULL){
+	  if(j<nbReqIdentifier && strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
+	    checkValidValue(request_inputs,&err,"identifier",NULL,1);
 	    reqId=j+1;
 	    break;
 	  }
-      }else
-	break;
-    }
-  }else{
-    checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
-    map* version1=getMap(request_inputs,"AcceptVersions");
-    if(version1!=NULL){
-      if(strstr(version1->value,schemas[1][0])!=NULL){
-	addToMap(request_inputs,"version",schemas[1][0]);
-	setMapInMaps(m,"main","rversion",schemas[1][0]);
+	  else
+	    if(j>=nbReqIdentifier && j<nbReqIdentifier+nbReqJob && 
+	       strncasecmp(REQUEST,requests[vid][j+1],strlen(requests[vid][j+1]))==0){
+	      checkValidValue(request_inputs,&err,"jobid",NULL,1);
+	      reqId=j+1;
+	      break;
+	    }
+	}else
+	  break;
       }
-      else{
-	addToMap(request_inputs,"version",version1->value);
-	setMapInMaps(m,"main","rversion",version1->value);
+    }else{
+      checkValidValue(request_inputs,&err,"AcceptVersions",(const char**)vvv,-1);
+      map* version1=getMap(request_inputs,"AcceptVersions");
+      if(version1!=NULL){
+	if(strstr(version1->value,schemas[1][0])!=NULL){
+	  addToMap(request_inputs,"version",schemas[1][0]);
+	  setMapInMaps(m,"main","rversion",schemas[1][0]);
+	}
+	else{
+	  addToMap(request_inputs,"version",version1->value);
+	  setMapInMaps(m,"main","rversion",version1->value);
+	}
+	version=getMap(request_inputs,"version");
       }
-      version=getMap(request_inputs,"version");
-    }
-  }
-  if(err!=NULL){
-    printExceptionReportResponse (m, err);
-    freeMap(&err);
-    free(err);
-    if (count (request_inputs) == 1)
+    }
+    if(err!=NULL){
+      printExceptionReportResponse (m, err);
+      freeMap(&err);
+      free(err);
+      if (count (request_inputs) == 1)
+	{
+	  freeMap (&request_inputs);
+	  free (request_inputs);
+	}
+      free(REQUEST);
+      freeMaps (&m);
+      free (m);
+      return 1;
+    }
+
+    r_inputs = getMap (request_inputs, "serviceprovider");
+    if (r_inputs == NULL)
       {
-	freeMap (&request_inputs);
-	free (request_inputs);
+	addToMap (request_inputs, "serviceprovider", "");
       }
-    free(REQUEST);
-    freeMaps (&m);
-    free (m);
-    return 1;
-  }
-
-  r_inputs = getMap (request_inputs, "serviceprovider");
-  if (r_inputs == NULL)
-    {
-      addToMap (request_inputs, "serviceprovider", "");
-    }
-
-  maps *request_output_real_format = NULL;
-  map *tmpm = getMapFromMaps (m, "main", "serverAddress");
-  if (tmpm != NULL)
-    SERVICE_URL = zStrdup (tmpm->value);
-  else
-    SERVICE_URL = zStrdup (DEFAULT_SERVICE_URL);
-
-
-
-  service *s1;
-  int scount = 0;
-#ifdef DEBUG
-  dumpMap (r_inputs);
-#endif
-
-  if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
-    {
-#ifdef DEBUG
-      dumpMap (r_inputs);
-#endif
-      xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
-      xmlNodePtr n=printGetCapabilitiesHeader(doc,m,(version!=NULL?version->value:"1.0.0"));
-      /**
-       * Here we need to close stdout to ensure that unsupported chars 
-       * has been found in the zcfg and then printed on stdout
-       */
-      int saved_stdout = zDup (fileno (stdout));
-      zDup2 (fileno (stderr), fileno (stdout));
-
-      maps* imports = getMaps(m, IMPORTSERVICE);
-      if (imports != NULL) {       
-        map* zcfg = imports->content;
+
+    map *tmpm = getMapFromMaps (m, "main", "serverAddress");
+    if (tmpm != NULL)
+      SERVICE_URL = zStrdup (tmpm->value);
+    else
+      SERVICE_URL = zStrdup (DEFAULT_SERVICE_URL);
+
+
+    int scount = 0;
+#ifdef DEBUG
+    dumpMap (r_inputs);
+#endif
+
+    if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
+      {
+#ifdef DEBUG
+	dumpMap (r_inputs);
+#endif
+	xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
+	xmlNodePtr n=printGetCapabilitiesHeader(doc,m,(version!=NULL?version->value:"1.0.0"));
+	/**
+	 * Here we need to close stdout to ensure that unsupported chars 
+	 * has been found in the zcfg and then printed on stdout
+	 */
+	int saved_stdout = zDup (fileno (stdout));
+	zDup2 (fileno (stderr), fileno (stdout));
+
+	maps* imports = getMaps(m, IMPORTSERVICE);
+	if (imports != NULL) {       
+	  map* zcfg = imports->content;
         
-        while (zcfg != NULL) {
-	  if (zcfg->value != NULL) {
-	    service* svc = (service*) malloc(SERVICE_SIZE);
-	    if (svc == NULL || readServiceFile(m, zcfg->value, &svc, zcfg->name) < 0) {
-	      // pass over silently
-	      zcfg = zcfg->next;
-	      continue;
+	  while (zcfg != NULL) {
+	    if (zcfg->value != NULL) {
+	      service* svc = (service*) malloc(SERVICE_SIZE);
+	      if (svc == NULL || readServiceFile(m, zcfg->value, &svc, zcfg->name) < 0) {
+		// pass over silently
+		zcfg = zcfg->next;
+		continue;
+	      }
+	      inheritance(zooRegistry, &svc);
+	      printGetCapabilitiesForProcess(zooRegistry, m, doc, n, svc);
+	      freeService(&svc);
+	      free(svc);                             
 	    }
-	    inheritance(zooRegistry, &svc);
-	    printGetCapabilitiesForProcess(zooRegistry, m, doc, n, svc);
-	    freeService(&svc);
-	    free(svc);                             
+	    zcfg = zcfg->next;
+	  }            
+	}
+
+	if (int res =		  
+	    recursReaddirF (m, zooRegistry, doc, n, conf_dir, NULL, saved_stdout, 0,
+			    printGetCapabilitiesForProcess) < 0)
+	  {
+	    freeMaps (&m);
+	    free (m);
+	    if(zooRegistry!=NULL){
+	      freeRegistry(&zooRegistry);
+	      free(zooRegistry);
+	    }
+	    free (REQUEST);
+	    free (SERVICE_URL);
+	    fflush (stdout);
+	    return res;
 	  }
-	  zcfg = zcfg->next;
-        }            
+	fflush (stdout);
+	zDup2 (saved_stdout, fileno (stdout));
+#ifdef META_DB
+	fetchServicesFromDb(zooRegistry,m,doc,n,printGetCapabilitiesForProcess,1);
+	close_sql(m,0);
+#endif      
+	printDocument (m, doc, zGetpid ());
+	freeMaps (&m);
+	free (m);
+	if(zooRegistry!=NULL){
+	  freeRegistry(&zooRegistry);
+	  free(zooRegistry);
+	}
+	free (REQUEST);
+	free (SERVICE_URL);
+	fflush (stdout);
+	return 0;
       }
-
-      if (int res =		  
-          recursReaddirF (m, zooRegistry, doc, n, conf_dir, NULL, saved_stdout, 0,
-                          printGetCapabilitiesForProcess) < 0)
-        {
-          freeMaps (&m);
-          free (m);
-	  if(zooRegistry!=NULL){
-	    freeRegistry(&zooRegistry);
-	    free(zooRegistry);
+    else
+      {
+	r_inputs = getMap (request_inputs, "JobId");
+	if(reqId>nbReqIdentifier){
+	  if (strncasecmp (REQUEST, "GetStatus", 9) == 0 ||
+	      strncasecmp (REQUEST, "GetResult", 9) == 0){
+	    runGetStatus(m,r_inputs->value,REQUEST);
+#ifdef RELY_ON_DB
+	    map* dsNb=getMapFromMaps(m,"lenv","ds_nb");
+	    if(dsNb!=NULL && atoi(dsNb->value)>1)
+	      close_sql(m,1);
+	    close_sql(m,0);
+#endif
+	  
+	    freeMaps (&m);
+	    free(m);
+	    if(zooRegistry!=NULL){
+	      freeRegistry(&zooRegistry);
+	      free(zooRegistry);
+	    }
+	    free (REQUEST);
+	    free (SERVICE_URL);
+	    return 0;
 	  }
-          free (REQUEST);
-          free (SERVICE_URL);
-          fflush (stdout);
-          return res;
-        }
-      fflush (stdout);
-      zDup2 (saved_stdout, fileno (stdout));
+	  else
+	    if (strncasecmp (REQUEST, "Dismiss", strlen(REQUEST)) == 0){
+	      runDismiss(m,r_inputs->value);
+	      freeMaps (&m);
+	      free (m);
+	      if(zooRegistry!=NULL){
+		freeRegistry(&zooRegistry);
+		free(zooRegistry);
+	      }
+	      free (REQUEST);
+	      free (SERVICE_URL);
+	      return 0;
+	    
+	    }
+	  return 0;
+	}
+	if(reqId<=nbReqIdentifier){
+	  r_inputs = getMap (request_inputs, "Identifier");
+
+	  struct dirent *dp;
+	  DIR *dirp = opendir (conf_dir);
+	  if (dirp == NULL)
+	    {
+	      errorException (m, _("The specified path does not exist."),
+			      "InternalError", NULL);
+	      freeMaps (&m);
+	      free (m);
+	      if(zooRegistry!=NULL){
+		freeRegistry(&zooRegistry);
+		free(zooRegistry);
+	      }
+	      free (REQUEST);
+	      free (SERVICE_URL);
+	      return 0;
+	    }
+	  if (strncasecmp (REQUEST, "DescribeProcess", 15) == 0)
+	    {
+	      /**
+	       * Loop over Identifier list
+	       */
+	      xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
+	      r_inputs = NULL;
+	      r_inputs = getMap (request_inputs, "version");
+#ifdef DEBUG
+	      fprintf(stderr," ** DEBUG %s %d \n",__FILE__,__LINE__);
+	      fflush(stderr);
+#endif
+	      xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
+					    root_nodes[vid][1],(version!=NULL?version->value:"1.0.0"),1);
+
+	      r_inputs = getMap (request_inputs, "Identifier");
+
+	      fetchServicesForDescription(zooRegistry, m, r_inputs->value,
+					  printDescribeProcessForProcess,
+					  (void*) doc, (void*) n, conf_dir,
+					  request_inputs,printExceptionReportResponse);
+
+	      printDocument (m, doc, zGetpid ());
+	      freeMaps (&m);
+	      free (m);
+	      if(zooRegistry!=NULL){
+		freeRegistry(&zooRegistry);
+		free(zooRegistry);
+	      }
+	      free (REQUEST);
+	      free (SERVICE_URL);
+	      fflush (stdout);
 #ifdef META_DB
-      fetchServicesFromDb(zooRegistry,m,doc,n,printGetCapabilitiesForProcess,1);
-      close_sql(m,0);
-#endif      
-      printDocument (m, doc, zGetpid ());
+	      close_sql(m,0);
+	      //end_sql();
+#endif
+	      return 0;
+	    }
+	  else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
+	    {
+	      map* version=getMapFromMaps(m,"main","rversion");
+	      int vid=getVersionId(version->value);	    
+	      int len = 0;
+	      int j = 0;
+	      for(j=0;j<nbSupportedRequests;j++){
+		if(requests[vid][j]!=NULL)
+		  len+=strlen(requests[vid][j])+2;
+		else{
+		  len+=4;
+		  break;
+		}
+	      }
+	      char *tmpStr=(char*)malloc(len*sizeof(char));
+	      int it=0;
+	      for(j=0;j<nbSupportedRequests;j++){
+		if(requests[vid][j]!=NULL){
+		  if(it==0){
+		    sprintf(tmpStr,"%s",requests[vid][j]);
+		    it++;
+		  }else{
+		    char *tmpS=zStrdup(tmpStr);
+		    if(j+1<nbSupportedRequests && requests[vid][j+1]==NULL){
+		      sprintf(tmpStr,"%s and %s",tmpS,requests[vid][j]);
+		    }else{
+		      sprintf(tmpStr,"%s, %s",tmpS,requests[vid][j]);
+		  
+		    }
+		    free(tmpS);
+		  }
+		}
+		else{
+		  len+=4;
+		  break;
+		}
+	      }
+	      char* message=(char*)malloc((61+len)*sizeof(char));
+	      sprintf(message,"The <request> value was not recognized. Allowed values are %s.",tmpStr);
+	      errorException (m,_(message),"InvalidParameterValue", "request");
+#ifdef DEBUG
+	      fprintf (stderr, "No request found %s", REQUEST);
+#endif
+	      closedir (dirp);
+	      freeMaps (&m);
+	      free (m);
+	      if(zooRegistry!=NULL){
+		freeRegistry(&zooRegistry);
+		free(zooRegistry);
+	      }
+	      free (REQUEST);
+	      free (SERVICE_URL);
+	      fflush (stdout);
+	      return 0;
+	    }
+	  closedir (dirp);
+	}
+      }
+
+    map *postRequest = NULL;
+    postRequest = getMap (request_inputs, "xrequest");
+  
+    if(vid==1 && postRequest==NULL){
+      errorException (m,_("Unable to run Execute request using the GET HTTP method"),"InvalidParameterValue", "request");  
       freeMaps (&m);
       free (m);
@@ -2544,20 +2925,61 @@
       return 0;
     }
-  else
-    {
-      r_inputs = getMap (request_inputs, "JobId");
-      if(reqId>nbReqIdentifier){
-	if (strncasecmp (REQUEST, "GetStatus", 9) == 0 ||
-	    strncasecmp (REQUEST, "GetResult", 9) == 0){
-	  runGetStatus(m,r_inputs->value,REQUEST);
-#ifdef RELY_ON_DB
-	  map* dsNb=getMapFromMaps(m,"lenv","ds_nb");
-	  if(dsNb!=NULL && atoi(dsNb->value)>1)
-	    close_sql(m,1);
-	  close_sql(m,0);
-#endif
-	  
+    s1 = NULL;
+ 
+    r_inputs = getMap (request_inputs, "Identifier");
+    map* import = getMapFromMaps (m, IMPORTSERVICE, r_inputs->value); 
+    if (import != NULL && import->value != NULL) { 
+      strncpy(tmps1, import->value, 1024);
+      setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
+      setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
+    } 
+    else {
+      snprintf (tmps1, 1024, "%s/%s.zcfg", conf_dir, r_inputs->value);
+#ifdef DEBUG
+      fprintf (stderr, "Trying to load %s\n", tmps1);
+#endif
+      if (strstr (r_inputs->value, ".") != NULL)
+	{
+	  char *identifier = zStrdup (r_inputs->value);
+	  parseIdentifier (m, conf_dir, identifier, tmps1);
+	  map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
+	  if (tmpMap != NULL)
+	    addToMap (request_inputs, "metapath", tmpMap->value);
+	  free (identifier);
+	}
+      else
+	{
+	  setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
+	  setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
+	}
+    }
+
+    r_inputs = getMapFromMaps (m, "lenv", "Identifier");
+  
+#ifdef META_DB
+    int metadb_id=_init_sql(m,"metadb");
+    //FAILED CONNECTING DB
+    if(getMapFromMaps(m,"lenv","dbIssue")!=NULL || metadb_id<0){
+      fprintf(stderr,"ERROR CONNECTING METADB\n");
+    }
+    if(metadb_id>=0)
+      s1=extractServiceFromDb(m,r_inputs->value,0);
+    //close_sql(m,0);
+    if(s1!=NULL){
+      inheritance(zooRegistry,&s1);
+#ifdef USE_HPC
+      addNestedOutputs(&s1);
+#endif
+      if(zooRegistry!=NULL){
+	freeRegistry(&zooRegistry);
+	free(zooRegistry);
+      }
+    }else /* Not found in MetaDB */{
+#endif
+      s1 = createService();
+      if (s1 == NULL)
+	{
 	  freeMaps (&m);
-	  free(m);
+	  free (m);
 	  if(zooRegistry!=NULL){
 	    freeRegistry(&zooRegistry);
@@ -2566,9 +2988,132 @@
 	  free (REQUEST);
 	  free (SERVICE_URL);
+	  return errorException (m, _("Unable to allocate memory"),
+				 "InternalError", NULL);
+	}
+
+      int saved_stdout = zDup (fileno (stdout));
+      zDup2 (fileno (stderr), fileno (stdout));
+      t = readServiceFile (m, tmps1, &s1, r_inputs->value);
+      if(t>=0){
+	inheritance(zooRegistry,&s1);
+#ifdef USE_HPC
+	addNestedOutputs(&s1);
+#endif
+      }
+      if(zooRegistry!=NULL){
+	freeRegistry(&zooRegistry);
+	free(zooRegistry);
+      }
+      fflush (stdout);
+      zDup2 (saved_stdout, fileno (stdout));
+      if (t < 0)
+	{
+	  char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
+	  sprintf (tmpMsg,
+		   _
+		   ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
+		   r_inputs->value);
+	  errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
+	  free (tmpMsg);
+	  free (s1);
+	  freeMaps (&m);
+	  free (m);
+	  free (REQUEST);
+	  free (SERVICE_URL);
 	  return 0;
 	}
-	else
-	  if (strncasecmp (REQUEST, "Dismiss", strlen(REQUEST)) == 0){
-	    runDismiss(m,r_inputs->value);
+      zClose (saved_stdout);
+#ifdef META_DB
+    }
+#endif
+  
+#ifdef DEBUG
+    dumpService (s1);
+#endif
+    int j;
+
+
+    /**
+     * Create the input and output maps data structure
+     */
+    int i = 0;
+    HINTERNET res;
+    hInternet = InternetOpen (
+#ifndef WIN32
+			      (LPCTSTR)
+#endif
+			      "ZooWPSClient\0",
+			      INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
+
+#ifndef WIN32
+    if (!CHECK_INET_HANDLE (hInternet))
+      fprintf (stderr, "WARNING : hInternet handle failed to initialize");
+#endif
+    maps *tmpmaps = request_input_real_format;
+
+    if(parseRequest(&m,&request_inputs,s1,&request_input_real_format,&request_output_real_format,&hInternet)<0){
+      freeMaps (&m);
+      free (m);
+      free (REQUEST);
+      free (SERVICE_URL);
+      InternetCloseHandle (&hInternet);
+      freeService (&s1);
+      free (s1);
+      return 0;
+    }
+    //InternetCloseHandle (&hInternet);
+
+    initAllEnvironment(m,request_inputs,ntmp,"xrequest");
+
+
+#ifdef DEBUG
+    dumpMap (request_inputs);
+#endif
+
+    map *status = getMap (request_inputs, "status");
+    if(vid==0){
+      // Need to check if we need to fork to load a status enabled 
+      r_inputs = NULL;
+      map *store = getMap (request_inputs, "storeExecuteResponse");
+      /**
+       * 05-007r7 WPS 1.0.0 page 57 :
+       * 'If status="true" and storeExecuteResponse is "false" then the service 
+       * shall raise an exception.'
+       */
+      if (status != NULL && strcmp (status->value, "true") == 0 &&
+	  store != NULL && strcmp (store->value, "false") == 0)
+	{
+	  errorException (m,
+			  _
+			  ("The status parameter cannot be set to true if storeExecuteResponse is set to false. Please modify your request parameters."),
+			  "InvalidParameterValue", "storeExecuteResponse");
+	  freeService (&s1);
+	  free (s1);
+	  freeMaps (&m);
+	  free (m);
+	
+	  freeMaps (&request_input_real_format);
+	  free (request_input_real_format);
+	
+	  freeMaps (&request_output_real_format);
+	  free (request_output_real_format);
+
+	  free (REQUEST);
+	  free (SERVICE_URL);
+	  return 1;
+	}
+      r_inputs = getMap (request_inputs, "storeExecuteResponse");
+    }else{
+      // Define status depending on the WPS 2.0.0 mode attribute
+      status = getMap (request_inputs, "mode");
+      map* mode=getMap(s1->content,"mode");
+      if(strcasecmp(status->value,"async")==0){
+	if(mode!=NULL && strcasecmp(mode->value,"async")==0)
+	  addToMap(request_inputs,"status","true");
+	else{
+	  if(mode!=NULL){
+	    // see ref. http://docs.opengeospatial.org/is/14-065/14-065.html#61
+	    errorException (m,_("The process does not permit the desired execution mode."),"NoSuchMode", mode->value);  
+	    fflush (stdout);
 	    freeMaps (&m);
 	    free (m);
@@ -2577,649 +3122,304 @@
 	      free(zooRegistry);
 	    }
+	    freeMaps (&request_input_real_format);
+	    free (request_input_real_format);
+	    freeMaps (&request_output_real_format);
+	    free (request_output_real_format);
 	    free (REQUEST);
 	    free (SERVICE_URL);
 	    return 0;
-	    
+	  }else
+	    addToMap(request_inputs,"status","true");
+	}
+      }
+      else{
+	if(strcasecmp(status->value,"auto")==0){
+	  if(mode!=NULL){
+	    if(strcasecmp(mode->value,"async")==0)
+	      addToMap(request_inputs,"status","false");
+	    else
+	      addToMap(request_inputs,"status","true");
 	  }
-	return 0;
+	  else
+	    addToMap(request_inputs,"status","false");
+	}else
+	  addToMap(request_inputs,"status","false");
       }
-      if(reqId<=nbReqIdentifier){
-	r_inputs = getMap (request_inputs, "Identifier");
-
-	struct dirent *dp;
-	DIR *dirp = opendir (conf_dir);
-	if (dirp == NULL)
-	  {
-	    errorException (m, _("The specified path does not exist."),
-			    "InternalError", NULL);
-	    freeMaps (&m);
-	    free (m);
-	    if(zooRegistry!=NULL){
-	      freeRegistry(&zooRegistry);
-	      free(zooRegistry);
-	    }
-	    free (REQUEST);
-	    free (SERVICE_URL);
-	    return 0;
-	  }
-	if (strncasecmp (REQUEST, "DescribeProcess", 15) == 0)
-	  {
-	    /**
-	     * Loop over Identifier list
-	     */
-	    xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
-	    r_inputs = NULL;
-	    r_inputs = getMap (request_inputs, "version");
-#ifdef DEBUG
-	    fprintf(stderr," ** DEBUG %s %d \n",__FILE__,__LINE__);
-	    fflush(stderr);
-#endif
-	    xmlNodePtr n = printWPSHeader(doc,m,"DescribeProcess",
-					  root_nodes[vid][1],(version!=NULL?version->value:"1.0.0"),1);
-
-	    r_inputs = getMap (request_inputs, "Identifier");
-
-	    fetchServicesForDescription(zooRegistry, m, r_inputs->value,
-					printDescribeProcessForProcess,
-					(void*) doc, (void*) n, conf_dir,
-					request_inputs,printExceptionReportResponse);
-
-	    printDocument (m, doc, zGetpid ());
-	    freeMaps (&m);
-	    free (m);
-	    if(zooRegistry!=NULL){
-	      freeRegistry(&zooRegistry);
-	      free(zooRegistry);
-	    }
-	    free (REQUEST);
-	    free (SERVICE_URL);
-	    fflush (stdout);
-#ifdef META_DB
-	    close_sql(m,0);
-	    //end_sql();
-#endif
-	    return 0;
-	  }
-	else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
-	  {
-	    map* version=getMapFromMaps(m,"main","rversion");
-	    int vid=getVersionId(version->value);	    
-	    int len = 0;
-	    int j = 0;
-	    for(j=0;j<nbSupportedRequests;j++){
-	      if(requests[vid][j]!=NULL)
-		len+=strlen(requests[vid][j])+2;
-	      else{
-		len+=4;
-		break;
-	      }
-	    }
-	    char *tmpStr=(char*)malloc(len*sizeof(char));
-	    int it=0;
-	    for(j=0;j<nbSupportedRequests;j++){
-	      if(requests[vid][j]!=NULL){
-		if(it==0){
-		  sprintf(tmpStr,"%s",requests[vid][j]);
-		  it++;
-		}else{
-		  char *tmpS=zStrdup(tmpStr);
-		  if(j+1<nbSupportedRequests && requests[vid][j+1]==NULL){
-		    sprintf(tmpStr,"%s and %s",tmpS,requests[vid][j]);
-		  }else{
-		    sprintf(tmpStr,"%s, %s",tmpS,requests[vid][j]);
-		  
-		  }
-		  free(tmpS);
-		}
-	      }
-	      else{
-		len+=4;
-		break;
-	      }
-	    }
-	    char* message=(char*)malloc((61+len)*sizeof(char));
-	    sprintf(message,"The <request> value was not recognized. Allowed values are %s.",tmpStr);
-	    errorException (m,_(message),"InvalidParameterValue", "request");
-#ifdef DEBUG
-	    fprintf (stderr, "No request found %s", REQUEST);
-#endif
-	    closedir (dirp);
-	    freeMaps (&m);
-	    free (m);
-	    if(zooRegistry!=NULL){
-	      freeRegistry(&zooRegistry);
-	      free(zooRegistry);
-	    }
-	    free (REQUEST);
-	    free (SERVICE_URL);
-	    fflush (stdout);
-	    return 0;
-	  }
-	closedir (dirp);
-      }
-    }
-
-  map *postRequest = NULL;
-  postRequest = getMap (request_inputs, "xrequest");
-  
-  if(vid==1 && postRequest==NULL){
-    errorException (m,_("Unable to run Execute request using the GET HTTP method"),"InvalidParameterValue", "request");  
-    freeMaps (&m);
-    free (m);
-    if(zooRegistry!=NULL){
-      freeRegistry(&zooRegistry);
-      free(zooRegistry);
-    }
-    free (REQUEST);
-    free (SERVICE_URL);
-    fflush (stdout);
-    return 0;
-  }
-  s1 = NULL;
- 
-  r_inputs = getMap (request_inputs, "Identifier");
-  map* import = getMapFromMaps (m, IMPORTSERVICE, r_inputs->value); 
-  if (import != NULL && import->value != NULL) { 
-    strncpy(tmps1, import->value, 1024);
-    setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
-    setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
-  } 
-  else {
-    snprintf (tmps1, 1024, "%s/%s.zcfg", conf_dir, r_inputs->value);
-#ifdef DEBUG
-    fprintf (stderr, "Trying to load %s\n", tmps1);
-#endif
-    if (strstr (r_inputs->value, ".") != NULL)
+      status = getMap (request_inputs, "status");
+    }
+
+    if (status != NULL)
+      if (strcasecmp (status->value, "false") == 0)
+	status = NULLMAP;
+    if (status == NULLMAP)
       {
-	char *identifier = zStrdup (r_inputs->value);
-	parseIdentifier (m, conf_dir, identifier, tmps1);
-	map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
-	if (tmpMap != NULL)
-	  addToMap (request_inputs, "metapath", tmpMap->value);
-	free (identifier);
-      }
-    else
-      {
-	setMapInMaps (m, "lenv", "Identifier", r_inputs->value);
-	setMapInMaps (m, "lenv", "oIdentifier", r_inputs->value);
-      }
-  }
-
-  r_inputs = getMapFromMaps (m, "lenv", "Identifier");
-  
-#ifdef META_DB
-  int metadb_id=_init_sql(m,"metadb");
-  //FAILED CONNECTING DB
-  if(getMapFromMaps(m,"lenv","dbIssue")!=NULL || metadb_id<0){
-    fprintf(stderr,"ERROR CONNECTING METADB\n");
-  }
-  if(metadb_id>=0)
-    s1=extractServiceFromDb(m,r_inputs->value,0);
-  //close_sql(m,0);
-  if(s1!=NULL){
-    inheritance(zooRegistry,&s1);
-#ifdef USE_HPC
-    addNestedOutputs(&s1);
-#endif
-    if(zooRegistry!=NULL){
-      freeRegistry(&zooRegistry);
-      free(zooRegistry);
-    }
-  }else /* Not found in MetaDB */{
-#endif
-    s1 = createService();
-    if (s1 == NULL)
-      {
-	freeMaps (&m);
-	free (m);
-	if(zooRegistry!=NULL){
-	  freeRegistry(&zooRegistry);
-	  free(zooRegistry);
-	}
-	free (REQUEST);
-	free (SERVICE_URL);
-	return errorException (m, _("Unable to allocate memory"),
-			       "InternalError", NULL);
-      }
-
-    int saved_stdout = zDup (fileno (stdout));
-    zDup2 (fileno (stderr), fileno (stdout));
-    t = readServiceFile (m, tmps1, &s1, r_inputs->value);
-    if(t>=0){
-      inheritance(zooRegistry,&s1);
-#ifdef USE_HPC
-      addNestedOutputs(&s1);
-#endif
-    }
-    if(zooRegistry!=NULL){
-      freeRegistry(&zooRegistry);
-      free(zooRegistry);
-    }
-    fflush (stdout);
-    zDup2 (saved_stdout, fileno (stdout));
-    if (t < 0)
-      {
-	char *tmpMsg = (char *) malloc (2048 + strlen (r_inputs->value));
-	sprintf (tmpMsg,
-		 _
-		 ("The value for <identifier> seems to be wrong (%s). Please specify one of the processes in the list returned by a GetCapabilities request."),
-		 r_inputs->value);
-	errorException (m, tmpMsg, "InvalidParameterValue", "identifier");
-	free (tmpMsg);
-	free (s1);
-	freeMaps (&m);
-	free (m);
-	free (REQUEST);
-	free (SERVICE_URL);
-	return 0;
-      }
-    zClose (saved_stdout);
-#ifdef META_DB
-  }
-#endif
-  
-#ifdef DEBUG
-  dumpService (s1);
-#endif
-  int j;
-
-
-  /**
-   * Create the input and output maps data structure
-   */
-  int i = 0;
-  HINTERNET hInternet;
-  HINTERNET res;
-  hInternet = InternetOpen (
-#ifndef WIN32
-			    (LPCTSTR)
-#endif
-			    "ZooWPSClient\0",
-			    INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
-
-#ifndef WIN32
-  if (!CHECK_INET_HANDLE (hInternet))
-    fprintf (stderr, "WARNING : hInternet handle failed to initialize");
-#endif
-  maps *request_input_real_format = NULL;
-  maps *tmpmaps = request_input_real_format;
-
-  if(parseRequest(&m,&request_inputs,s1,&request_input_real_format,&request_output_real_format,&hInternet)<0){
-    freeMaps (&m);
-    free (m);
-    free (REQUEST);
-    free (SERVICE_URL);
-    InternetCloseHandle (&hInternet);
-    freeService (&s1);
-    free (s1);
-    return 0;
-  }
-  //InternetCloseHandle (&hInternet);
-
-  initAllEnvironment(m,request_inputs,ntmp,"xrequest");
-
-
-#ifdef DEBUG
-  dumpMap (request_inputs);
-#endif
-
-  map *status = getMap (request_inputs, "status");
-  if(vid==0){
-    // Need to check if we need to fork to load a status enabled 
-    r_inputs = NULL;
-    map *store = getMap (request_inputs, "storeExecuteResponse");
-    /**
-     * 05-007r7 WPS 1.0.0 page 57 :
-     * 'If status="true" and storeExecuteResponse is "false" then the service 
-     * shall raise an exception.'
-     */
-    if (status != NULL && strcmp (status->value, "true") == 0 &&
-	store != NULL && strcmp (store->value, "false") == 0)
-      {
-	errorException (m,
-			_
-			("The status parameter cannot be set to true if storeExecuteResponse is set to false. Please modify your request parameters."),
-			"InvalidParameterValue", "storeExecuteResponse");
-	freeService (&s1);
-	free (s1);
-	freeMaps (&m);
-	free (m);
-	
-	freeMaps (&request_input_real_format);
-	free (request_input_real_format);
-	
-	freeMaps (&request_output_real_format);
-	free (request_output_real_format);
-
-	free (REQUEST);
-	free (SERVICE_URL);
-	return 1;
-      }
-    r_inputs = getMap (request_inputs, "storeExecuteResponse");
-  }else{
-    // Define status depending on the WPS 2.0.0 mode attribute
-    status = getMap (request_inputs, "mode");
-    map* mode=getMap(s1->content,"mode");
-    if(strcasecmp(status->value,"async")==0){
-      if(mode!=NULL && strcasecmp(mode->value,"async")==0)
-	addToMap(request_inputs,"status","true");
-      else{
-	if(mode!=NULL){
-	  // see ref. http://docs.opengeospatial.org/is/14-065/14-065.html#61
-	  errorException (m,_("The process does not permit the desired execution mode."),"NoSuchMode", mode->value);  
-	  fflush (stdout);
+	if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
+	  freeService (&s1);
+	  free (s1);
 	  freeMaps (&m);
 	  free (m);
-	  if(zooRegistry!=NULL){
-	    freeRegistry(&zooRegistry);
-	    free(zooRegistry);
-	  }
+	  free (REQUEST);
+	  free (SERVICE_URL);
 	  freeMaps (&request_input_real_format);
 	  free (request_input_real_format);
 	  freeMaps (&request_output_real_format);
 	  free (request_output_real_format);
-	  free (REQUEST);
-	  free (SERVICE_URL);
-	  return 0;
-	}else
-	  addToMap(request_inputs,"status","true");
+	  freeMaps (&tmpmaps);
+	  free (tmpmaps);
+	  return -1;
+	}
+	map* testMap=getMapFromMaps(m,"main","memory");
+	if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
+	  dumpMapsValuesToFiles(&m,&request_input_real_format);
+	loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
+			   &request_output_real_format, &eres);	  
+
+#ifdef META_DB
+	close_sql(m,0);      
+#endif      
       }
-    }
-    else{
-      if(strcasecmp(status->value,"auto")==0){
-	if(mode!=NULL){
-	  if(strcasecmp(mode->value,"async")==0)
-	    addToMap(request_inputs,"status","false");
-	  else
-	    addToMap(request_inputs,"status","true");
-	}
+    else
+      {
+	int pid;
+#ifdef DEBUG
+	fprintf (stderr, "\nPID : %d\n", cpid);
+#endif
+#ifndef WIN32
+	pid = fork ();
+#else
+	if (cgiSid == NULL)
+	  {
+	    createProcess (m, request_inputs, s1, NULL, cpid,
+			   request_input_real_format,
+			   request_output_real_format);
+	    pid = cpid;
+	  }
 	else
-	  addToMap(request_inputs,"status","false");
-      }else
-	addToMap(request_inputs,"status","false");
-    }
-    status = getMap (request_inputs, "status");
-  }
-
-  int eres = SERVICE_STARTED;
-  int cpid = zGetpid ();
-
-  maps* bmap=NULL;
-  char *fbkp, *fbkpid, *fbkpres, *fbkp1, *flog;
-  FILE *f0, *f1;
-  if (status != NULL)
-    if (strcasecmp (status->value, "false") == 0)
-      status = NULLMAP;
-  if (status == NULLMAP)
-    {
-      if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
-	freeService (&s1);
-	free (s1);
-	freeMaps (&m);
-	free (m);
-	free (REQUEST);
-	free (SERVICE_URL);
-	freeMaps (&request_input_real_format);
-	free (request_input_real_format);
-	freeMaps (&request_output_real_format);
-	free (request_output_real_format);
-	freeMaps (&tmpmaps);
-	free (tmpmaps);
-	return -1;
-      }
-      map* testMap=getMapFromMaps(m,"main","memory");
-      if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
-	dumpMapsValuesToFiles(&m,&request_input_real_format);
-      loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
-                         &request_output_real_format, &eres);	  
-
-#ifdef META_DB
-      close_sql(m,0);      
-#endif      
-    }
-  else
-    {
-      int pid;
-#ifdef DEBUG
-      fprintf (stderr, "\nPID : %d\n", cpid);
-#endif
+	  {
+	    pid = 0;
+	    cpid = atoi (cgiSid);
+	    updateStatus(m,0,_("Initializing"));
+	  }
+#endif
+	if (pid > 0)
+	  {
+	    //
+	    // dady :
+	    // set status to SERVICE_ACCEPTED
+	    //
+#ifdef DEBUG
+	    fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
+		     zGetpid ());
+#endif
+	    eres = SERVICE_ACCEPTED;
+	  }
+	else if (pid == 0)
+	  {
+	    eres = SERVICE_ACCEPTED;
+	    //
+	    // son : have to close the stdout, stdin and stderr to let the parent
+	    // process answer to http client.
+	    //
+	    map* usid = getMapFromMaps (m, "lenv", "uusid");
+	    map* tmpm = getMapFromMaps (m, "lenv", "osid");
+	    int cpid = atoi (tmpm->value);
+	    pid=cpid;
+	    r_inputs = getMapFromMaps (m, "main", "tmpPath");
+	    setMapInMaps (m, "lenv", "async","true");
+	    map* r_inputs1 = createMap("ServiceName", s1->name);
+
+	    // Create the filename for the result file (.res)
+	    fbkpres =
+	      (char *)
+	      malloc ((strlen (r_inputs->value) +
+		       strlen (usid->value) + 7) * sizeof (char));                    
+	    sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
+	    bmap = createMaps("status");
+	    bmap->content=createMap("usid",usid->value);
+	    addToMap(bmap->content,"sid",tmpm->value);
+	    addIntToMap(bmap->content,"pid",zGetpid());
+	  
+	    // Create PID file referencing the OS process identifier
+	    fbkpid =
+	      (char *)
+	      malloc ((strlen (r_inputs->value) +
+		       strlen (usid->value) + 7) * sizeof (char));
+	    sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
+	    setMapInMaps (m, "lenv", "file.pid", fbkpid);
+
+	    f0 = freopen (fbkpid, "w+",stdout);
+	    printf("%d",zGetpid());
+	    fflush(stdout);
+
+	    // Create SID file referencing the semaphore name
+	    fbkp =
+	      (char *)
+	      malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+		       strlen (usid->value) + 7) * sizeof (char));
+	    sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
+	    setMapInMaps (m, "lenv", "file.sid", fbkp);
+	    FILE* f2 = freopen (fbkp, "w+",stdout);
+	    printf("%s",tmpm->value);
+	    fflush(f2);
+	    free(fbkp);
+
+	    fbkp =
+	      (char *)
+	      malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+		       strlen (usid->value) + 7) * sizeof (char));
+	    sprintf (fbkp, "%s/%s_%s.xml", r_inputs->value, r_inputs1->value,
+		     usid->value);
+	    setMapInMaps (m, "lenv", "file.responseInit", fbkp);
+	    flog =
+	      (char *)
+	      malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+		       strlen (usid->value) + 13) * sizeof (char));
+	    sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
+		     r_inputs1->value, usid->value);
+	    setMapInMaps (m, "lenv", "file.log", flog);
+#ifdef DEBUG
+	    fprintf (stderr, "RUN IN BACKGROUND MODE \n");
+	    fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
+		     zGetpid ());
+	    fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
+#endif
+	    freopen (flog, "w+", stderr);
+	    fflush (stderr);
+	    f0 = freopen (fbkp, "w+", stdout);
+	    rewind (stdout);
 #ifndef WIN32
-      pid = fork ();
+	    fclose (stdin);
+#endif
+#ifdef RELY_ON_DB
+	    init_sql(m);
+	    recordServiceStatus(m);
+#endif
+#ifdef USE_CALLBACK
+	    invokeCallback(m,NULL,NULL,0,0);
+#endif
+	    if(vid==0){
+	      //
+	      // set status to SERVICE_STARTED and flush stdout to ensure full 
+	      // content was outputed (the file used to store the ResponseDocument).
+	      // Then, rewind stdout to restart writing from the begining of the file.
+	      // This way, the data will be updated at the end of the process run.
+	      //
+	      printProcessResponse (m, request_inputs, cpid, s1, r_inputs1->value,
+				    SERVICE_STARTED, request_input_real_format,
+				    request_output_real_format);
+	      fflush (stdout);
+#ifdef RELY_ON_DB
+	      recordResponse(m,fbkp);
+#endif
+	    }
+
+	    fflush (stderr);
+
+	    fbkp1 =
+	      (char *)
+	      malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+		       strlen (usid->value) + 13) * sizeof (char));
+	    sprintf (fbkp1, "%s/%s_final_%s.xml", r_inputs->value,
+		     r_inputs1->value, usid->value);
+	    setMapInMaps (m, "lenv", "file.responseFinal", fbkp1);
+
+	    f1 = freopen (fbkp1, "w+", stdout);
+
+	    map* serviceTypeMap=getMap(s1->content,"serviceType");
+	    if(serviceTypeMap!=NULL)
+	      setMapInMaps (m, "lenv", "serviceType", serviceTypeMap->value);
+
+	    char *flenv =
+	      (char *)
+	      malloc ((strlen (r_inputs->value) + 
+		       strlen (usid->value) + 12) * sizeof (char));
+	    sprintf (flenv, "%s/%s_lenv.cfg", r_inputs->value, usid->value);
+	    maps* lenvMaps=getMaps(m,"lenv");
+	    dumpMapsToFile(lenvMaps,flenv,0);
+	    free(flenv);
+
+#ifdef USE_CALLBACK
+	    invokeCallback(m,request_input_real_format,NULL,1,0);
+#endif
+	    if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
+	      freeService (&s1);
+	      free (s1);
+	      fflush (stdout);
+	      fflush (stderr);
+	      fclose (f0);
+	      fclose (f1);
+	      if(dumpBackFinalFile(m,fbkp,fbkp1)<0)
+		return -1;
+#ifndef RELY_ON_DB
+	      dumpMapsToFile(bmap,fbkpres,1);
+	      removeShmLock (m, 1);
 #else
-      if (cgiSid == NULL)
-        {
-	  createProcess (m, request_inputs, s1, NULL, cpid,
-			 request_input_real_format,
-			 request_output_real_format);
-	  pid = cpid;
-        }
-      else
-        {
-	  pid = 0;
-	  cpid = atoi (cgiSid);
-	  updateStatus(m,0,_("Initializing"));
-        }
-#endif
-      if (pid > 0)
-	{
-	  //
-	  // dady :
-	  // set status to SERVICE_ACCEPTED
-	  //
-#ifdef DEBUG
-	  fprintf (stderr, "father pid continue (origin %d) %d ...\n", cpid,
-		   zGetpid ());
-#endif
-	  eres = SERVICE_ACCEPTED;
-	}
-      else if (pid == 0)
-	{
-	  eres = SERVICE_ACCEPTED;
-	  //
-	  // son : have to close the stdout, stdin and stderr to let the parent
-	  // process answer to http client.
-	  //
-	  map* usid = getMapFromMaps (m, "lenv", "uusid");
-	  map* tmpm = getMapFromMaps (m, "lenv", "osid");
-	  int cpid = atoi (tmpm->value);
-	  pid=cpid;
-	  r_inputs = getMapFromMaps (m, "main", "tmpPath");
-	  setMapInMaps (m, "lenv", "async","true");
-	  map* r_inputs1 = createMap("ServiceName", s1->name);
-
-	  // Create the filename for the result file (.res)
-	  fbkpres =
-	    (char *)
-	    malloc ((strlen (r_inputs->value) +
-		     strlen (usid->value) + 7) * sizeof (char));                    
-	  sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
-	  bmap = createMaps("status");
-	  bmap->content=createMap("usid",usid->value);
-	  addToMap(bmap->content,"sid",tmpm->value);
-	  addIntToMap(bmap->content,"pid",zGetpid());
-	  
-	  // Create PID file referencing the OS process identifier
-	  fbkpid =
-	    (char *)
-	    malloc ((strlen (r_inputs->value) +
-		     strlen (usid->value) + 7) * sizeof (char));
-	  sprintf (fbkpid, "%s/%s.pid", r_inputs->value, usid->value);
-	  setMapInMaps (m, "lenv", "file.pid", fbkpid);
-
-	  f0 = freopen (fbkpid, "w+",stdout);
-	  printf("%d",zGetpid());
-	  fflush(stdout);
-
-	  // Create SID file referencing the semaphore name
-	  fbkp =
-	    (char *)
-	    malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
-		     strlen (usid->value) + 7) * sizeof (char));
-	  sprintf (fbkp, "%s/%s.sid", r_inputs->value, usid->value);
-	  setMapInMaps (m, "lenv", "file.sid", fbkp);
-	  FILE* f2 = freopen (fbkp, "w+",stdout);
-	  printf("%s",tmpm->value);
-	  fflush(f2);
-	  free(fbkp);
-
-	  fbkp =
-	    (char *)
-	    malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
-		     strlen (usid->value) + 7) * sizeof (char));
-	  sprintf (fbkp, "%s/%s_%s.xml", r_inputs->value, r_inputs1->value,
-		   usid->value);
-	  setMapInMaps (m, "lenv", "file.responseInit", fbkp);
-	  flog =
-	    (char *)
-	    malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
-		     strlen (usid->value) + 13) * sizeof (char));
-	  sprintf (flog, "%s/%s_%s_error.log", r_inputs->value,
-		   r_inputs1->value, usid->value);
-	  setMapInMaps (m, "lenv", "file.log", flog);
-#ifdef DEBUG
-	  fprintf (stderr, "RUN IN BACKGROUND MODE \n");
-	  fprintf (stderr, "son pid continue (origin %d) %d ...\n", cpid,
-		   zGetpid ());
-	  fprintf (stderr, "\nFILE TO STORE DATA %s\n", r_inputs->value);
-#endif
-	  freopen (flog, "w+", stderr);
-	  fflush (stderr);
-	  f0 = freopen (fbkp, "w+", stdout);
-	  rewind (stdout);
-#ifndef WIN32
-	  fclose (stdin);
-#endif
-#ifdef RELY_ON_DB
-	  init_sql(m);
-	  recordServiceStatus(m);
-#endif
+	      recordResponse(m,fbkp1);
 #ifdef USE_CALLBACK
-	  invokeCallback(m,NULL,NULL,0,0);
-#endif
-	  if(vid==0){
-	    //
-	    // set status to SERVICE_STARTED and flush stdout to ensure full 
-	    // content was outputed (the file used to store the ResponseDocument).
-	    // Then, rewind stdout to restart writing from the begining of the file.
-	    // This way, the data will be updated at the end of the process run.
-	    //
-	    printProcessResponse (m, request_inputs, cpid, s1, r_inputs1->value,
-				  SERVICE_STARTED, request_input_real_format,
-				  request_output_real_format);
-	    fflush (stdout);
-#ifdef RELY_ON_DB
-	    recordResponse(m,fbkp);
-#endif
-	  }
-
-	  fflush (stderr);
-
-	  fbkp1 =
-	    (char *)
-	    malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
-		     strlen (usid->value) + 13) * sizeof (char));
-	  sprintf (fbkp1, "%s/%s_final_%s.xml", r_inputs->value,
-		   r_inputs1->value, usid->value);
-	  setMapInMaps (m, "lenv", "file.responseFinal", fbkp1);
-
-	  f1 = freopen (fbkp1, "w+", stdout);
-
-	  map* serviceTypeMap=getMap(s1->content,"serviceType");
-	  if(serviceTypeMap!=NULL)
-	    setMapInMaps (m, "lenv", "serviceType", serviceTypeMap->value);
-
-	  char *flenv =
-	    (char *)
-	    malloc ((strlen (r_inputs->value) + 
-		     strlen (usid->value) + 12) * sizeof (char));
-	  sprintf (flenv, "%s/%s_lenv.cfg", r_inputs->value, usid->value);
-	  maps* lenvMaps=getMaps(m,"lenv");
-	  dumpMapsToFile(lenvMaps,flenv,0);
-	  free(flenv);
-
-#ifdef USE_CALLBACK
-	  invokeCallback(m,request_input_real_format,NULL,1,0);
-#endif
-	  if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
-	    freeService (&s1);
-	    free (s1);
-	    fflush (stdout);
-	    fflush (stderr);
-	    fclose (f0);
-	    fclose (f1);
-	    if(dumpBackFinalFile(m,fbkp,fbkp1)<0)
-	      return -1;
-#ifndef RELY_ON_DB
-	    dumpMapsToFile(bmap,fbkpres,1);
-	    removeShmLock (m, 1);
-#else
-	    recordResponse(m,fbkp1);
-#ifdef USE_CALLBACK
-	    invokeCallback(m,NULL,NULL,7,0);
-#endif
-#endif
-	    zUnlink (fbkpid);
-	    unhandleStatus (m);
+	      invokeCallback(m,NULL,NULL,7,0);
+#endif
+#endif
+	      zUnlink (fbkpid);
+	      unhandleStatus (m);
 #ifdef RELY_ON_DB
 #ifdef META_DB
-	    cleanupCallbackThreads();
-	    close_sql(m,1);
-#endif
-	    close_sql(m,0);
-#endif
-	    freeMaps (&m);
-	    free (m);
-	    free (REQUEST);
-	    free (SERVICE_URL);
-	    freeMaps (&request_input_real_format);
-	    free (request_input_real_format);
-	    freeMaps (&request_output_real_format);
-	    free (request_output_real_format);
-	    freeMaps (&tmpmaps);
-	    free (tmpmaps);
-	    return -1;
+	      cleanupCallbackThreads();
+	      close_sql(m,1);
+#endif
+	      close_sql(m,0);
+#endif
+	      freeMaps (&m);
+	      free (m);
+	      free (REQUEST);
+	      free (SERVICE_URL);
+	      freeMaps (&request_input_real_format);
+	      free (request_input_real_format);
+	      freeMaps (&request_output_real_format);
+	      free (request_output_real_format);
+	      freeMaps (&tmpmaps);
+	      free (tmpmaps);
+	      return -1;
+	    }
+	    if(getMapFromMaps(m,"lenv","mapError")!=NULL){
+	      setMapInMaps(m,"lenv","message",_("Issue with geographic data"));
+#ifdef USE_CALLBACK
+	      invokeCallback(m,NULL,NULL,7,0);
+#endif
+	      eres=-1;//SERVICE_FAILED;
+	    }else{
+	      map* testMap=getMapFromMaps(m,"main","memory");
+	      if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
+		dumpMapsValuesToFiles(&m,&request_input_real_format);
+	      loadServiceAndRun (&m, s1, request_inputs,
+				 &request_input_real_format,
+				 &request_output_real_format, &eres);
+	    }
 	  }
-	  if(getMapFromMaps(m,"lenv","mapError")!=NULL){
-	    setMapInMaps(m,"lenv","message",_("Issue with geographic data"));
-#ifdef USE_CALLBACK
-	    invokeCallback(m,NULL,NULL,7,0);
-#endif
-	    eres=-1;//SERVICE_FAILED;
-	  }else{
-	    map* testMap=getMapFromMaps(m,"main","memory");
-	    if(testMap==NULL || strcasecmp(testMap->value,"load")!=0)
-	      dumpMapsValuesToFiles(&m,&request_input_real_format);
-	    loadServiceAndRun (&m, s1, request_inputs,
-			       &request_input_real_format,
-			       &request_output_real_format, &eres);
+	else
+	  {
+	    /**
+	     * error server don't accept the process need to output a valid 
+	     * error response here !!!
+	     */
+	    eres = -1;
+	    errorException (m, _("Unable to run the child process properly"),
+			    "InternalError", NULL);
 	  }
-	}
-      else
-        {
-	  /**
-	   * error server don't accept the process need to output a valid 
-	   * error response here !!!
-	   */
-	  eres = -1;
-	  errorException (m, _("Unable to run the child process properly"),
-			  "InternalError", NULL);
-        }
-    }
+      }
 	
 #ifdef DEBUG
-  fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
-  dumpMaps (request_output_real_format);
-  fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
-#endif
-  fflush(stdout);
-  rewind(stdout);
-
-  //fprintf(stderr,"%s %d %d\n",__FILE__,__LINE__,eres);  
-  if (eres != -1)
-    outputResponse (s1, request_input_real_format,
-                    request_output_real_format, request_inputs,
-                    cpid, m, eres);
-  fflush (stdout);
-  
+    fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
+    dumpMaps (request_output_real_format);
+    fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
+#endif
+    fflush(stdout);
+    rewind(stdout);
+
+    if (eres != -1)
+      outputResponse (s1, request_input_real_format,
+		      request_output_real_format, request_inputs,
+		      cpid, m, eres);
+    fflush (stdout);
+  }
   /**
    * Ensure that if error occurs when freeing memory, no signal will return
@@ -3248,4 +3448,5 @@
 
       fclose (f0);
+
       fclose (f1);
 
@@ -3278,7 +3479,10 @@
       zUnlink (fbkp1);
       unhandleStatus (m);
+#if defined(USE_JSON) || defined(USE_CALLBACK)
+      cleanupCallbackThreads();
+#endif
+
 #ifdef RELY_ON_DB
 #ifdef META_DB
-      cleanupCallbackThreads();
       close_sql(m,1);
 #endif
@@ -3287,9 +3491,11 @@
 #endif
       free(fbkpid);
-      free(fbkpres); 
+      free(fbkpres);
       free (fbkp1);
       if(cgiSid!=NULL)
 	free(cgiSid);
-      InternetCloseHandle (&hInternet);
+      map* tMap=getMapFromMaps(m,"lenv","executionType");
+      if(tMap!=NULL && strncasecmp(tMap->value,"xml",3)==0)
+	InternetCloseHandle (&hInternet);
       fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
       fflush(stderr);
