Index: /trunk/zoo-project/HISTORY.txt
===================================================================
--- /trunk/zoo-project/HISTORY.txt	(revision 948)
+++ /trunk/zoo-project/HISTORY.txt	(revision 949)
@@ -1,3 +1,5 @@
 Version 1.8.0-dev
+  * Start simplification of the runRequest function
+  * Integrate optional support for OGC API - Processing implementation
   * Add the optional handleText parameter to provide pure text for
   complex data node with mimetype="text/*"
Index: /trunk/zoo-project/zoo-kernel/main_conf_read.l
===================================================================
--- /trunk/zoo-project/zoo-kernel/main_conf_read.l	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/main_conf_read.l	(revision 949)
@@ -34,7 +34,7 @@
 %}
 
-attname	[a-zA-Z0-9_\-:.]+
+attname	[a-zA-Z0-9_\-:./\{\}-]+
 
-attvalue1	[%\*,;@a-zA-Z0-9_\-.:" "\"\'/\\\(\)\+\x41-\xff?&=\!$]+
+attvalue1	[%\*,;@a-zA-Z0-9_\-.:" "\"\'/\\\(\)\+\x41-\xff?&=\=\!$-]+
 
 whitesp                      [ ]
Index: /trunk/zoo-project/zoo-kernel/meta_sql.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/meta_sql.c	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/meta_sql.c	(revision 949)
@@ -450,8 +450,10 @@
  * @return the number of services found, -1 in case of failure
  */
-int fetchServicesFromDb(registry* reg,maps* conf, xmlDocPtr doc, xmlNodePtr n,
-			void (func) (registry *, maps *, xmlDocPtr, xmlNodePtr,
+int fetchServicesFromDb(registry* reg,maps* conf, void* doc0, void* n0,
+			void (func) (registry *, maps *, void*, void*,
 				     service *), int minimal ){
   int result=0;
+  xmlDocPtr doc=(xmlDocPtr) doc0;
+  xmlNodePtr n=(xmlNodePtr) n0;
   result=_init_sql(conf,"metadb");
   if(getMapFromMaps(conf,"lenv","dbIssue")!=NULL || result < 0)
Index: /trunk/zoo-project/zoo-kernel/meta_sql.h
===================================================================
--- /trunk/zoo-project/zoo-kernel/meta_sql.h	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/meta_sql.h	(revision 949)
@@ -41,7 +41,7 @@
 #endif
 
-  ZOO_DLL_EXPORT int fetchServicesFromDb(registry*,maps*, xmlDocPtr, xmlNodePtr,
-					 void (func) (registry *, maps *, xmlDocPtr,
-						      xmlNodePtr,service *),int);
+  ZOO_DLL_EXPORT int fetchServicesFromDb(registry*,maps*, void*, void*,
+					 void (func) (registry *, maps *, void*,
+						      void*,service *),int);
   ZOO_DLL_EXPORT service* extractServiceFromDb(maps*,const char*,int);
 
Index: /trunk/zoo-project/zoo-kernel/oas.cfg
===================================================================
--- /trunk/zoo-project/zoo-kernel/oas.cfg	(revision 949)
+++ /trunk/zoo-project/zoo-kernel/oas.cfg	(revision 949)
@@ -0,0 +1,200 @@
+[openapi]
+rootUrl=https://demo.mapmint.com/wps3/
+links=/,/api,,/conformance,/processes
+paths=/root,/api,/conformance,/processes,/processes/{id},/processes/{id}/jobs,/processes/{id}/jobs/{jobID},/processes/{id}/jobs/{jobID}/result
+paths2=,/processes/{id}/jobs/{jobID}/result/{resultID}
+paths1=p,processes/{id}/jobs,,processes/{id}/jobs/{jobID}
+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
+
+[/]
+rel=self
+type=application/json
+title=this document
+
+[root]
+method=get
+title=landing page of this API
+abstract=The landing page provides links to the API definition, the Conformance statements and the metadata about the processes offered by this service.
+tags=Home
+tags_description=
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/root.yaml
+
+[/api]
+rel=service
+type=application/openapi+json;version=3.0
+title=the API definition
+
+[api]
+method=get
+title=This document
+abstract=This document
+tags=API
+tags_description=
+schema=
+
+[/conformance]
+rel=conformance
+type=application/json
+title=WPS 2.0 REST/JSON Binding Extension conformance classes implemented by this server
+
+[conformance]
+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
+tags=Conformance
+tags_description=
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/req-classes.yaml
+
+[/processes]
+rel=processes
+type=application/json
+title=The processes offered by this server
+
+[processes]
+method=get
+title=retrieve available processes
+abstract=Information about the available processes
+tags=GetCapabilities
+tags_description=
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/processCollection.yaml
+
+[processes/{id}]
+method=get
+title=retrieve a process description
+abstract=A process description.
+tags=ProcessDescription
+tags_description=
+schemat=https://demo.mapmint.com/wps-rest-binding/core/openapi/schemas/process.yaml
+schematr=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/processOffering.yaml
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/process.yaml
+parameters=/components/parameters/id
+
+
+[/processes/{id}/jobs]
+rel=canonical
+type=application/json
+title=Process Description
+
+[processes/{id}/jobs]
+length=2
+method=get
+title=retrieve a list of jobs run
+abstract=A list of jobs run.
+tags=JobList
+tags_description=
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/jobCollection.yaml
+parameters=/components/parameters/id
+method_1=post
+title_1=execute a job
+abstract_1=An execute endpoint.
+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
+
+[requestBody]
+abstract=Mandatory execute request in JSON format
+type=application/json
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/execute.yaml
+
+[/processes/{id}/jobs/{jobID}]
+rel=canonical
+type=application/json
+title=Status
+
+[processes/{id}/jobs/{jobID}]
+method=get
+title=The status of a job.
+abstract=The status of a job.
+tags=GetStatus
+tags_description=
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/statusInfo.yaml
+parameters=/components/parameters/id,/components/parameters/jobID
+
+[/processes/{id}/jobs/{jobID}/result]
+rel=canonical
+type=application/json
+title=Get Result
+
+[processes/{id}/jobs/{jobID}/result]
+method=get
+title=The result of a job execution.
+abstract=The result of a job execution.
+tags=GetResult
+tags_description=
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/result.yaml
+parameters=/components/parameters/id,/components/parameters/jobID
+ep=,/components/parameters/oas-header2
+
+[/processes/{id}/jobs/{jobID}/result/{resultID}]
+rel=canonical
+type=application/json
+title=Get Result
+
+[processes/{id}/jobs/{jobID}/result/{resultID}]
+method=get
+title=The result of a job execution.
+abstract=The result of a job execution.
+tags=GetResult
+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
+
+
+[{id}]
+type=string
+title=The id of a process
+abstract=The id of a process
+in=path
+required=true
+example=buffer
+
+[{jobID}]
+type=string
+title=The id of a job
+abstract=The id of a job
+in=path
+required=true
+
+[{resultID}]
+type=string
+title=The id of an output
+abstract=The id of an output
+in=path
+required=true
+
+[{f}]
+default=json
+enum=json
+title=The optional f parameter
+abstract=The optional f parameter indicates the output format which the server shall provide as part of the response document.  The default format is JSON.
+in=query
+required=false
+
+[conformTo]
+rootUrl=http://www.opengis.net/spec/WPS/2.0/req/service/binding/rest-json/
+link=core
+link_1=oas30
+link_2=json
+length=3
+
+[exception]
+abstract=Exception
+type=application/json
+schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/exception.yaml
Index: /trunk/zoo-project/zoo-kernel/response_print.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/response_print.c	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/response_print.c	(revision 949)
@@ -639,6 +639,8 @@
  * @return the generated wps:ProcessOfferings xmlNodePtr 
  */
-void printGetCapabilitiesForProcess(registry *reg, maps* m,xmlDocPtr doc,xmlNodePtr nc,service* serv){
+void printGetCapabilitiesForProcess(registry *reg, maps* m,void* doc0,void* nc0,service* serv){
   xmlNsPtr ns,ns_ows,ns_xml,ns_xlink;
+  xmlDocPtr doc=(xmlDocPtr) doc0;
+  xmlNodePtr nc=(xmlNodePtr) nc0;
   xmlNodePtr n=NULL,nc1,nc2,nc3;
   map* version=getMapFromMaps(m,"main","rversion");
@@ -1000,7 +1002,9 @@
  * @return the generated wps:ProcessOfferings xmlNodePtr 
  */
-void printDescribeProcessForProcess(registry *reg, maps* m,xmlDocPtr doc,xmlNodePtr nc,service* serv){
+void printDescribeProcessForProcess(registry *reg, maps* m,void* doc0,void* nc0,service* serv){
   xmlNsPtr ns,ns_ows,ns_xlink;
   xmlNodePtr n,nc1;
+  xmlDocPtr doc=(xmlDocPtr) doc0;
+  xmlNodePtr nc=(xmlNodePtr) nc0;
   xmlNodePtr nc2 = NULL;
   map* version=getMapFromMaps(m,"main","rversion");
Index: /trunk/zoo-project/zoo-kernel/response_print.h
===================================================================
--- /trunk/zoo-project/zoo-kernel/response_print.h	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/response_print.h	(revision 949)
@@ -210,6 +210,6 @@
   xmlNodePtr printWPSHeader(xmlDocPtr,maps*,const char*,const char*,const char*,int);
   xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr,maps*,const char*);
-  void printGetCapabilitiesForProcess(registry*,maps*,xmlDocPtr,xmlNodePtr,service*);
-  void printDescribeProcessForProcess(registry*,maps*,xmlDocPtr,xmlNodePtr,service*);
+  void printGetCapabilitiesForProcess(registry*,maps*,void*,void*,service*);
+  void printDescribeProcessForProcess(registry*,maps*,void*,void*,service*);
   void printFullDescription(xmlDocPtr,int,elements*,const char*,xmlNsPtr,xmlNsPtr,xmlNodePtr,int,int,const map*);
   void printDocument(maps*,xmlDocPtr,int);
Index: /trunk/zoo-project/zoo-kernel/service.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service.c	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/service.c	(revision 949)
@@ -389,5 +389,5 @@
  * @return a pointer to the specific element if found, NULL in other case.
  */ 
-elements* getElements(elements* m,char *key){
+elements* getElements(elements* m,const char *key){
   elements* tmp=m;
   while(tmp!=NULL){
Index: /trunk/zoo-project/zoo-kernel/service.h
===================================================================
--- /trunk/zoo-project/zoo-kernel/service.h	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/service.h	(revision 949)
@@ -425,5 +425,5 @@
   ZOO_DLL_EXPORT void setElementsName(elements**,char*);
   ZOO_DLL_EXPORT bool hasElement(elements*,const char*);
-  ZOO_DLL_EXPORT elements* getElements(elements*,char*);
+  ZOO_DLL_EXPORT elements* getElements(elements*,const char*);
   ZOO_DLL_EXPORT void freeIOType(iotype**);
   ZOO_DLL_EXPORT void freeElements(elements**);
Index: /trunk/zoo-project/zoo-kernel/service_json.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_json.c	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/service_json.c	(revision 949)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- *  Copyright 2017 GeoLabs SARL. All rights reserved.
+ *  Copyright 2017-2019 GeoLabs SARL. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,9 +24,32 @@
 
 #include "service_json.h"
+#include "json.h"
+#include <errno.h>
+#include "json_tokener.h"
+#include "stdlib.h"
+#include "mimetypes.h"
+#include "server_internal.h"
+#include "service_internal.h"
+#include <dirent.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
-
+  /**
+   * Equivalent range keywords for WPS version 1 and 2
+   */
+  const char* rangeCorrespondances[4][2]={
+    { "rangeMin", "minimumValue" },
+    { "rangeMax", "maximumValue"},
+    { "rangeSpacing", "spacing" }, 
+    { "rangeClosure", "rangeClosure" }
+  };
+  
+
+  /**
+   * Convert a map to a json object
+   * @param myMap the map to be converted into json object
+   * @return a json_object pointer to the created json_object
+   */
   json_object* mapToJson(map* myMap){
     json_object *res=json_object_new_object();
@@ -67,4 +90,9 @@
   }
 
+  /**
+   * Convert a maps to a json object
+   * @param myMap the maps to be converted into json object
+   * @return a json_object pointer to the created json_object
+   */
   json_object* mapsToJson(maps* myMap){
     json_object *res=json_object_new_object();
@@ -73,7 +101,5 @@
       json_object *obj=NULL;
       if(cursor->content!=NULL){
-	//json_object *content=NULL;
 	obj=mapToJson(cursor->content);
-	//json_object_object_add(obj,"content",content);
       }else
 	obj=json_object_new_object();
@@ -89,4 +115,9 @@
   }
 
+  /**
+   * Convert an elements to a json object
+   * @param myElements the elements pointer to be converted into a json object
+   * @return a json_object pointer to the created json_object
+   */
   json_object* elementsToJson(elements* myElements){
     json_object *res=json_object_new_object();
@@ -112,12 +143,7 @@
 	}
 	json_object_object_add(cres,"supported",resi);
-	fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
-	fflush(stderr);
       }
       
-      dumpElements(cur->child);
       json_object_object_add(cres,"child",elementsToJson(cur->child));
-      fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
-      fflush(stderr);
 
       json_object_object_add(res,cur->name,cres);
@@ -127,4 +153,9 @@
   }
   
+  /**
+   * Convert an service to a json object
+   * @param myService the service pointer to be converted into a json object
+   * @return a json_object pointer to the created json_object
+   */
   json_object* serviceToJson(service* myService){
     json_object *res=json_object_new_object();
@@ -137,5 +168,1535 @@
     return res;
   }
+
+  /**
+   * Add Allowed Range properties to a json_object
+   * @param m the main configuration maps pointer
+   * @param iot the iotype pointer
+   * @param prop the json_object pointer to add the allowed range properties
+   * @return a json_object pointer to the created json_object
+   */
+  void printAllowedRangesJ(maps* m,iotype* iot,json_object* prop){
+    map* tmpMap1;
+    json_object* prop4=json_object_new_object();
+    for(int i=0;i<4;i++){
+      tmpMap1=getMap(iot->content,rangeCorrespondances[i][0]);
+      if(tmpMap1!=NULL){
+	if(i<3)
+	  json_object_object_add(prop4,rangeCorrespondances[i][1],json_object_new_string(tmpMap1->value));
+	else{
+	  char* currentValue=NULL;
+	  int limit=strlen(tmpMap1->value);
+	  for(int j=0;j<limit;j++){
+	    const char* tmpS="closed";
+	    if(tmpMap1->value[j]=='o'){
+	      tmpS="open";
+	    }
+	    if(currentValue==NULL){
+	      currentValue=(char*)malloc((strlen(tmpS)+1)*sizeof(char));
+	      sprintf(currentValue,"%s",tmpS);
+	    }else{
+	      char* tmpS1=zStrdup(currentValue);
+	      currentValue=(char*)realloc(currentValue,(strlen(tmpS1)+strlen(tmpS)+2)*sizeof(char));
+	      sprintf(currentValue,"%s-%s",tmpS1,tmpS);
+	    }
+	  }	      
+	  json_object_object_add(prop4,rangeCorrespondances[i][1],json_object_new_string(currentValue));
+	}
+      }
+    }
+    json_object_array_add(prop,prop4);
+  }
   
+  /**
+   * Add literalDataDomains property to a json_object
+   * @param m the main configuration maps pointer
+   * @param in the elements pointer
+   * @param input the json_object pointer to add the literalDataDomains property
+   * @return a json_object pointer to the created json_object
+   */
+  void printLiteralDataJ(maps* m,elements* in,json_object* input){
+    json_object* prop0=json_object_new_array();
+    json_object* prop1=json_object_new_object();
+    json_object* prop2=json_object_new_object();
+    if(in->defaults!=NULL){
+      map* tmpMap1=getMap(in->defaults->content,"DataType");
+      if(tmpMap1!=NULL){
+	json_object_object_add(prop2,"name",json_object_new_string(tmpMap1->value));
+	json_object_object_add(prop1,"dataType",prop2);
+      }
+      tmpMap1=getMap(in->defaults->content,"value");
+      if(tmpMap1!=NULL)
+	json_object_object_add(prop1,"defaultValue",json_object_new_string(tmpMap1->value));
+      json_object* prop3=json_object_new_object();
+      tmpMap1=getMap(in->defaults->content,"rangeMin");
+      if(tmpMap1!=NULL){
+	json_object* prop5=json_object_new_array();
+	printAllowedRangesJ(m,in->defaults,prop5);
+	if(in->supported!=NULL){
+	  iotype* iot=in->supported;
+	  while(iot!=NULL){
+	    printAllowedRangesJ(m,iot,prop5);
+	    iot=iot->next;
+	  }
+	}
+	json_object_object_add(prop3,"allowedRanges",prop5);
+      }
+      else{
+	tmpMap1=getMap(in->defaults->content,"range");
+	if(tmpMap1!=NULL){
+	  // TODO: parse range = [rangeMin,rangeMax]
+	}else{ 
+	  // AllowedValues
+	  tmpMap1=getMap(in->defaults->content,"AllowedValues");
+	  if(tmpMap1!=NULL){
+	    char* saveptr;
+	    json_object* prop5=json_object_new_array();
+	    char *tmps = strtok_r (tmpMap1->value, ",", &saveptr);
+	    while(tmps!=NULL){
+	      json_object_array_add(prop5,json_object_new_string(tmps));
+	      tmps = strtok_r (NULL, ",", &saveptr);
+	    }
+	    json_object_object_add(prop3,"allowedValues",prop5);
+	    
+	  }else{
+	    json_object_object_add(prop3,"anyValue",json_object_new_boolean(true));
+	  }
+	}
+      }
+      json_object_object_add(prop1,"valueDefinition",prop3);
+      json_object_array_add(prop0,prop1);
+    }
+    json_object_object_add(input,"literalDataDomains",prop0);
+  }
+
+  /**
+   * Add Format properties to a json_object
+   * @param m the main configuration maps pointer
+   * @param iot the current iotype pointer
+   * @param res the json_object pointer to add the properties to
+   * @param isDefault boolean specifying if the currrent iotype is default
+   * @param maxSize a map pointer to the maximumMegabytes param defined in the zcfg file for this input/output
+   */
+  void printFormatJ(maps* m,iotype* iot,json_object* res,bool isDefault,map* maxSize){
+    if(iot!=NULL){
+      map* tmpMap1=getMap(iot->content,"mimeType");
+      json_object* prop1=json_object_new_object();
+      json_object_object_add(prop1,"default",json_object_new_boolean(isDefault));
+      json_object_object_add(prop1,"mimeType",json_object_new_string(tmpMap1->value));
+      tmpMap1=getMap(iot->content,"encoding");
+      if(tmpMap1!=NULL)
+	json_object_object_add(prop1,"encoding",json_object_new_string(tmpMap1->value));
+      tmpMap1=getMap(iot->content,"schema");
+      if(tmpMap1!=NULL)
+	json_object_object_add(prop1,"schema",json_object_new_string(tmpMap1->value));
+      if(maxSize!=NULL)
+	json_object_object_add(prop1,"maximumMegabytes",json_object_new_int64(atoll(maxSize->value)));
+      json_object_array_add(res,prop1);
+    }
+  }
+
+  /**
+   * Add additionalParameters property to a json_object
+   * @param conf the main configuration maps pointer
+   * @param meta a map pointer to the current metadata informations
+   * @param doc the json_object pointer to add the property to
+   */
+  void printJAdditionalParameters(maps* conf,map* meta,json_object* doc){
+    map* cmeta=meta;
+    json_object* carr=json_object_new_array();
+    int hasElement=-1;
+    json_object* jcaps=json_object_new_object();
+    while(cmeta!=NULL){
+      json_object* jcmeta=json_object_new_object();
+      if(strcasecmp(cmeta->name,"role")!=0 &&
+	 strcasecmp(cmeta->name,"href")!=0 &&
+	 strcasecmp(cmeta->name,"title")!=0 &&
+	 strcasecmp(cmeta->name,"length")!=0 ){
+	json_object_object_add(jcmeta,"name",json_object_new_string(cmeta->name));
+	json_object_object_add(jcmeta,"value",json_object_new_string(cmeta->value));
+	json_object_array_add(carr,jcmeta);
+	hasElement++;
+      }else{
+	if(strcasecmp(cmeta->name,"length")!=0)
+	  json_object_object_add(jcaps,cmeta->name,json_object_new_string(cmeta->value));
+      }
+      cmeta=cmeta->next;
+    }
+    if(hasElement>=0){
+      json_object_object_add(jcaps,"additionalParameter",carr);
+      json_object_object_add(doc,"additionalParameters",jcaps);
+    }
+  }
+
+  /**
+   * Add metadata property to a json_object
+   * @param conf the main configuration maps pointer
+   * @param meta a map pointer to the current metadata informations
+   * @param doc the json_object pointer to add the property to
+   */
+  void printJMetadata(maps* conf,map* meta,json_object* doc){
+    map* cmeta=meta;
+    json_object* carr=json_object_new_array();
+    int hasElement=-1;
+    while(cmeta!=NULL){
+      json_object* jcmeta=json_object_new_object();
+      if(strcasecmp(cmeta->name,"role")==0 ||
+	 strcasecmp(cmeta->name,"href")==0 ||
+	 strcasecmp(cmeta->name,"title")==0 ){
+	json_object_object_add(jcmeta,cmeta->name,json_object_new_string(cmeta->value));
+	hasElement++;
+      }
+      json_object_array_add(carr,jcmeta);
+      cmeta=cmeta->next;
+    }
+    if(hasElement>=0)
+      json_object_object_add(doc,"metadata",carr);
+  }
+
+  /**
+   * Add metadata properties to a json_object
+   * @param m the main configuration maps pointer
+   * @param io a string 
+   * @param in an elements pointer to the current input/output
+   * @param inputs the json_object pointer to add the property to
+   * @param serv the service pointer to extract the metadata from
+   */
+  void printIOTypeJ(maps* m, const char *io, elements* in,json_object* inputs,service* serv){
+    while(in!=NULL){
+      json_object* input=json_object_new_object();
+      json_object_object_add(input,"id",json_object_new_string(in->name));
+      map* tmpMap=getMap(in->content,"title");
+      if(tmpMap!=NULL)
+	json_object_object_add(input,"title",json_object_new_string(tmpMap->value));
+      tmpMap=getMap(in->content,"abstract");
+      if(tmpMap!=NULL)
+	json_object_object_add(input,"abstract",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));
+	tmpMap=getMap(in->content,"maxOccurs");
+	if(tmpMap!=NULL)
+	  json_object_object_add(input,"maxOccurs",json_object_new_string(tmpMap->value));
+      }
+      if(in->format!=NULL){
+	json_object* input1=json_object_new_object();
+	json_object* prop0=json_object_new_array();
+	if(strcasecmp(in->format,"LiteralData")==0 ||
+	   strcasecmp(in->format,"LiteralOutput")==0){
+	  printLiteralDataJ(m,in,input1);
+	}else{
+	  if(strcasecmp(in->format,"ComplexData")==0 ||
+	     strcasecmp(in->format,"ComplexOutput")==0){
+	    map* sizeMap=getMap(in->content,"maximumMegabytes");
+	    printFormatJ(m,in->defaults,prop0,true,sizeMap);
+	    iotype* sup=in->supported;
+	    while(sup!=NULL){
+	      printFormatJ(m,sup,prop0,false,sizeMap);
+	      sup=sup->next;
+	    }
+	    json_object_object_add(input1,"formats",prop0);
+	  }
+	  else{
+	    json_object* prop1=json_object_new_object();
+	    json_object_object_add(prop1,"default",json_object_new_boolean(true));
+	    map* tmpMap1=getMap(in->defaults->content,"crs");
+	    if(tmpMap1==NULL)
+	      return;
+	    json_object_object_add(prop1,"crs",json_object_new_string(tmpMap1->value));
+	    json_object_array_add(prop0,prop1);
+	    iotype* sup=in->supported;
+	    while(sup!=NULL){
+	      json_object* prop1=json_object_new_object();
+	      json_object_object_add(prop1,"default",json_object_new_boolean(false));
+	      tmpMap1=getMap(sup->content,"crs");
+	      json_object_object_add(prop1,"crs",json_object_new_string(tmpMap1->value));
+	      json_object_array_add(prop0,prop1);
+	      sup=sup->next;
+	    }	      
+	    json_object_object_add(input1,"supportedCRS",prop0);
+	  }
+	}
+	json_object_object_add(input,io,input1);
+      }
+      printJMetadata(m,in->metadata,input);
+      printJAdditionalParameters(m,in->additional_parameters,input);
+      json_object_array_add(inputs,input);	
+      in=in->next;
+    }
+    
+  }
+
+  /**
+   * Add all the capabilities properties to a json_object
+   * @param ref the registry pointer
+   * @param m the main configuration maps pointer
+   * @param doc0 the void (json_object) pointer to add the property to
+   * @param nc0 the void (json_object) pointer to add the property to
+   * @param serv the service pointer to extract the metadata from
+   */
+  void printGetCapabilitiesForProcessJ(registry *reg, maps* m,void* doc0,void* nc0,service* serv){
+    json_object* doc=(json_object*) doc0;
+    json_object* nc=(json_object*) nc0;
+    json_object *res=json_object_new_object();
+    map* tmpMap0=getMapFromMaps(m,"lenv","level");
+    char* rUrl=serv->name;
+    if(tmpMap0!=NULL && atoi(tmpMap0->value)>0){
+      int i=0;
+      maps* tmpMaps=getMaps(m,"lenv");
+      char* tmpName=NULL;
+      for(i=0;i<atoi(tmpMap0->value);i++){
+	char* key=(char*)malloc(15*sizeof(char));
+	sprintf(key,"sprefix_%d",i);
+	map* tmpMap1=getMap(tmpMaps->content,key);
+	if(i+1==atoi(tmpMap0->value))
+	  if(tmpName==NULL){
+	    tmpName=(char*) malloc((strlen(serv->name)+strlen(tmpMap1->value)+1)*sizeof(char));
+	    sprintf(tmpName,"%s%s",tmpMap1->value,serv->name);
+	  }else{
+	    char* tmpStr=zStrdup(tmpName);
+	    tmpName=(char*) realloc(tmpName,(strlen(tmpStr)+strlen(tmpMap1->value)+strlen(serv->name)+1)*sizeof(char));
+	    sprintf(tmpName,"%s%s%s",tmpStr,tmpMap1->value,serv->name);
+	    free(tmpStr);
+	  }
+	else
+	  if(tmpName==NULL){
+	    tmpName=(char*) malloc((strlen(tmpMap1->value)+1)*sizeof(char));
+	    sprintf(tmpName,"%s",tmpMap1->value);
+	  }else{
+	    char* tmpStr=zStrdup(tmpName);
+	    tmpName=(char*) realloc(tmpName,(strlen(tmpStr)+strlen(tmpMap1->value)+1)*sizeof(char));
+	    sprintf(tmpName,"%s%s",tmpStr,tmpMap1->value);
+	    free(tmpStr);
+	  }
+      }
+      json_object_object_add(res,"id",json_object_new_string(tmpName));
+      if(tmpName!=NULL){
+	rUrl=zStrdup(tmpName);
+	free(tmpName);
+      }
+    }
+    else
+      json_object_object_add(res,"id",json_object_new_string(serv->name));
+    if(serv->content!=NULL){
+      map* tmpMap=getMap(serv->content,"title");
+      if(tmpMap!=NULL){
+	json_object_object_add(res,"title",json_object_new_string(tmpMap->value));
+      }
+      tmpMap=getMap(serv->content,"abstract");
+      if(tmpMap!=NULL){
+	json_object_object_add(res,"abstract",json_object_new_string(tmpMap->value));
+      }
+      tmpMap=getMap(serv->content,"processVersion");
+      if(tmpMap!=NULL){
+	if(strlen(tmpMap->value)<5){
+	  char *val=(char*)malloc((strlen(tmpMap->value)+5)*sizeof(char));
+	  sprintf(val,"%s.0.0",tmpMap->value);
+	  json_object_object_add(res,"version",json_object_new_string(val));
+	  free(val);
+	}
+	else
+	  json_object_object_add(res,"version",json_object_new_string(tmpMap->value));
+      }
+      int limit=4;
+      int i=0;
+      map* sType=getMap(serv->content,"serviceType");
+      for(;i<limit;i+=2){
+	json_object *res1=json_object_new_object();
+	json_object *res2=json_object_new_array();
+	char *saveptr;
+	char* dupStr=strdup(jcapabilities[i+1]);
+	char *tmps = strtok_r (dupStr, " ", &saveptr);
+	while(tmps!=NULL){
+	  json_object_array_add(res2,json_object_new_string(tmps));
+	  tmps = strtok_r (NULL, " ", &saveptr);
+	}
+	free(dupStr);
+	json_object_object_add(res,jcapabilities[i],res2);
+      }
+      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_object_add(res2,"type",json_object_new_string("application/json"));
+      json_object_object_add(res2,"title",json_object_new_string("Process Description"));
+      map* tmpUrl=getMapFromMaps(m,"main","serverAddress");
+      char* tmpStr=(char*) malloc((strlen(tmpUrl->value)+strlen(rUrl)+13)*sizeof(char));
+      sprintf(tmpStr,"%s/processes/%s/",tmpUrl->value,rUrl);
+      if(doc==NULL){
+	json_object_object_add(res2,"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);
+	free(tmpStr1);
+      }
+      json_object_object_add(res2,"href",json_object_new_string(tmpStr));
+      free(tmpStr);
+      json_object_array_add(res1,res2);
+      json_object_object_add(res,"links",res1);
+    }
+    if(doc==NULL){
+      elements* in=serv->inputs;
+      json_object* inputs=json_object_new_array();
+      printIOTypeJ(m,"input",in,inputs,serv);
+      json_object_object_add(res,"inputs",inputs);
+
+      in=serv->outputs;
+      json_object* outputs=json_object_new_array();
+      printIOTypeJ(m,"output",in,outputs,serv);
+      json_object_object_add(res,"outputs",outputs);
+
+    }
+    if(strcmp(rUrl,serv->name)!=0)
+      free(rUrl);
+    if(doc!=NULL)
+      json_object_array_add(doc,res);
+    else
+      json_object_object_add(nc,"process",json_object_get(res));
+
+  }
+
+  /**
+   * Print an OWS ExceptionReport Document and HTTP headers (when required) 
+   * depending on the code.
+   * Set hasPrinted value to true in the [lenv] section.
+   * 
+   * @param m the maps containing the settings of the main.cfg file
+   * @param s the map containing the text,code,locator keys (or a map array of the same keys)
+   */
+  void printExceptionReportResponseJ(maps* m,map* s){
+    if(getMapFromMaps(m,"lenv","hasPrinted")!=NULL)
+      return;
+    int buffersize;
+    json_object *res=json_object_new_object();
+
+    maps* tmpMap=getMaps(m,"main");
+    const char *exceptionCode;
+    
+    map* tmp=getMap(s,"code");
+    if(tmp!=NULL){
+      if(strcmp(tmp->value,"OperationNotSupported")==0 ||
+	 strcmp(tmp->value,"NoApplicableCode")==0)
+	exceptionCode="501 Not Implemented";
+      else
+	if(strcmp(tmp->value,"MissingParameterValue")==0 ||
+	   strcmp(tmp->value,"InvalidUpdateSequence")==0 ||
+	   strcmp(tmp->value,"OptionNotSupported")==0 ||
+	   strcmp(tmp->value,"VersionNegotiationFailed")==0 ||
+	   strcmp(tmp->value,"InvalidParameterValue")==0)
+	  exceptionCode="400 Bad request";
+	else
+	  if(strcmp(tmp->value,"NotFound")==0)
+	    exceptionCode="404 Not Found";
+	  else
+	    exceptionCode="501 Internal Server Error";
+      json_object_object_add(res,"code",json_object_new_string(tmp->value));
+    }
+    else
+      exceptionCode="501 Internal Server Error";
+    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) ){
+	  printf("Status: %s\r\n\r\n",exceptionCode);
+	}
+      }
+      else{
+	printf("Status: %s\r\n\r\n",exceptionCode);
+      }
+    }else{
+      printf("Status: %s\r\n\r\n",exceptionCode);
+    }
+    tmp=getMap(s,"text");
+    if(tmp==NULL)
+      tmp=getMap(s,"message");
+    if(tmp==NULL)
+      tmp=getMapFromMaps(m,"lenv","message");
+    if(tmp!=NULL)
+      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);
+    printf(jsonStr);
+    if(m!=NULL)
+      setMapInMaps(m,"lenv","hasPrinted","true");
+  }
+
+  /**
+   * Parse LiteralData value
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param req json_object pointing to the input/output
+   * @param element
+   * @param output the maps to set current json structure
+   */
+  void parseJLiteral(maps* conf,json_object* req,elements* element,maps* output){
+    json_object* json_cinput=NULL;
+    if(json_object_object_get_ex(req,"value",&json_cinput)!=FALSE){
+      output->content=createMap("value",json_object_get_string(json_cinput));
+    }
+    const char* tmpStrs[2]={
+      "dataType",
+      "uom"
+    };
+    for(int i=0;i<2;i++)
+      if(json_object_object_get_ex(req,tmpStrs[i],&json_cinput)!=FALSE){
+	json_object* json_cinput1;
+	if(json_object_object_get_ex(json_cinput,"name",&json_cinput1)!=FALSE){
+	  if(output->content==NULL)
+	    output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput1));
+	  else
+	    addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput1));
+	}
+	if(json_object_object_get_ex(json_cinput,"reference",&json_cinput1)!=FALSE){
+	  if(output->content==NULL)
+	    output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput1));
+	  else
+	    addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput1));
+	}
+      }
+    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
+      if(output->content==NULL)
+	output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
+      else
+	addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
+    }
+  }
+
+  /**
+   * Parse ComplexData value
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param req json_object pointing to the input/output
+   * @param element
+   * @param output the maps to set current json structure
+   * @param name the name of the request from http_requests
+   */
+  void parseJComplex(maps* conf,json_object* req,elements* element,maps* output,const char* name){
+    json_object* json_cinput=NULL;
+    if(json_object_object_get_ex(req,"value",&json_cinput)!=FALSE){
+      json_object* json_value=NULL;
+      if(json_object_object_get_ex(json_cinput,"inlineValue",&json_value)!=FALSE)
+	output->content=createMap("value",json_object_get_string(json_value));
+      else{
+	if(json_object_object_get_ex(json_cinput,"href",&json_value)!=FALSE){
+	  output->content=createMap("xlink:href",json_object_get_string(json_value));
+	  int len=0;
+	  int createdStr=0;
+	  char *tmpStr="url";
+	  char *tmpStr1="input";
+	  if(getMaps(conf,"http_requests")==NULL){
+	    maps* tmpMaps=createMaps("http_requests");
+	    tmpMaps->content=createMap("length","1");
+	    addMapsToMaps(&conf,tmpMaps);
+	    freeMaps(&tmpMaps);
+	    free(tmpMaps);
+	  }else{
+	    map* tmpMap=getMapFromMaps(conf,"http_requests","length");
+	    int len=atoi(tmpMap->value);
+	    createdStr=1;
+	    tmpStr=(char*) malloc((12)*sizeof(char));
+	    sprintf(tmpStr,"%d",len+1);
+	    setMapInMaps(conf,"http_requests","length",tmpStr);
+	    sprintf(tmpStr,"url_%d",len);
+	    tmpStr1=(char*) malloc((14)*sizeof(char));
+	    sprintf(tmpStr1,"input_%d",len);
+	  }
+	  setMapInMaps(conf,"http_requests",tmpStr,json_object_get_string(json_value));
+	  setMapInMaps(conf,"http_requests",tmpStr1,name);
+	  if(createdStr>0){
+	    free(tmpStr);
+	    free(tmpStr1);
+	  }
+	}
+      }
+    }
+    if(json_object_object_get_ex(req,"format",&json_cinput)!=FALSE){
+      json_object_object_foreach(json_cinput, key, val) {
+	if(output->content==NULL)
+	  output->content=createMap(key,json_object_get_string(val));
+	else
+	  addToMap(output->content,key,json_object_get_string(val));
+	
+      }
+    }
+    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
+      if(output->content==NULL)
+	output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
+      else
+	addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
+    }
+  }
+
+  /**
+   * Parse BoundingBox value
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param req json_object pointing to the input/output
+   * @param element
+   * @param output the maps to set current json structure
+   */
+  void parseJBoundingBox(maps* conf,json_object* req,elements* element,maps* output){
+    json_object* json_cinput=NULL;
+    if(json_object_object_get_ex(req,"bbox",&json_cinput)!=FALSE){
+      output->content=createMap("value",json_object_get_string(json_cinput));
+    }
+    if(json_object_object_get_ex(req,"crs",&json_cinput)!=FALSE){
+      if(output->content==NULL)
+	output->content=createMap("crs",json_object_get_string(json_cinput));
+      else
+	addToMap(output->content,"crs","http://www.opengis.net/def/crs/OGC/1.3/CRS84");
+    }
+    char* tmpStrs[2]={
+      "lowerCorner",
+      "upperCorner"
+    };
+    for(int i=0;i<2;i++)
+      if(json_object_object_get_ex(req,tmpStrs[i],&json_cinput)!=FALSE){
+	if(output->content==NULL)
+	  output->content=createMap(tmpStrs[i],json_object_get_string(json_cinput));
+	else
+	  addToMap(output->content,tmpStrs[i],json_object_get_string(json_cinput));
+      }
+    if(json_object_object_get_ex(req,"transmissionMode",&json_cinput)!=FALSE){
+      if(output->content==NULL)
+	output->content=createMap("transmissionMode",json_object_get_string(json_cinput));
+      else
+	addToMap(output->content,"transmissionMode",json_object_get_string(json_cinput));
+    }
+  }
+
+  /**
+   * Parse inputs / outputs
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param req json_object pointing to the input/output
+   * @param ioElements the elements extracted from the zcfg
+   * @param ioMaps the produced maps containing inputs (or outputs) 
+   * @param ioType the char* set to inputs or outputs
+   */
+  void parseJIO(maps* conf, json_object* req, elements* ioElements, maps** ioMaps,const char* ioType){
+    json_object* json_io=NULL;
+    if(json_object_object_get_ex(req,ioType,&json_io)!=FALSE){	    
+      json_object* json_current_io=NULL;
+      size_t len=json_object_array_length(json_io);
+      for(int i=0;i<len;i++){
+	maps *cMaps=NULL;
+	json_current_io=json_object_array_get_idx(json_io,i);
+	json_object* cname=NULL;
+	if(json_object_object_get_ex(json_current_io,"id",&cname)!=FALSE){
+	  cMaps=createMaps(json_object_get_string(cname));
+	  elements* cio=getElements(ioElements,json_object_get_string(cname));
+	  json_object* json_input;
+	  json_object* json_cinput;
+	  if(json_object_object_get_ex(json_current_io,"input",&json_input)!=FALSE){
+	    if(json_object_object_get_ex(json_input,"dataType",&json_cinput)!=FALSE){
+	      parseJLiteral(conf,json_input,cio,cMaps);
+	    } else if(json_object_object_get_ex(json_input,"format",&json_cinput)!=FALSE){
+	      parseJComplex(conf,json_input,cio,cMaps,json_object_get_string(cname));
+	    } else if(json_object_object_get_ex(json_input,"bbox",&json_cinput)!=FALSE){
+	      parseJBoundingBox(conf,json_input,cio,cMaps);
+	    }// else error!
+	    else{
+	      if(json_object_object_get_ex(json_input,"value",&json_cinput)!=FALSE){
+		map* error=createMap("code","BadRequest");
+		char tmpS[1024];
+		sprintf(tmpS,_("Missing input for %s"),ioElements->name);
+		addToMap(error,"message",tmpS);
+		setMapInMaps(conf,"lenv","status_code","400 Bad Request");
+		printExceptionReportResponseJ(conf,error);
+		return;
+	      }else{
+		if(json_object_get_type(json_cinput)==json_type_string){
+		  parseJLiteral(conf,json_input,cio,cMaps);
+		}else if(json_object_get_type(json_cinput)==json_type_object){
+		  json_object* json_ccinput=NULL;
+		  if(json_object_object_get_ex(json_cinput,"bbox",&json_ccinput)!=FALSE){
+		    parseJComplex(conf,json_input,cio,cMaps,json_object_get_string(cname));
+		  }
+		  else{
+		    parseJBoundingBox(conf,json_input,cio,cMaps);
+		  }
+		}else{
+		  if(strcmp(ioType,"input")==0){
+		    map* error=createMap("code","BadRequest");
+		    char tmpS1[1024];
+		    sprintf(tmpS1,_("Issue with input %s"),ioElements->name);
+		    addToMap(error,"message",tmpS1);
+		    setMapInMaps(conf,"lenv","status_code","400 Bad Request");
+		    printExceptionReportResponseJ(conf,error);
+		    return;
+		  }
+		}
+	      }
+	    }
+	  }else{
+	    if(strcmp(ioType,"input")==0){
+	      map* error=createMap("code","BadRequest");
+	      char tmpS1[1024];
+	      sprintf(tmpS1,_("Missing input for %s"),ioElements->name);
+	      addToMap(error,"message",tmpS1);
+	      setMapInMaps(conf,"lenv","status_code","400 Bad Request");
+	      printExceptionReportResponseJ(conf,error);
+	      return;
+	    }else{
+	      // Outputs
+	      if(json_object_object_get_ex(json_current_io,"transmissionMode",&json_cinput)!=FALSE){
+		if(cMaps->content==NULL)
+		  cMaps->content=createMap("transmissionMode",json_object_get_string(json_cinput));
+		else
+		  addToMap(cMaps->content,"transmissionMode",json_object_get_string(json_cinput));
+	      }
+	      if(json_object_object_get_ex(json_current_io,"format",&json_cinput)!=FALSE){
+		json_object_object_foreach(json_cinput, key, val) {
+		  if(cMaps->content==NULL)
+		    cMaps->content=createMap(key,json_object_get_string(val));
+		  else
+		    addToMap(cMaps->content,key,json_object_get_string(val));
+		}
+	      }	      
+	    }
+	  }
+	}
+	addToMap(cMaps->content,"inRequest","true");
+	if (ioMaps == NULL)
+	  *ioMaps = dupMaps(&cMaps);
+	else
+	  addMapsToMaps (ioMaps, cMaps);
+      }
+    }
+  }
+    
+      
+  
+  /**
+   * Parse Json Request
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param s the current service metadata
+   * @param req the JSON object of the request body
+   * @param inputs the produced maps
+   * @param outputs the produced maps
+   */
+  void parseJRequest(maps* conf, service* s,json_object* req,maps** inputs,maps** outputs){
+    elements* io=s->inputs;
+
+    json_object* json_io=NULL;
+    int parsed=0;
+    char* tmpS="input";
+    maps* in=*inputs;
+    parseJIO(conf,req,s->inputs,inputs,"inputs");
+
+    if(parsed==0){
+      json_io=NULL;
+      if(json_object_object_get_ex(req,"outputs",&json_io)!=FALSE){
+	parseJIO(conf,req,s->outputs,outputs,"outputs");
+      }
+    }      
+  }
+
+  /**
+   * Print the jobs list
+   *
+   * @param conf the maps containing the settings of the main.cfg file
+   * @return the JSON object pointer to the jobs list
+   */
+  json_object* printJobList(maps* conf){
+    json_object* res=json_object_new_array();
+    map* tmpPath=getMapFromMaps(conf,"main","tmpPath");
+    map* oIdentifier=getMapFromMaps(conf,"lenv","oIdentifier");
+    char* cpath=(char*)malloc((strlen(tmpPath->value)+strlen(oIdentifier->value)+14)*sizeof(char));
+    sprintf(cpath,"%s/statusInfos/%s",tmpPath->value,oIdentifier->value);
+    struct dirent *dp;
+    DIR *dirp = opendir (cpath);
+    if(dirp!=NULL){
+      while ((dp = readdir (dirp)) != NULL){
+	char* extn = strstr(dp->d_name, ".json");
+	if(extn!=NULL){
+	  json_object* cjob=json_object_new_object();
+	  char* tmpStr=zStrdup(dp->d_name);
+	  tmpStr[strlen(dp->d_name)-5]=0;
+	  json_object_object_add(cjob,"id",json_object_new_string(tmpStr));
+	  char *tmps1=(char*)malloc((strlen(cpath)+strlen(dp->d_name)+2)*sizeof(char));
+	  sprintf (tmps1, "%s/%s", cpath, dp->d_name);
+	  FILE* cdat=fopen(tmps1,"rb");
+	  if(cdat!=NULL){
+	    zStatStruct f_status;
+	    int s=zStat(tmps1, &f_status);
+	    char* mystring=(char*)malloc((f_status.st_size+1)*sizeof(char));
+	    fread(mystring,1,f_status.st_size,cdat);
+	    mystring[f_status.st_size]=0;	    
+	    json_object *jobj = NULL;
+	    int slen = 0;
+	    enum json_tokener_error jerr;
+	    struct json_tokener* tok=json_tokener_new();
+	    do {
+	      slen = strlen(mystring);
+	      jobj = json_tokener_parse_ex(tok, mystring, slen);
+	    } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
+	    if (jerr != json_tokener_success) {
+	      fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
+	      return res;
+	    }
+	    if (tok->char_offset < slen){
+	      return res;
+	    }
+	    json_object_object_add(cjob,"infos",jobj);
+	    free(mystring);
+	    fclose(cdat);
+	  }
+	  free(tmpStr);
+	  json_object_array_add(res,cjob);
+	}
+      }
+      closedir (dirp);
+    }
+    return res;
+  }
+
+  /**
+   * Print the result of an execution
+   *
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param s service pointer to metadata
+   * @param result outputs of the service
+   * @param res the status of executino 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();
+    json_object* eres=json_object_new_array();
+    maps* resu=result;
+    int itn=0;
+    while(resu!=NULL){
+      json_object* res1=json_object_new_object();
+      json_object_object_add(res1,"id",json_object_new_string(resu->name));
+      map* tmpMap=NULL;
+      if((tmpMap=getMap(resu->content,"value"))!=NULL ||
+	 (getMap(resu->content,"generated_file"))!=NULL){
+	json_object* res2=json_object_new_object();
+	map* tmpMap1=NULL;
+	if((tmpMap1=getMap(resu->content,"transmissionMode"))!=NULL) {
+	  if(strcmp(tmpMap1->value,"value")==0) {
+	    map* tmpMap2=getMap(resu->content,"mimeType");
+	    if(tmpMap2!=NULL && strstr(tmpMap2->value,"json")!=NULL){
+	      json_object *jobj = NULL;
+	      int slen = 0;
+	      enum json_tokener_error jerr;
+	      struct json_tokener* tok=json_tokener_new();
+	      do {
+		slen = strlen(tmpMap->value);
+		jobj = json_tokener_parse_ex(tok, tmpMap->value, slen);
+	      } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
+	      if (jerr != json_tokener_success) {
+		fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
+		return eres1;
+	      }
+	      if (tok->char_offset < slen){
+		return eres1;		
+	      }
+	      json_object_object_add(res2,"inlineValue",jobj);
+	    }else
+	      json_object_object_add(res2,"inlineValue",json_object_new_string(tmpMap->value));
+	  }
+	  else{
+	    // Create file for reference data if not existing
+	    map *gfile=getMap(resu->content,"generated_file");
+	    char *file_name=NULL;
+	    char *file_path=NULL;
+	    char *file_url=NULL;
+	    map *tmp1=getMapFromMaps(conf,"main","tmpPath");
+	    if(gfile!=NULL){
+	      gfile=getMap(resu->content,"expected_generated_file");
+	      if(gfile==NULL){
+		gfile=getMap(resu->content,"generated_file");
+	      }
+	      if(strstr(gfile->value,tmp1->value)!=NULL)
+		file_name=zStrdup(strstr(gfile->value,tmp1->value)+strlen(tmp1->value));
+	    }/*else*/
+	    {
+	      // Create file for reference data
+	      map *tmpUrl=getMapFromMaps(conf,"main","tmpUrl");
+	      map *usid=getMapFromMaps(conf,"lenv","usid");
+	      map *ext=getMap(resu->content,"extension");
+	      if(gfile==NULL){
+		char file_ext[32];	    
+		if( ext != NULL && ext->value != NULL) {
+		  strncpy(file_ext, ext->value, 32);
+		}
+		else {
+		  // Obtain default file extension (see mimetypes.h).	      
+		  // If the MIME type is not recognized, txt is used as the default extension
+		  map* mtype=getMap(resu->content,"mimeType");
+		  getFileExtension(mtype != NULL ? mtype->value : NULL, file_ext, 32);
+		}
+		if(file_name!=NULL)
+		  free(file_name);
+	      
+		file_name=(char*)malloc((strlen(s->name)+strlen(usid->value)+strlen(file_ext)+strlen(resu->name)+45)*sizeof(char));
+		sprintf(file_name,"ZOO_DATA_%s_%s_%s_%d.%s",s->name,resu->name,usid->value,itn,file_ext);
+
+		file_path=(char*)malloc((strlen(tmp1->value)+strlen(file_name)+2)*sizeof(char));
+		sprintf(file_path,"%s/%s",tmp1->value,file_name);
+	      }else{
+		file_path=(char*)malloc((strlen(gfile->value)+1)*sizeof(char));
+		sprintf(file_path,"%s",gfile->value);
+	      }
+		
+	      
+	      itn++;
+	      
+	      file_url=(char*)malloc((strlen(tmpUrl->value)+
+				      strlen(file_name)+2)*sizeof(char));
+	      sprintf(file_url,"%s/%s",tmpUrl->value,file_name);
+
+	      if(gfile==NULL){
+		FILE *ofile=fopen(file_path,"wb");
+		if(ofile==NULL){
+		  char tmpMsg[1024];
+		  sprintf(tmpMsg,
+			  _("Unable to create the file \"%s\" for storing the %s final result."),
+			  file_name,resu->name);
+		  map* error=createMap("code","InternalError");
+		  addToMap(error,"message",tmpMsg);
+		  printExceptionReportResponseJ(conf,error);
+		  free(file_name);
+		  free(file_path);
+		  return NULL;
+		}
+
+		map* toto=getMap(resu->content,"value");
+		if(toto==NULL){
+		  char tmpMsg[1024];
+		  sprintf(tmpMsg,
+			  _("No value found for the requested output %s."),
+			  resu->name);
+		  map* error=createMap("code","InternalError");
+		  addToMap(error,"message",tmpMsg);
+		  printExceptionReportResponseJ(conf,error);
+		  fclose(ofile);
+		  free(file_name);
+		  free(file_path);
+		  return NULL;
+		}
+		map* size=getMap(resu->content,"size");
+		if(size!=NULL && toto!=NULL)
+		  fwrite(toto->value,1,(atoi(size->value))*sizeof(char),ofile);
+		else
+		  if(toto!=NULL && toto->value!=NULL)
+		    fwrite(toto->value,1,
+			   strlen(toto->value)*sizeof(char),ofile);
+		fclose(ofile);
+	      }
+	      json_object_object_add(res2,"href",
+				     json_object_new_string(file_url));
+	      free(file_url);
+	      free(file_name);
+	      free(file_path);
+	      
+	    }
+	    
+	  }
+	}
+	json_object_object_add(res1,"value",res2);	
+	json_object_array_add(eres,res1);
+      }
+      resu=resu->next;
+    }
+    json_object_object_add(eres1,"outputs",eres);
+    const char* jsonStr =
+      json_object_to_json_string_ext(eres1,JSON_C_TO_STRING_PLAIN);
+    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
+    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
+    map *sessId = getMapFromMaps (conf, "lenv", "usid");
+    char tmp[1024];
+    sprintf(tmp,"%s/%s_%s.json",
+	    tmpPath->value,cIdentifier->value,sessId->value);
+    FILE* foutput=fopen(tmp,"w+");
+    if(foutput!=NULL){
+      fclose(foutput);
+      char tmpUrl[1024];
+      map* tmpPath1 = getMapFromMaps (conf, "main", "tmpUrl");
+      sprintf(tmpUrl,"%s/%s_%s.json",tmpPath1->value,
+	      cIdentifier->value,sessId->value);
+      setMapInMaps(conf,"headers","Location",tmpUrl);
+    }
+    if(res==3){
+      setMapInMaps(conf,"headers","Status","201 Created");
+    }
+    else{
+      setMapInMaps(conf,"headers","Status","500 Issue running your service");
+    }
+
+    return eres1;
+  }
+
+
+  /**
+   * Create the status links
+   *
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param result an integer (>0 for adding the /result link)
+   * @param obj the JSON object pointer to add the links to
+   * @return 0
+   */
+  int createStatusLinks(maps* conf,int result,json_object* obj){
+    json_object* res=json_object_new_array();
+    map *tmpPath = getMapFromMaps (conf, "main", "serverAddress");
+    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
+    map *sessId = getMapFromMaps (conf, "lenv", "usid");
+    char *Url0=(char*) malloc((strlen(tmpPath->value)+
+			       strlen(cIdentifier->value)+
+			       strlen(sessId->value)+18)*sizeof(char));
+    int needResult=-1;
+    char *message, *status;
+    sprintf(Url0,"%s/processes/%s/jobs/%s",
+	    tmpPath->value,
+	    cIdentifier->value,
+	    sessId->value);
+    setMapInMaps(conf,"headers","Location",Url0);
+    json_object* val=json_object_new_object();
+    json_object_object_add(val,"Title",
+			   json_object_new_string(_("Status location")));
+    json_object_object_add(val,"href",json_object_new_string(Url0));
+    json_object_array_add(res,val);
+    if(result>0){
+      free(Url0);
+      Url0=(char*) malloc((strlen(tmpPath->value)+
+			   strlen(cIdentifier->value)+strlen(sessId->value)+
+			   25)*sizeof(char));
+      sprintf(Url0,"%s/processes/%s/jobs/%s/result",
+	      tmpPath->value,
+	      cIdentifier->value,
+	      sessId->value);
+      json_object* val1=json_object_new_object();
+      json_object_object_add(val1,"Title",
+			     json_object_new_string(_("Result location")));
+      json_object_object_add(val1,"href",json_object_new_string(Url0));
+      json_object_array_add(res,val1);
+    }
+    json_object_object_add(obj,"links",res);
+    free(Url0);
+    return 0;
+  }
+
+  /**
+   * Get the status file path
+   *
+   * @param conf the maps containing the settings of the main.cfg file
+   * @return a char* containing the full status file path
+   */
+  char* json_getStatusFilePath(maps* conf){
+    map *tmpPath = getMapFromMaps (conf, "main", "tmpPath");
+    map *cIdentifier = getMapFromMaps (conf, "lenv", "oIdentifier");
+    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");
+    char *tmp1=(char*) malloc((strlen(tmpPath->value)+
+			       strlen(cIdentifier->value)+14)*sizeof(char));
+    sprintf(tmp1,"%s/statusInfos/%s",
+	    tmpPath->value,
+	    cIdentifier->value);
+    if(mkdir(tmp1,0777) != 0 && errno != EEXIST){
+      fprintf(stderr,"Issue creating directory %s\n",tmp1);
+      return NULL;
+    }
+    free(tmp1);
+    tmp1=(char*) malloc((strlen(tmpPath->value)+
+			 strlen(cIdentifier->value)+
+			 strlen(sessId->value)+20)*sizeof(char));
+    int needResult=0;
+    char *message, *rstatus;
+    sprintf(tmp1,"%s/statusInfos/%s/%s.json",
+	    tmpPath->value,
+	    cIdentifier->value,
+	    sessId->value);
+    
+    return tmp1;
+  }
+  
+  /**
+   * 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){
+    int needResult=0;
+    const char *message, *rstatus;
+    char* tmp1=json_getStatusFilePath(conf);
+    // 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:
+      {
+	message=_("ZOO-Kernel accepted to run your service!");
+	rstatus="accepted";
+	break;
+      }
+    case SERVICE_STARTED:
+      {
+	message=_("ZOO-Kernel is currently running your service!");
+	rstatus="running";
+	break;
+      }
+    case SERVICE_PAUSED:
+      {
+	message=_("ZOO-Kernel pause your service!");
+	rstatus="paused";
+	break;
+      }
+    case SERVICE_SUCCEEDED:
+      {
+	message=_("ZOO-Kernel successfully run your service!");
+	rstatus="successful";
+	needResult=1;
+	break;
+      }
+    default:
+      {
+	message=_("ZOO-Kernel failed to run your service!");
+	rstatus="failed";
+	break;
+      }
+    }
+    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);
+    
+    FILE* foutput1=fopen(tmp1,"w+");
+    if(foutput1!=NULL){
+      const char* jsonStr1=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
+      fprintf(foutput1,"%s",jsonStr1);
+      fclose(foutput1);
+    }else{
+      // Failure
+      setMapInMaps(conf,"lenv","message",_("Unable to store the statusInfo!"));
+      free(tmp1);
+      return 1;
+    }
+    free(tmp1);
+    return 0;
+  }
+
+  /**
+   * Create the status file 
+   *
+   * @param conf the maps containing the settings of the main.cfg file
+   * @return an integer (0 in case of success, 1 in case of failure)
+   */
+  int json_getStatusFile(maps* conf){
+    char* tmp1=json_getStatusFilePath(conf);
+    FILE* statusFile=fopen(tmp1,"rb");
+
+    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);
+	}
+      }
+  }
+
+  /**
+   * Produce the JSON object for api info object
+   *
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param res the JSON object for the api info
+   */
+  void produceApiInfo(maps* conf,json_object* res,json_object* res5){
+    json_object *res1=json_object_new_object();
+    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
+    if(tmpMap!=NULL){
+      json_object *res2=json_object_new_object();
+      json_object_object_add(res2,"name",json_object_new_string(tmpMap->value));
+      tmpMap=getMapFromMaps(conf,"provider","addressElectronicMailAddress");
+      if(tmpMap!=NULL)
+	json_object_object_add(res2,"email",json_object_new_string(tmpMap->value));
+      tmpMap=getMapFromMaps(conf,"provider","providerSite");
+      if(tmpMap!=NULL)
+	json_object_object_add(res2,"url",json_object_new_string(tmpMap->value));
+      json_object_object_add(res1,"contact",res2);
+    }
+    tmpMap=getMapFromMaps(conf,"identification","abstract");
+    if(tmpMap!=NULL){
+      json_object_object_add(res1,"description",json_object_new_string(tmpMap->value));
+      json_object_object_add(res5,"description",json_object_new_string(tmpMap->value));
+      tmpMap=getMapFromMaps(conf,"main","serverAddress");
+      json_object_object_add(res5,"url",json_object_new_string(tmpMap->value));
+    }
+    tmpMap=getMapFromMaps(conf,"identification","title");
+    if(tmpMap!=NULL)
+      json_object_object_add(res1,"title",json_object_new_string(tmpMap->value));
+    json_object_object_add(res1,"version",json_object_new_string(ZOO_VERSION));
+    tmpMap=getMapFromMaps(conf,"identification","keywords");
+    if(tmpMap!=NULL){
+      char *saveptr;
+      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
+      json_object *res3=json_object_new_array();
+      while (tmps != NULL){
+	json_object_array_add(res3,json_object_new_string(tmps));
+	tmps = strtok_r (NULL, ",", &saveptr);
+      }
+      json_object_object_add(res1,"x-keywords",res3);
+    }
+    maps* tmpMaps=getMaps(conf,"provider");
+    if(tmpMaps!=NULL){
+      json_object *res4=json_object_new_object();
+      map* cItem=tmpMaps->content;
+      while(cItem!=NULL){
+	json_object_object_add(res4,cItem->name,json_object_new_string(cItem->value));
+	cItem=cItem->next;
+      }
+      json_object_object_add(res1,"x-ows-servicecontact",res4);
+    }
+
+    json_object *res4=json_object_new_object();
+    tmpMap=getMapFromMaps(conf,"main","license_name");
+    if(tmpMap!=NULL){
+      json_object_object_add(res4,"name",json_object_new_string(tmpMap->value));
+      tmpMap=getMapFromMaps(conf,"main","license_url");
+      if(tmpMap!=NULL){
+	json_object_object_add(res4,"url",json_object_new_string(tmpMap->value));      
+      }
+    }
+    json_object_object_add(res1,"license",res4);
+
+    json_object_object_add(res,"info",res1);    
+  }
+
+  /**
+   * Produce the JSON object for api parameter
+   *
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param res the JSON object to populate with the parameters
+   */
+  void produceApiParameters(maps* conf,json_object* res){
+    json_object *res9=json_object_new_object();
+    maps* tmpMaps1=getMaps(conf,"{id}");
+    map* tmpMap2=getMapFromMaps(conf,"openapi","parameters");
+    char *saveptr12;
+    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);
+      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);    
+  }
+
+  void produceApiComponents(maps*conf,json_object* res){
+    json_object* res1=json_object_new_object();
+    produceApiParameters(conf,res1);
+    json_object_object_add(res,"components",res1);
+  }
+
+  /**
+   * Produce the JSON object for /api
+   *
+   * @param conf the maps containing the settings of the main.cfg file
+   * @param res the JSON object to populate
+   */
+  void produceApi(maps* conf,json_object* res){
+    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();
+    setMapInMaps(conf,"headers","Content-Type","application/openapi+json; version=3.0;charset=UTF-8");
+
+    produceApiInfo(conf,res,res4);
+    map* tmpMap=getMapFromMaps(conf,"provider","providerName");
+
+    tmpMap=getMapFromMaps(conf,"openapi","version");
+    if(tmpMap!=NULL)
+      json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
+    else
+      json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
+
+    tmpMap=getMapFromMaps(conf,"openapi","paths");
+    if(tmpMap!=NULL){
+      json_object *res5=json_object_new_object();
+      char *saveptr;
+      char *tmps = strtok_r (tmpMap->value, ",", &saveptr);
+      int cnt=0;
+      maps* tmpMaps;
+      json_object *paths=json_object_new_object();
+      while (tmps != NULL){
+	tmpMaps=getMaps(conf,tmps+1);
+	json_object *method=json_object_new_object();
+	if(tmpMaps!=NULL){
+	  if(getMap(tmpMaps->content,"length")==NULL)
+	    addToMap(tmpMaps->content,"length","1");
+	  map* len=getMap(tmpMaps->content,"length");
+	    
+	  for(int i=0;i<atoi(len->value);i++){
+	    json_object *methodc=json_object_new_object();
+	    map* cMap=getMapArray(tmpMaps->content,"method",i);
+	    map* vMap=getMapArray(tmpMaps->content,"title",i);
+	    if(vMap!=NULL)
+	      json_object_object_add(methodc,"summary",json_object_new_string(vMap->value));
+	    vMap=getMapArray(tmpMaps->content,"abstract",i);
+	    if(vMap!=NULL)
+	      json_object_object_add(methodc,"description",json_object_new_string(vMap->value));
+	    vMap=getMapArray(tmpMaps->content,"tags",i);
+	    if(vMap!=NULL){
+	      json_object *cc=json_object_new_array();
+	      json_object_array_add(cc,json_object_new_string(vMap->value));
+	      json_object_object_add(methodc,"tags",cc);
+	    }
+	    json_object *responses=json_object_new_object();
+	    json_object *cc3=json_object_new_object();
+	    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);
+	    }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);
+	    }
+	    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);
+	    }
+	    json_object_object_add(methodc,"responses",cc3);
+	    vMap=getMapArray(tmpMaps->content,"parameters",i);
+	    if(vMap!=NULL){
+	      char *saveptr0;
+	      char *tmps1 = strtok_r (vMap->value, ",", &saveptr0);
+	      json_object *cc2=json_object_new_array();
+	      int cnt=0;
+	      while(tmps1!=NULL){
+		char* tmpStr=(char*)malloc((strlen(tmps1)+2)*sizeof(char));
+		sprintf(tmpStr,"#%s",tmps1);
+		json_object *cc1=json_object_new_object();
+		json_object_object_add(cc1,"$ref",json_object_new_string(tmpStr));
+		json_object_array_add(cc2,cc1);
+		free(tmpStr);
+		cnt++;
+		tmps1 = strtok_r (NULL, ",", &saveptr0);
+	      }
+	      json_object_object_add(methodc,"parameters",cc2);
+	    }
+	    if(i==1){
+	      maps* tmpMaps1=getMaps(conf,"requestBody");
+	      if(tmpMaps1!=NULL){
+		vMap=getMap(tmpMaps1->content,"schema");
+		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=getMap(tmpMaps->content,"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);
+		  vMap=getMap(tmpMaps1->content,"abstract");
+		  if(vMap!=NULL)
+		    json_object_object_add(cc2,"description",json_object_new_string(vMap->value));
+		  json_object_object_add(cc2,"required",json_object_new_boolean(true));
+		  json_object_object_add(methodc,"requestBody",cc2);
+
+		}
+	      }
+	    }
+	    map* mMap=getMapArray(tmpMaps->content,"method",i);
+	    if(mMap!=NULL)
+	      json_object_object_add(method,mMap->value,methodc);
+	    else
+	      json_object_object_add(method,"get",methodc);
+
+	  }
+
+	  tmpMap=getMapFromMaps(conf,"openapi","version");
+	  if(tmpMap!=NULL)
+	    json_object_object_add(res,"openapi",json_object_new_string(tmpMap->value));
+	  else
+	    json_object_object_add(res,"openapi",json_object_new_string("3.0.2"));
+	  if(strstr(tmps,"/root")!=NULL)
+	    json_object_object_add(paths,"/",method);
+	  else
+	    json_object_object_add(paths,tmps,method);
+	}
+	tmps = strtok_r (NULL, ",", &saveptr);
+	cnt++;
+      }
+      json_object_object_add(res,"paths",paths);
+    }
+      
+    tmpMap=getMapFromMaps(conf,"openapi","links");
+    if(tmpMap!=NULL){
+	
+    }
+    
+    json_object *res3=json_object_new_array();
+    json_object_array_add(res3,res4);
+    json_object_object_add(res,"servers",res3);
+  }
   
 #ifdef __cplusplus
Index: /trunk/zoo-project/zoo-kernel/service_json.h
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_json.h	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/service_json.h	(revision 949)
@@ -28,4 +28,5 @@
 #pragma once
 
+#include "response_print.h"
 #include <stdio.h>
 #include <ctype.h>
@@ -36,7 +37,24 @@
 extern "C" {
 #endif
+  /**
+   * Name and corresponding attributes depending on the WPS version
+   */
+  static const char* jcapabilities[4]={
+    "jobControlOptions","sync-execute async-execute dismiss",
+    "outputTransmission","value reference"
+  };
+
   json_object* mapToJson(map*);
   json_object* mapsToJson(maps*);
   json_object* serviceToJson(service*);
+  void printGetCapabilitiesForProcessJ(registry*, maps*,void*,void*,service*);
+  void printExceptionReportResponseJ(maps*,map*);
+  void parseJRequest(maps*,service* s,json_object*,maps**,maps**);
+  json_object*  printJResult(maps*,service*,maps*,int);
+  json_object* printJobList(maps*);
+  int createStatusFile(maps*,int);
+  int json_getStatusFile(maps*);
+  void produceApi(maps*,json_object*);
+  //void printIOTypeJ(maps*, const char*, elements*,json_object*,service*);
 #ifdef __cplusplus
 }
Index: /trunk/zoo-project/zoo-kernel/zoo_loader.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/zoo_loader.c	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/zoo_loader.c	(revision 949)
@@ -98,5 +98,28 @@
   map* tmpMap=NULL;
 
-  if(strncmp(cgiContentType,"text/xml",8)==0 || 
+  if(strncmp(cgiContentType,"application/json",16)==0 &&
+     strncasecmp(cgiRequestMethod,"post",4)==0){
+       char *buffer=new char[2];
+       char *res=NULL;
+       int r=0;
+       int len=0;
+       while((r=fread(buffer,sizeof(char),1,cgiIn))>0){
+	 fprintf(stderr,"%s",buffer);
+	 buffer[1]=0;
+	 if(res==NULL){
+	   res=(char*)malloc(2*sizeof(char));
+	   sprintf(res,"%s",buffer);
+	 }
+	 else{
+	   res=(char*)realloc(res,(len+2)*sizeof(char));
+	   memcpy(res + len, buffer, sizeof(char));
+	   res[len+1]=0;
+	 }
+	 len+=1;
+       }
+       delete[] buffer;
+       tmpMap=createMap("jrequest",res);
+       free(res);
+  }else if(strncmp(cgiContentType,"text/xml",8)==0 ||
      strncasecmp(cgiRequestMethod,"post",4)==0){
     if(cgiContentLength==0){
@@ -123,5 +146,5 @@
        if(res!=NULL)
 	 free(res);
-    }else{		
+    }else{  
       char *buffer=new char[cgiContentLength+1];
       if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)>0){
@@ -363,7 +386,12 @@
       xmlCleanupParser();
     }else{
-      freeMap(&tmpMap);
-      free(tmpMap);
-      tmpMap=createMap("not_valid","true");
+      if(tmpMap!=NULL){	
+	if(getMap(tmpMap,"jrequest")==NULL){
+	  freeMap(&tmpMap);
+	  free(tmpMap);
+	  tmpMap=createMap("not_valid","true");
+	}
+      }else
+	tmpMap=createMap("not_valid","true");
     }
 
@@ -408,5 +436,5 @@
   if(strQuery!=NULL)
     free(strQuery);
-  
+
   runRequest(&tmpMap);
 
Index: /trunk/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 948)
+++ /trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 949)
@@ -70,5 +70,5 @@
 #include "request_parser.h"
 #include "sqlapi.h"
-#ifdef WIN32
+#ifdef USE_JSON
 #include "caching.h"
 #endif
@@ -107,6 +107,10 @@
 
 #ifdef USE_CALLBACK
+#include "service_callback.h"
+#endif
+
+#ifdef USE_JSON
 #include "service_json.h"
-#include "service_callback.h"
+#include "json_tokener.h"
 #endif
 
@@ -258,10 +262,14 @@
  */
 int
-recursReaddirF ( maps * m, registry *r, xmlDocPtr doc, xmlNodePtr n, char *conf_dir, 
-		 char *prefix, int saved_stdout, int level, 
-		 void (func) (registry *, maps *, xmlDocPtr, xmlNodePtr, service *) )
+recursReaddirF ( maps * m, registry *r, void* doc1, void* n1, char *conf_dir,
+		 //( maps * m, registry *r, xmlDocPtr doc, xmlNodePtr n, char *conf_dir,
+		 char *prefix, int saved_stdout, int level,
+		 void (func) (registry *, maps *, void*, void*, service *) )
+		 //void (func) (registry *, maps *, xmlDocPtr, xmlNodePtr, service *) )
 {
   struct dirent *dp;
   int scount = 0;
+  xmlDocPtr doc=(xmlDocPtr) doc1;
+  xmlNodePtr n=(xmlNodePtr) n1;
 
   if (conf_dir == NULL)
@@ -385,4 +393,601 @@
 
 /**
+ * When th zcfg file is not found, print error message and cleanup memory
+ * @param zooRegistry the populated registry
+ * @param m the maps pointer to the content of main.cfg file
+ * @param zcfg the zcfg file name
+ * @param code the string determining the nature of the error
+ * @param locator the string determining which parameter the error refer to
+ * @param orig the service name
+ * @param corig the current service name (in case multiple services was parsed)
+ * @param funcError the function used to print the error back
+ */
+void exitAndCleanUp(registry* zooRegistry, maps* m,
+		    const char* zcfg,const char* code,const char* locator,
+		    char* orig,char* corig,
+		    void (funcError) (maps*, map*)){
+  map *tmp00 = getMapFromMaps (m, "lenv", "message");
+  char tmp01[1024];
+  if (tmp00 != NULL)
+    sprintf (tmp01,
+	     _("Unable to parse the ZCFG file: %s (%s)"),
+	     zcfg, tmp00->value);
+  else
+    sprintf (tmp01,
+	     _("Unable to parse the ZCFG file: %s."),
+	     zcfg);
+  map* errormap = createMap("text", tmp01);
+  addToMap(errormap,"code", code);
+  addToMap(errormap,"locator", locator);
+  funcError(m,errormap);
+  freeMaps (&m);
+  free (m);
+  if(zooRegistry!=NULL){
+    freeRegistry(&zooRegistry);
+    free(zooRegistry);
+  }
+  free (orig);
+  if (corig != NULL)
+    free (corig);
+  //xmlFreeDoc (doc);
+  xmlCleanupParser ();
+  zooXmlCleanupNs ();
+  freeMap(&errormap);
+  free(errormap);
+}
+
+
+/**
+ * Search services from various possible sources 
+ *
+ * @param zopRegistry the populated registry
+ * @param m the maps pointer to the content of main.cfg file
+ * @param r_inputs the service(s) name(s)
+ * @param func the function used to print the result back
+ * @param doc the xml document or NULL (for json)
+ * @param n the xmlNode of JSON object pointer to the current element
+ * @param conf_dir the directory where the main.cfg has been found
+ * @param request_inputs the map pointer to the request KVP if any
+ * @param funcError the function used to print the error back
+ * @return 0 in case of success, 1 otherwise
+ */
+int fetchServicesForDescription(registry* zooRegistry, maps* m, char* r_inputs,
+				void (func) (registry *, maps *, void*, void*, service *),
+				void* doc, void* n, char* conf_dir, map* request_inputs,
+				void (funcError) (maps*, map*) ){
+  char *orig = zStrdup (r_inputs);
+  service* s1=NULL;
+  int saved_stdout = zDup (fileno (stdout));
+  int t;
+  int scount = 0;
+  struct dirent *dp;
+
+  zDup2 (fileno (stderr), fileno (stdout));  
+  if (strcasecmp ("all", orig) == 0)
+    {
+      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;
+	    }
+	    inheritance(zooRegistry, &svc);
+#ifdef USE_HPC
+	    addNestedOutputs(&svc);
+#endif
+
+	    func(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,
+			  func) < 0)
+	return res;
+#ifdef META_DB
+      fetchServicesFromDb(zooRegistry,m,doc,n,func,0);
+      close_sql(m,0);
+#endif
+    }
+  else
+    {
+      DIR *dirp = opendir (conf_dir);
+      char *saveptr;
+      char *tmps = strtok_r (orig, ",", &saveptr);
+
+      char buff[256];
+      char buff1[1024];
+      while (tmps != NULL)
+	{
+	  int hasVal = -1;
+	  char *corig = zStrdup (tmps);
+	  map* import = getMapFromMaps (m, IMPORTSERVICE, corig);   
+	  if (import != NULL && import->value != NULL) 
+	    {
+#ifdef META_DB			
+	      service* s2=extractServiceFromDb(m,import->name,0);
+	      if(s2==NULL){
+#endif
+		s1 = createService();
+		t = readServiceFile (m, import->value, &s1, import->name);
+
+		if (t < 0) // failure reading zcfg
+		  {
+		    zDup2 (saved_stdout, fileno (stdout));
+		    exitAndCleanUp(zooRegistry, m,
+				   tmps,"InvalidParameterValue","identifier",
+				   orig,corig,
+				   funcError);
+                    return 1;
+		  }
+#ifdef DEBUG
+		dumpService (s1);
+#endif
+		inheritance(zooRegistry,&s1);
+#ifdef USE_HPC
+		addNestedOutputs(&s1);
+#endif
+		func (zooRegistry, m, doc, n, s1);
+		freeService (&s1);
+		free (s1);
+		s1 = NULL;
+		scount++;
+		hasVal = 1;                
+#ifdef META_DB
+	      }
+#endif
+	    }
+	  else if (strstr (corig, ".") != NULL)
+	    {
+	      parseIdentifier (m, conf_dir, corig, buff1);
+	      map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
+	      if (tmpMap != NULL)
+		addToMap (request_inputs, "metapath", tmpMap->value);
+	      map *tmpMapI = getMapFromMaps (m, "lenv", "Identifier");
+	      /**
+	       * No support for dot in service name stored in metadb!?
+	       #ifdef META_DB
+	       service* s2=extractServiceFromDb(m,tmpMapI->value,0);
+	       if(s2==NULL){
+	       #endif
+	      */
+	      s1 = createService();
+	      t = readServiceFile (m, buff1, &s1, tmpMapI->value);
+	      if (t < 0)
+		{
+		  zDup2 (saved_stdout, fileno (stdout));
+		  exitAndCleanUp(zooRegistry, m,
+				 tmps,"InvalidParameterValue","identifier",
+				 orig,corig,
+				 funcError);
+		  return 1;
+		}
+#ifdef DEBUG
+	      dumpService (s1);
+#endif
+	      inheritance(zooRegistry,&s1);
+#ifdef USE_HPC
+	      addNestedOutputs(&s1);
+#endif
+	      func (zooRegistry, m, doc, n, s1);
+	      freeService (&s1);
+	      free (s1);
+	      s1 = NULL;
+	      scount++;
+	      hasVal = 1;
+	      setMapInMaps (m, "lenv", "level", "0");
+	    }
+	  else
+	    {
+#ifdef META_DB
+	      _init_sql(m,"metadb");
+	      //FAILED CONNECTING DB
+	      if(getMapFromMaps(m,"lenv","dbIssue")!=NULL){
+		fprintf(stderr,"ERROR CONNECTING METADB");
+	      }
+	      service* s2=extractServiceFromDb(m,corig,0);
+	      if(s2!=NULL){
+		inheritance(zooRegistry,&s2);
+#ifdef USE_HPC
+		addNestedOutputs(&s2);
+#endif
+		func (zooRegistry,m, doc, n, s2);
+		freeService (&s2);
+		free (s2);
+		s2 = NULL;
+		hasVal = 1;
+	      }else /*TOTO*/{
+#endif
+		memset (buff, 0, 256);
+		snprintf (buff, 256, "%s.zcfg", corig);
+		memset (buff1, 0, 1024);
+#ifdef DEBUG
+		printf ("\n#######%s\n########\n", buff);
+#endif
+		while ((dp = readdir (dirp)) != NULL)
+		  {
+		    if (strcasecmp (dp->d_name, buff) == 0)
+		      {
+			memset (buff1, 0, 1024);
+			snprintf (buff1, 1024, "%s/%s", conf_dir,
+				  dp->d_name);
+			s1 = createService();
+			if (s1 == NULL)
+			  {
+			    zDup2 (saved_stdout, fileno (stdout));
+			    map* errormap = createMap("text", _("Unable to allocate memory"));
+			    addToMap(errormap,"code", "InternalError");
+			    addToMap(errormap,"locator", "NULL");
+			    funcError(m,errormap);
+			    return -1;
+			  }
+#ifdef DEBUG_SERVICE_CONF
+			fprintf
+			  (stderr,"#################\n(%s) %s\n#################\n",
+			   r_inputs->value, buff1);
+#endif
+			char *tmp0 = zStrdup (dp->d_name);
+			tmp0[strlen (tmp0) - 5] = 0;
+			t = readServiceFile (m, buff1, &s1, tmp0);
+			free (tmp0);
+			if (t < 0)
+			  {
+			    zDup2 (saved_stdout, fileno (stdout));
+			    exitAndCleanUp(zooRegistry, m,
+					   buff,"InternalError","NULL",
+					   orig,corig,
+					   funcError);
+			    return 1;
+			  }
+#ifdef DEBUG
+			dumpService (s1);
+#endif
+			inheritance(zooRegistry,&s1);
+#ifdef USE_HPC
+			addNestedOutputs(&s1);
+#endif
+			func (zooRegistry,m, doc, n, s1);
+			freeService (&s1);
+			free (s1);
+			s1 = NULL;
+			scount++;
+			hasVal = 1;
+		      }
+		  }
+#ifdef META_DB
+	      }
+#endif
+	    }		      
+	  if (hasVal < 0)
+	    {
+	      zDup2 (saved_stdout, fileno (stdout));
+	      exitAndCleanUp(zooRegistry, m,
+			     buff,"InvalidParameterValue","Identifier",
+			     orig,corig,
+			     funcError);
+	      return 1;
+	    }
+	  rewinddir (dirp);
+	  tmps = strtok_r (NULL, ",", &saveptr);
+	  if (corig != NULL)
+	    free (corig);
+	}		  
+    }
+  fflush (stdout);
+  zDup2 (saved_stdout, fileno (stdout));
+  free (orig);
+  return 0;
+}
+
+/**
+ * Run every HTTP request to download inputs passed as reference
+ *
+ * @param conf the maps pointing to the main.cfg file content
+ * @param inputs the maps pointing to the inputs provided in the request
+ */
+int loadHttpRequests(maps* conf,maps* inputs){
+  // Resolve reference
+  // TODO: add erro gesture
+  int eres;
+  maps* tmpMaps=getMaps(conf,"http_requests");
+  if(tmpMaps!=NULL){
+    map* lenMap=getMap(tmpMaps->content,"length");
+    int len=0;
+    if(lenMap!=NULL){
+      len=atoi(lenMap->value);
+    }
+    HINTERNET hInternet;
+    HINTERNET res;
+    if(len>0)
+      hInternet = InternetOpen (
+#ifndef WIN32
+				(LPCTSTR)
+#endif
+				"ZOO-Project WPS Client\0",
+				INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
+    for(int j=0;j<len;j++){
+      map* tmpUrl=getMapArray(tmpMaps->content,"url",j);
+      map* tmpInput=getMapArray(tmpMaps->content,"input",j);
+      maps* currentMaps=getMaps(inputs,tmpInput->value);
+      loadRemoteFile(&conf,&currentMaps->content,&hInternet,tmpUrl->value);
+      addIntToMap(currentMaps->content,"Order",hInternet.nb);
+      addToMap(currentMaps->content,"Reference",tmpUrl->value);
+    }
+    if(len>0){
+      map* error=NULL;
+      runHttpRequests(&conf,&inputs,&hInternet,&error);
+      InternetCloseHandle(&hInternet);
+    }
+  }
+  return 0;
+}
+
+/**
+ * Initialize environment sections, load env, and populate lenv and renv.
+ *
+ * @param conf the maps pointing to the main.cfg file content
+ * @param request_inputs the map pointing to the request KVP 
+ * @param cPath a string pointing to the cwd
+ * @param request a string pointing to the request key (xrequest or jrequest)
+ */
+void initAllEnvironment(maps* conf,map* request_inputs,
+			const char* cPath,const char* request){
+  // Define each env variable in runing environment
+  maps *curs = getMaps (conf, "env");
+  if (curs != NULL) {
+    map *mapcs = curs->content;
+    while (mapcs != NULLMAP)
+      {
+#ifndef WIN32
+	setenv (mapcs->name, mapcs->value, 1);
+#ifdef DEBUG
+	fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
+		 mapcs->value);
+#endif
+#else
+	if (mapcs->value[strlen (mapcs->value) - 2] == '\r')
+	  {
+#ifdef DEBUG
+	    fprintf (stderr, "[ZOO: Env var finish with \r]\n");
+#endif
+	    mapcs->value[strlen (mapcs->value) - 1] = 0;
+	  }
+#ifdef DEBUG
+	if (SetEnvironmentVariable (mapcs->name, mapcs->value) == 0)
+	  {
+	    fflush (stderr);
+	    fprintf (stderr, "setting variable... %s\n", "OK");
+	  }
+	else
+	  {
+	    fflush (stderr);
+	    fprintf (stderr, "setting variable... %s\n", "OK");
+	  }
+#else
+	SetEnvironmentVariable (mapcs->name, mapcs->value);
+#endif
+	char *toto =
+	  (char *)
+	  malloc ((strlen (mapcs->name) + strlen (mapcs->value) +
+		   2) * sizeof (char));
+	sprintf (toto, "%s=%s", mapcs->name, mapcs->value);
+	_putenv (toto);
+#ifdef DEBUG
+	fflush (stderr);
+#endif
+#endif
+
+#ifdef DEBUG
+	fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
+		 mapcs->value);
+	fflush (stderr);
+#endif
+	mapcs = mapcs->next;
+      }
+  }
+
+	    
+
+  int eres = SERVICE_STARTED;
+  int cpid = zGetpid ();
+
+  // Create a map containing a copy of the request map
+  maps *_tmpMaps = createMaps("request");
+  addMapToMap(&_tmpMaps->content,request_inputs);
+  addMapsToMaps (&conf, _tmpMaps);
+  freeMaps (&_tmpMaps);
+  free (_tmpMaps);
+  /**
+   * Initialize the specific [lenv] section which contains runtime variables:
+   * 
+   *  - usid : it is an universally unique identifier  
+   *  - osid : it is an idenfitication number 
+   *  - sid : it is the process idenfitication number (OS)
+   *  - uusid : it is an universally unique identifier 
+   *  - status : value between 0 and 100 to express the  completude of 
+   * the operations of the running service 
+   *  - message : is a string where you can store error messages, in case 
+   * service is failing, or o provide details on the ongoing operation.
+   *  - cwd : the current working directory or servicePath if defined
+   *  - soap : is a boolean value, true if the request was contained in a SOAP 
+   * Envelop 
+   *  - sessid : string storing the session identifier (only when cookie is 
+   * used)
+   *  - cgiSid : only defined on Window platforms (for being able to identify 
+   * the created process)
+   *
+   */
+  _tmpMaps = createMaps("lenv");
+  char tmpBuff[100];
+  struct ztimeval tp;
+  if (zGettimeofday (&tp, NULL) == 0)
+    sprintf (tmpBuff, "%i", (cpid + ((int) tp.tv_sec + (int) tp.tv_usec)));
+  else
+    sprintf (tmpBuff, "%i", (cpid + (int) time (NULL)));
+  _tmpMaps->content = createMap ("osid", tmpBuff);
+  sprintf (tmpBuff, "%i", cpid);
+  addToMap (_tmpMaps->content, "sid", tmpBuff);
+  char* tmpUuid=get_uuid();
+  addToMap (_tmpMaps->content, "uusid", tmpUuid);
+  addToMap (_tmpMaps->content, "usid", tmpUuid);
+  free(tmpUuid);
+  addToMap (_tmpMaps->content, "status", "0");
+  map* cwdMap0=getMapFromMaps(conf,"main","servicePath");
+  if(cwdMap0!=NULL){
+    addToMap (_tmpMaps->content, "cwd", cwdMap0->value);
+    addToMap (_tmpMaps->content, "rcwd", cPath);
+  }
+  else
+    addToMap (_tmpMaps->content, "cwd", cPath);
+  addToMap (_tmpMaps->content, "message", _("No message provided"));
+  map *ltmp = getMap (request_inputs, "soap");
+  if (ltmp != NULL)
+    addToMap (_tmpMaps->content, "soap", ltmp->value);
+  else
+    addToMap (_tmpMaps->content, "soap", "false");
+
+  // Parse the session file and add it to the main maps
+  char* originalCookie=NULL;
+  if (cgiCookie != NULL && strlen (cgiCookie) > 0)
+    {
+      int hasValidCookie = -1;
+      char *tcook = originalCookie = zStrdup (cgiCookie);
+      map *testing = getMapFromMaps (conf, "main", "cookiePrefix");
+      parseCookie(&conf,originalCookie);
+      map *sessId=getMapFromMaps(conf,"cookies",
+				 (testing==NULL?"ID":testing->value));
+      if (sessId!=NULL)
+	{
+	  addToMap (_tmpMaps->content, "sessid", sessId->value);
+	  char session_file_path[1024];
+	  map *tmpPath = getMapFromMaps (conf, "main", "sessPath");
+	  if (tmpPath == NULL)
+	    tmpPath = getMapFromMaps (conf, "main", "tmpPath");
+	  char *tmp1 = strtok (tcook, ";");
+	  if (tmp1 != NULL)
+	    sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
+		     sessId->value);
+	  else
+	    sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
+		     sessId->value);
+	  free (tcook);
+	  maps *tmpSess = (maps *) malloc (MAPS_SIZE);
+	  tmpSess->child=NULL;
+	  struct stat file_status;
+	  int istat = stat (session_file_path, &file_status);
+	  if (istat == 0 && file_status.st_size > 0)
+	    {
+	      int saved_stdout = zDup (fileno (stdout));
+	      zDup2 (fileno (stderr), fileno (stdout));
+	      conf_read (session_file_path, tmpSess);
+	      addMapsToMaps (&conf, tmpSess);
+	      freeMaps (&tmpSess);
+	      fflush(stdout);
+	      zDup2 (saved_stdout, fileno (stdout));
+	      zClose(saved_stdout);
+	    }
+	  free (tmpSess);
+	}
+    }
+  addMapsToMaps (&conf, _tmpMaps);
+  freeMaps (&_tmpMaps);
+  free (_tmpMaps);
+  maps* bmap=NULL;
+#ifdef DEBUG
+  dumpMap (request_inputs);
+#endif
+  int ei = 1;
+  
+  _tmpMaps = createMaps("renv");
+
+#ifdef WIN32
+  LPVOID orig = GetEnvironmentStrings();
+  LPTSTR s = (LPTSTR) orig;
+  
+  while (*s != NULL) {
+    char* env = strdup(s);
+    char* delim = strchr(env,'=');
+    if (delim != NULL) {
+      char* val = delim+1;
+      *delim = '\0';		
+      if(_tmpMaps->content == NULL) {
+        _tmpMaps->content = createMap(env,val);
+      }
+      else {
+        addToMap(_tmpMaps->content,env,val);
+      }			
+    }
+    s += strlen(s)+1;
+  } 
+  FreeEnvironmentStrings((LPCH)orig);	
+#else
+  char **orig = environ;
+  char *s=*orig;
+  
+  if(orig!=NULL)
+    for (; s; ei++ ) {
+      if(strstr(s,"=")!=NULL && strlen(strstr(s,"="))>1){
+	int len=strlen(s);
+	char* tmpName=zStrdup(s);
+	char* tmpValue=strstr(s,"=")+1;
+	char* tmpName1=(char*)malloc((1+(len-(strlen(tmpValue)+1)))*sizeof(char));
+	snprintf(tmpName1,(len-strlen(tmpValue)),"%s",tmpName);
+	if(_tmpMaps->content == NULL)
+	  _tmpMaps->content = createMap (tmpName1,tmpValue);
+	else
+	  addToMap (_tmpMaps->content,tmpName1,tmpValue);
+	free(tmpName1);
+	free(tmpName);
+      }
+      s = *(orig+ei);
+    }  
+#endif
+  
+  if(_tmpMaps->content!=NULL && getMap(_tmpMaps->content,"HTTP_COOKIE")!=NULL){
+    addToMap(_tmpMaps->content,"HTTP_COOKIE1",&cgiCookie[0]);
+  }
+  addMapsToMaps (&conf, _tmpMaps);
+  freeMaps (&_tmpMaps);
+  free (_tmpMaps);
+  map* postRequest=getMap(request_inputs,request);
+  if(postRequest!=NULL)
+    setMapInMaps (conf, "renv", request, postRequest->value);
+#ifdef WIN32
+  char *cgiSidL = NULL;
+  if (getenv ("CGISID") != NULL)
+    addToMap (request_inputs, "cgiSid", getenv ("CGISID"));
+
+  char* usidp;
+  if ( (usidp = getenv("USID")) != NULL ) {
+    setMapInMaps (conf, "lenv", "usid", usidp);
+  }
+
+  map *test1 = getMap (request_inputs, "cgiSid");
+  if (test1 != NULL){
+    cgiSid = zStrdup(test1->value);
+    addToMap (request_inputs, "storeExecuteResponse", "true");
+    addToMap (request_inputs, "status", "true");
+    setMapInMaps (conf, "lenv", "osid", test1->value);
+    status = getMap (request_inputs, "status");
+  }
+  test1 = getMap (request_inputs, "usid");
+  if (test1 != NULL){
+    setMapInMaps (conf, "lenv", "usid", test1->value);
+    setMapInMaps (conf, "lenv", "uusid", test1->value);
+  }
+#endif
+  
+}
+
+/**
  * Signal handling function which simply call exit(0).
  *
@@ -444,4 +1049,56 @@
   exit (0);
 }
+
+#ifdef USE_JSON
+  /**
+   * Signal handling function which create an ExceptionReport node containing the
+   * information message corresponding to the signal number.
+   *
+   * @param sig the signal number
+   */
+void json_sig_handler (int sig){
+  char tmp[100];
+  const char *ssig;
+  switch (sig)
+    {
+    case SIGSEGV:
+      ssig = "SIGSEGV";
+      break;
+    case SIGTERM:
+      ssig = "SIGTERM";
+      break;
+    case SIGINT:
+      ssig = "SIGINT";
+      break;
+    case SIGILL:
+      ssig = "SIGILL";
+      break;
+    case SIGFPE:
+      ssig = "SIGFPE";
+      break;
+    case SIGABRT:
+      ssig = "SIGABRT";
+      break;
+    default:
+      ssig = "UNKNOWN";
+      break;
+    }
+  sprintf (tmp,
+	   _
+	   ("ZOO Kernel failed to process your request, receiving signal %d = %s "),
+	   sig, ssig);
+  map* tmpMap=createMap("decode","suze");
+  maps* tmpMaps=createMaps("lenv");
+  setMapInMaps(tmpMaps,"lenv","message",tmp);
+  setMapInMaps(tmpMaps,"lenv","status","failed");
+  printExceptionReportResponseJ(tmpMaps,tmpMap);
+  //errorException (NULL, tmp, "InternalError", NULL);
+#ifdef DEBUG
+  fprintf (stderr, "Not this time!\n");
+#endif
+  exit (0);
+}
+  
+#endif
 
 /**
@@ -509,5 +1166,5 @@
 #ifdef WIN32
       HINSTANCE so =
-        LoadLibraryEx (tmps1, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);						
+        LoadLibraryEx (tmps1, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
 #else
       void *so = dlopen (tmps1, RTLD_LAZY);
@@ -974,5 +1631,5 @@
 runRequest (map ** inputs)
 {
-	
+ 
 #ifndef USE_GDB
 #ifndef WIN32
@@ -990,6 +1647,4 @@
   map *r_inputs = NULL;
   map *request_inputs = *inputs;
-  //fprintf(stderr,"%s \n",json_object_to_json_string_ext(mapToJson(request_inputs),JSON_C_TO_STRING_PLAIN));
-  
 #ifdef IGNORE_METAPATH
   addToMap(request_inputs, "metapath", "");
@@ -1021,12 +1676,4 @@
   char conf_file[10240];
   snprintf (conf_file, 10240, "%s/%s/main.cfg", ntmp, r_inputs->value);
-#ifdef ETC_DIR
-#ifndef WIN32
-  getcwd (ntmp, 1024);
-#else
-  _getcwd (ntmp, 1024);
-#endif
-#endif
-
   if (conf_read (conf_file, m) == 2)
     {
@@ -1064,4 +1711,7 @@
     fstde = freopen (fstdem->value, "a+", stderr);
 
+  /**
+   * Language gesture
+   */
   r_inputs = getMap (request_inputs, "language");
   if (r_inputs == NULL)
@@ -1160,5 +1810,8 @@
       fprintf(stderr,"*** %s ***\n",tmpUrl);
 #endif
-      setMapInMaps(m,"main","serverAddress",tmpUrl);
+      if(getMapFromMaps(m,"main","proxied")==NULL)
+	setMapInMaps(m,"main","serverAddress",tmpUrl);
+      else
+	setMapInMaps(m,"lenv","serverAddress",tmpUrl);
     }
 
@@ -1178,4 +1831,538 @@
   }
 
+  // Populate the Registry
+  char conf_dir[1024];
+  int t;
+  char tmps1[1024];
+  r_inputs = NULL;
+  r_inputs = getMap (request_inputs, "metapath");
+  map* cwdMap0=getMapFromMaps(m,"main","servicePath");
+  if (r_inputs != NULL)
+    if(cwdMap0!=NULL)
+      snprintf (conf_dir, 1024, "%s/%s", cwdMap0->value, r_inputs->value);
+    else
+      snprintf (conf_dir, 1024, "%s/%s", ntmp, r_inputs->value);
+  else
+    if(cwdMap0!=NULL)
+      snprintf (conf_dir, 1024, "%s", cwdMap0->value);
+    else
+      snprintf (conf_dir, 1024, "%s", ntmp);
+  map* reg = getMapFromMaps (m, "main", "registry");
+  registry* zooRegistry=NULL;
+  if(reg!=NULL){
+#ifndef WIN32
+    int saved_stdout = zDup (fileno (stdout));
+    zDup2 (fileno (stderr), fileno (stdout));
+#endif
+    if(createRegistry (m,&zooRegistry,reg->value)<0){
+      map *message=getMapFromMaps(m,"lenv","message");
+      map *type=getMapFromMaps(m,"lenv","type");
+#ifndef WIN32
+      zDup2 (saved_stdout, fileno (stdout));
+#endif
+      errorException (m, message->value,
+		      type->value, NULL);
+      return 0;
+    }
+#ifndef WIN32
+    zDup2 (saved_stdout, fileno (stdout));
+    zClose(saved_stdout);
+#endif
+  }
+  
+  setMapInMaps(m,"lenv","executionType","xml");
+  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);
+    return 1;
+#else
+#ifndef USE_GDB
+#ifndef WIN32
+    signal (SIGCHLD, SIG_IGN);
+#endif  
+    signal (SIGSEGV, json_sig_handler);
+    signal (SIGTERM, json_sig_handler);
+    signal (SIGINT, json_sig_handler);
+    signal (SIGILL, json_sig_handler);
+    signal (SIGFPE, json_sig_handler);
+    signal (SIGABRT, json_sig_handler);
+#endif
+    r_inputs = getMapOrFill (&request_inputs, "metapath", "");
+    char conf_file1[10240];
+    maps* m1 = (maps *) malloc (MAPS_SIZE);
+    snprintf (conf_file1, 10240, "%s/%s/oas.cfg", ntmp, r_inputs->value);
+    if (conf_read (conf_file1, m1) == 2)
+      {
+	errorException (NULL, _("Unable to load the oas.cfg file."),
+			"InternalError", NULL);
+	free (m);
+	return 1;
+      }
+    addMapsToMaps(&m,m1);
+    setMapInMaps(m,"lenv","executionType","json");
+
+    json_object *res=json_object_new_object();
+    setMapInMaps(m,"headers","Content-Type","application/json;charset=UTF-8");
+    /* - Root url */
+    if(cgiContentLength==1){
+      map* tmpMap=getMapFromMaps(m,"main","serverAddress");
+      json_object *res1=json_object_new_array();
+      const char* urls[4]={
+	"/","/api","/conformance","/processes"
+      };
+      map* tmpUrl=getMapFromMaps(m,"main","serverAddress");
+      for(int kk=0;kk<4;kk++){
+	maps* tmpMaps=getMaps(m,urls[kk]);
+	json_object *res2;
+	if(tmpMaps!=NULL){
+	  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));
+	  json_object_array_add(res1,res2);
+	}
+      }
+      json_object_object_add(res,"links",res1);
+    }else if(strcmp(cgiQueryString,"/conformance")==0){
+      /* - /conformance url */
+      map* rootUrl=getMapFromMaps(m,"conformTo","rootUrl");
+      json_object *res1=json_object_new_array();
+      map* length=getMapFromMaps(m,"conformTo","length");
+      maps* tmpMaps=getMaps(m,"conformTo");
+      for(int kk=0;kk<atoi(length->value);kk++){
+	map* tmpMap1=getMapArray(tmpMaps->content,"link",kk);
+	json_object *res2;
+	if(tmpMap1!=NULL){
+	  char* tmpStr=(char*) malloc((strlen(rootUrl->value)+strlen(tmpMap1->value)+1)*sizeof(char));
+	  sprintf(tmpStr,"%s%s",rootUrl->value,tmpMap1->value);
+	  json_object_array_add(res1,json_object_new_string(tmpStr));
+	}
+      }
+      json_object_object_add(res,"conformTo",res1);
+    }else if(strcmp(cgiQueryString,"/api")==0){
+      /* - /api url */
+      produceApi(m,res);
+    }else if(strcmp(cgiQueryString,"/processes")==0 || strcmp(cgiQueryString,"/processes/")==0){
+      /* - /processes */
+      json_object *res3=json_object_new_array();
+      int saved_stdout = zDup (fileno (stdout));
+      zDup2 (fileno (stderr), fileno (stdout));
+
+      if (int res =		  
+          recursReaddirF (m, NULL, res3, NULL, ntmp, NULL, saved_stdout, 0,
+			  printGetCapabilitiesForProcessJ) < 0)
+        {
+	}      
+      zDup2 (saved_stdout, fileno (stdout));
+      zClose(saved_stdout);
+      
+      json_object_object_add(res,"processes",res3);
+    }else{
+      service* s1=NULL;
+      int t=0;
+      if(strstr(cgiQueryString,"/processes/")==NULL){
+	map* error=createMap("code","BadRequest");
+	addToMap(error,"message",_("The ressource is not available"));
+	//setMapInMaps(conf,"lenv","status_code","404 Bad Request");
+	printExceptionReportResponseJ(m,error);
+	freeMaps (&m);
+	free (m);
+	free (REQUEST);
+	xmlCleanupParser ();
+	zooXmlCleanupNs ();			
+	return 1;
+      } else
+	if(strstr(cgiQueryString,"/jobs")==NULL && strstr(cgiQueryString,"/jobs/")==NULL){
+	  /* - /processes/{id}/ */
+	  DIR *dirp = opendir (ntmp);
+	  json_object *res3=json_object_new_object();
+	  char *orig = zStrdup (strstr(cgiQueryString,"/processes/")+11);
+	  if(orig[strlen(orig)-1]=='/')
+	    orig[strlen(orig)-1]=0;
+	  json_object* res1=json_object_new_object();
+	  int t=fetchServicesForDescription(NULL, m, orig,
+					    printGetCapabilitiesForProcessJ,
+					    NULL, (void*) res3, ntmp,
+					    request_inputs,
+					    printExceptionReportResponseJ);
+	  if(t==1){
+	    /*map* error=createMap("code","BadRequest");
+	    addToMap(error,"message",_("Failed to acces the requested service"));
+	    printExceptionReportResponseJ(m,error);*/
+	    return 1;
+	  }
+	  res=json_object_get(res3);
+	}else{	
+	  char* queryString=zStrdup(cgiQueryString);
+	  int len0=strlen(strstr(cgiQueryString,"/processes/")+11);
+	  int len1=strlen(cgiQueryString)-strlen(strstr(cgiQueryString,"/job"));
+	  char* cIdentifier=(char*)malloc((len1-10)*sizeof(char));
+	  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;
+	    cnt++;
+	  }
+	  char tmps1[1024];
+
+	  map* import = getMapFromMaps (m, IMPORTSERVICE, cIdentifier); 
+	  if (import != NULL && import->value != NULL) { 
+	    strncpy(tmps1, import->value, 1024);
+	    setMapInMaps (m, "lenv", "Identifier", cIdentifier);
+	    setMapInMaps (m, "lenv", "oIdentifier", cIdentifier);
+	  } 
+	  else {
+	    snprintf (tmps1, 1024, "%s/%s.zcfg", ntmp, cIdentifier);
+#ifdef DEBUG
+	    fprintf (stderr, "Trying to load %s\n", tmps1);
+#endif
+	    if (strstr (cIdentifier, ".") != NULL)
+	      {
+		char *identifier = zStrdup (cIdentifier);
+		parseIdentifier (m, ntmp, identifier, tmps1);
+		map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
+		if (tmpMap != NULL)
+		  addToMap (request_inputs, "metapath", tmpMap->value);
+		free (identifier);
+	      }
+	    else
+	      {
+		setMapInMaps (m, "lenv", "oIdentifier", cIdentifier);
+		setMapInMaps (m, "lenv", "Identifier", cIdentifier);
+	      }
+	  }
+
+	  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,cIdentifier,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);
+		map* error=createMap("code","InternalError");
+		addToMap(error,"message",_("Unable to allocate memory"));
+		//setMapInMaps(conf,"lenv","status_code","404 Bad Request");
+		printExceptionReportResponseJ(m,error);
+
+		return 1; /*errorException (m, _("Unable to allocate memory"),
+			    "InternalError", NULL);*/
+	      }
+
+	    int saved_stdout = zDup (fileno (stdout));
+	    zDup2 (fileno (stderr), fileno (stdout));
+	    t = readServiceFile (m, tmps1, &s1, cIdentifier);
+	    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);
+		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;
+	      }
+	    zClose (saved_stdout);
+	  
+#ifdef META_DB
+	  }
+#endif
+	  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__);
+	    }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;	      
+	      }
+	    }
+	  }else{
+	    /* - /jobs url */
+	    fprintf(stderr,"For Execute or Job list %s %d \n",__FILE__,__LINE__);
+	    if(strcasecmp(cgiRequestMethod,"get")==0){
+	      /* - /jobs List (GET) */
+	      res=printJobList(m);
+	    }else if(strcasecmp(cgiRequestMethod,"post")==0){
+	      /* - /jobs Execution (POST) */
+	      int eres = SERVICE_STARTED;
+
+	      initAllEnvironment(m,request_inputs,ntmp,"jrequest");
+	      map* req=getMapFromMaps(m,"renv","jrequest");
+	      json_object *jobj = NULL;
+	      const char *mystring = NULL;
+	      int slen = 0;
+	      enum json_tokener_error jerr;
+	      struct json_tokener* tok=json_tokener_new();
+	      do {
+		mystring = req->value;  // get JSON string, e.g. read from file, etc...
+		slen = strlen(mystring);
+		jobj = json_tokener_parse_ex(tok, mystring, slen);
+	      } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
+	      if (jerr != json_tokener_success) {
+		fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
+		return 1;
+	      }
+	      if (tok->char_offset < slen){
+		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);
+	      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;
+		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
+		  {
+		    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;
+		    createStatusFile(m,eres);
+		    printHeaders(m);
+		    printf("Status: 201 Created \r\n\r\n");
+		    return 1;
+		  }
+		else if (pid == 0)
+		  {
+		    eres = SERVICE_STARTED;
+		    //
+		    // 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);
+		    maps* 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
+#ifdef USE_CALLBACK
+		    invokeCallback(m,NULL,NULL,0,0);
+#endif
+		    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+		    fflush(stderr);
+		    
+		    createStatusFile(m,eres);
+		    	  
+		  
+		    fbkp1 =
+		      (char *)
+		      malloc ((strlen (r_inputs->value) + strlen (r_inputs1->value) +
+			       strlen (usid->value) + 15) * sizeof (char));
+		    sprintf (fbkp1, "%s/%s_final_%s.json", 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);
+
+		    map* testMap=getMapFromMaps(m,"main","memory");
+		    loadHttpRequests(m,inputs_real_format);
+		    loadServiceAndRun (&m, s1, request_inputs,
+				       &inputs_real_format,
+				       &outputs_real_format, &eres);
+		    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;
+
+		  }
+	      }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;
+	      }
+
+	    
+	    }//else error
+	    
+	  }
+	}
+    }
+    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");
@@ -1282,4 +2469,5 @@
 
 
+
   service *s1;
   int scount = 0;
@@ -1287,46 +2475,7 @@
   dumpMap (r_inputs);
 #endif
-  char conf_dir[1024];
-  int t;
-  char tmps1[1024];
-
-  r_inputs = NULL;
-  r_inputs = getMap (request_inputs, "metapath");
-  map* cwdMap0=getMapFromMaps(m,"main","servicePath");
-  if (r_inputs != NULL)
-    if(cwdMap0!=NULL)
-      snprintf (conf_dir, 1024, "%s/%s", cwdMap0->value, r_inputs->value);
-    else
-      snprintf (conf_dir, 1024, "%s/%s", ntmp, r_inputs->value);
-  else
-    if(cwdMap0!=NULL)
-      snprintf (conf_dir, 1024, "%s", cwdMap0->value);
-    else
-      snprintf (conf_dir, 1024, "%s", ntmp);
-  map* reg = getMapFromMaps (m, "main", "registry");
-  registry* zooRegistry=NULL;
-  if(reg!=NULL){
-#ifndef WIN32
-    int saved_stdout = zDup (fileno (stdout));
-    zDup2 (fileno (stderr), fileno (stdout));
-#endif
-    if(createRegistry (m,&zooRegistry,reg->value)<0){
-      map *message=getMapFromMaps(m,"lenv","message");
-      map *type=getMapFromMaps(m,"lenv","type");
-#ifndef WIN32
-      zDup2 (saved_stdout, fileno (stdout));
-#endif
-      errorException (m, message->value,
-		      type->value, NULL);
-      return 0;
-    }
-#ifndef WIN32
-    zDup2 (saved_stdout, fileno (stdout));
-    zClose(saved_stdout);
-#endif
-  }
-  
+
   if (strncasecmp (REQUEST, "GetCapabilities", 15) == 0)
-    {	
+    {
 #ifdef DEBUG
       dumpMap (r_inputs);
@@ -1396,5 +2545,5 @@
     }
   else
-    {	  
+    {
       r_inputs = getMap (request_inputs, "JobId");
       if(reqId>nbReqIdentifier){
@@ -1471,326 +2620,9 @@
 	    r_inputs = getMap (request_inputs, "Identifier");
 
-	    char *orig = zStrdup (r_inputs->value);
-
-	    int saved_stdout = zDup (fileno (stdout));
-	    zDup2 (fileno (stderr), fileno (stdout));
-	    if (strcasecmp ("all", orig) == 0)
-	      {
-		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;
-		      }
-		      inheritance(zooRegistry, &svc);
-#ifdef USE_HPC
-		      addNestedOutputs(&svc);
-#endif
-
-		      printDescribeProcessForProcess(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,
-				    printDescribeProcessForProcess) < 0)
-		  return res;
-#ifdef META_DB
-		fetchServicesFromDb(zooRegistry,m,doc,n,printDescribeProcessForProcess,0);
-		close_sql(m,0);
-#endif      
-
-	      }
-	    else
-	      {
-		char *saveptr;
-		char *tmps = strtok_r (orig, ",", &saveptr);
-
-		char buff[256];
-		char buff1[1024];
-		while (tmps != NULL)
-		  {
-		    int hasVal = -1;
-		    char *corig = zStrdup (tmps);
-		    map* import = getMapFromMaps (m, IMPORTSERVICE, corig);   
-		    if (import != NULL && import->value != NULL) 
-		      {
-#ifdef META_DB			
-			service* s2=extractServiceFromDb(m,import->name,0);
-			if(s2==NULL){
-#endif
-			  s1 = createService();
-			  t = readServiceFile (m, import->value, &s1, import->name);
-
-			  if (t < 0) // failure reading zcfg
-			    {
-			      map *tmp00 = getMapFromMaps (m, "lenv", "message");
-			      char tmp01[1024];
-			      if (tmp00 != NULL)
-				sprintf (tmp01, _("Unable to parse the ZCFG file: %s (%s)"), import->value, tmp00->value);
-			      else
-				sprintf (tmp01, _("Unable to parse the ZCFG file: %s."), import->value);
-			      
-			      zDup2 (saved_stdout, fileno (stdout));
-			      errorException (m, tmp01, "InternalError", NULL);
-			      
-			      freeMaps (&m);
-			      free (m);
-
-			      if(zooRegistry!=NULL){
-				freeRegistry(&zooRegistry);
-				free(zooRegistry);
-			      }
-			      free (orig);
-			      free (REQUEST);
-			      closedir (dirp);
-			      //xmlFreeDoc (doc);
-			      xmlCleanupParser ();
-			      zooXmlCleanupNs ();
-                    
-			      return 1;
-			    }
-#ifdef DEBUG
-			  dumpService (s1);
-#endif
-			  inheritance(zooRegistry,&s1);
-#ifdef USE_HPC
-			  addNestedOutputs(&s1);
-#endif
-			  printDescribeProcessForProcess (zooRegistry, m, doc, n, s1);
-			  freeService (&s1);
-			  free (s1);
-			  s1 = NULL;
-			  scount++;
-			  hasVal = 1;                
-#ifdef META_DB
-			}
-#endif
-		      }
-		    else if (strstr (corig, ".") != NULL)
-		      {
-
-			parseIdentifier (m, conf_dir, corig, buff1);
-			map *tmpMap = getMapFromMaps (m, "lenv", "metapath");
-			if (tmpMap != NULL)
-			  addToMap (request_inputs, "metapath", tmpMap->value);
-			map *tmpMapI = getMapFromMaps (m, "lenv", "Identifier");
-			/**
-			 * No support for dot in service name stored in metadb!?
-		//	 #ifdef META_DB
-			 service* s2=extractServiceFromDb(m,tmpMapI->value,0);
-			 if(s2==NULL){
-		//	 #endif
-			*/
-			s1 = createService();
-			t = readServiceFile (m, buff1, &s1, tmpMapI->value);
-			if (t < 0)
-			  {
-			    map *tmp00 = getMapFromMaps (m, "lenv", "message");
-			    char tmp01[1024];
-			    if (tmp00 != NULL)
-			      sprintf (tmp01,
-				       _
-				       ("Unable to parse the ZCFG file for the following ZOO-Service: %s. Message: %s"),
-				       tmps, tmp00->value);
-			    else
-			      sprintf (tmp01,
-				       _
-				       ("Unable to parse the ZCFG file for the following ZOO-Service: %s."),
-				       tmps);
-			    zDup2 (saved_stdout, fileno (stdout));
-			    errorException (m, tmp01, "InvalidParameterValue",
-					    "identifier");
-			    freeMaps (&m);
-			    free (m);
-			    if(zooRegistry!=NULL){
-			      freeRegistry(&zooRegistry);
-			      free(zooRegistry);
-			    }
-			    free (REQUEST);
-			    free (corig);
-			    free (orig);
-			    free (SERVICE_URL);
-			    free (s1);
-			    closedir (dirp);
-			    //xmlFreeDoc (doc);
-			    xmlCleanupParser ();
-			    zooXmlCleanupNs ();
-			    return 1;
-			  }
-#ifdef DEBUG
-			dumpService (s1);
-#endif
-			inheritance(zooRegistry,&s1);
-#ifdef USE_HPC
-			addNestedOutputs(&s1);
-#endif
-			printDescribeProcessForProcess (zooRegistry, m, doc, n, s1);
-			freeService (&s1);
-			free (s1);
-			s1 = NULL;
-			scount++;
-			hasVal = 1;
-			setMapInMaps (m, "lenv", "level", "0");
-		      }
-		    else
-		      {
-#ifdef META_DB
-			_init_sql(m,"metadb");
-			//FAILED CONNECTING DB
-			if(getMapFromMaps(m,"lenv","dbIssue")!=NULL){
-			  fprintf(stderr,"ERROR CONNECTING METADB");
-			}
-			service* s2=extractServiceFromDb(m,corig,0);
-			if(s2!=NULL){
-			  inheritance(zooRegistry,&s2);
-#ifdef USE_HPC
-			  addNestedOutputs(&s2);
-#endif
-			  printDescribeProcessForProcess (zooRegistry,m, doc, n, s2);
-			  freeService (&s2);
-			  free (s2);
-			  s2 = NULL;
-			  hasVal = 1;
-			}else /*TOTO*/{
-#endif
-			  memset (buff, 0, 256);
-			  snprintf (buff, 256, "%s.zcfg", corig);
-			  memset (buff1, 0, 1024);
-#ifdef DEBUG
-			  printf ("\n#######%s\n########\n", buff);
-#endif
-			  while ((dp = readdir (dirp)) != NULL)
-			    {
-			      if (strcasecmp (dp->d_name, buff) == 0)
-				{
-				  memset (buff1, 0, 1024);
-				  snprintf (buff1, 1024, "%s/%s", conf_dir,
-					    dp->d_name);
-				  s1 = createService();
-				  if (s1 == NULL)
-				    {
-				      zDup2 (saved_stdout, fileno (stdout));
-				      return errorException (m,
-							     _
-							     ("Unable to allocate memory"),
-							     "InternalError",
-							     NULL);
-				    }
-#ifdef DEBUG_SERVICE_CONF
-				  fprintf
-				    (stderr,"#################\n(%s) %s\n#################\n",
-				     r_inputs->value, buff1);
-#endif
-				  char *tmp0 = zStrdup (dp->d_name);
-				  tmp0[strlen (tmp0) - 5] = 0;
-				  t = readServiceFile (m, buff1, &s1, tmp0);
-				  free (tmp0);
-				  if (t < 0)
-				    {
-				      map *tmp00 =
-					getMapFromMaps (m, "lenv", "message");
-				      char tmp01[1024];
-				      if (tmp00 != NULL)
-					sprintf (tmp01,
-						 _
-						 ("Unable to parse the ZCFG file: %s (%s)"),
-						 dp->d_name, tmp00->value);
-				      else
-					sprintf (tmp01,
-						 _
-						 ("Unable to parse the ZCFG file: %s."),
-						 dp->d_name);
-				      zDup2 (saved_stdout, fileno (stdout));
-				      errorException (m, tmp01, "InternalError",
-						      NULL);
-				      freeMaps (&m);
-				      free (m);
-				      if(zooRegistry!=NULL){
-					freeRegistry(&zooRegistry);
-					free(zooRegistry);
-				      }
-				      free (orig);
-				      free (REQUEST);
-				      closedir (dirp);
-				      //xmlFreeDoc (doc);
-				      xmlCleanupParser ();
-				      zooXmlCleanupNs ();
-				      return 1;
-				    }
-#ifdef DEBUG
-				  dumpService (s1);
-#endif
-				  inheritance(zooRegistry,&s1);
-#ifdef USE_HPC
-				  addNestedOutputs(&s1);
-#endif
-				  /*json_object* jobj=serviceToJson(s1);
-				  const char* jsonStr=json_object_to_json_string_ext(jobj,JSON_C_TO_STRING_PLAIN);
-				  fprintf(stderr,"*** %s %d %s \n",__FILE__,__LINE__,jsonStr);*/
-
-				  printDescribeProcessForProcess (zooRegistry,m, doc, n, s1);
-				  freeService (&s1);
-				  free (s1);
-				  s1 = NULL;
-				  scount++;
-				  hasVal = 1;
-				}
-			    }
-#ifdef META_DB
-			}
-#endif
-		      }		      
-		    if (hasVal < 0)
-		      {
-			map *tmp00 = getMapFromMaps (m, "lenv", "message");
-			char tmp01[1024];
-			if (tmp00 != NULL)
-			  sprintf (tmp01,
-				   _("Unable to parse the ZCFG file: %s (%s)"),
-				   buff, tmp00->value);
-			else
-			  sprintf (tmp01,
-				   _("Unable to parse the ZCFG file: %s."),
-				   buff);
-			zDup2 (saved_stdout, fileno (stdout));
-			errorException (m, tmp01, "InvalidParameterValue",
-					"Identifier");
-			freeMaps (&m);
-			free (m);
-			if(zooRegistry!=NULL){
-			  freeRegistry(&zooRegistry);
-			  free(zooRegistry);
-			}
-			free (orig);
-			free (REQUEST);
-			closedir (dirp);
-			if (corig != NULL)
-			  free (corig);
-			xmlFreeDoc (doc);
-			xmlCleanupParser ();
-			zooXmlCleanupNs ();
-			return 1;
-		      }
-		    rewinddir (dirp);
-		    tmps = strtok_r (NULL, ",", &saveptr);
-		    if (corig != NULL)
-		      free (corig);
-		  }		  
-	      }
-	    closedir (dirp);
-	    fflush (stdout);
-	    zDup2 (saved_stdout, fileno (stdout));
-	    free (orig);
+	    fetchServicesForDescription(zooRegistry, m, r_inputs->value,
+					printDescribeProcessForProcess,
+					(void*) doc, (void*) n, conf_dir,
+					request_inputs,printExceptionReportResponse);
+
 	    printDocument (m, doc, zGetpid ());
 	    freeMaps (&m);
@@ -1810,5 +2642,5 @@
 	  }
 	else if (strncasecmp (REQUEST, "Execute", strlen (REQUEST)) != 0)
-	  {	  
+	  {
 	    map* version=getMapFromMaps(m,"main","rversion");
 	    int vid=getVersionId(version->value);	    
@@ -1867,5 +2699,5 @@
       }
     }
-	
+
   map *postRequest = NULL;
   postRequest = getMap (request_inputs, "xrequest");
@@ -1950,5 +2782,5 @@
 			       "InternalError", NULL);
       }
-  
+
     int saved_stdout = zDup (fileno (stdout));
     zDup2 (fileno (stderr), fileno (stdout));
@@ -2024,64 +2856,12 @@
   }
   //InternetCloseHandle (&hInternet);
-  
-  // Define each env variable in runing environment
-  maps *curs = getMaps (m, "env");
-  if (curs != NULL)
-    {
-      map *mapcs = curs->content;
-      while (mapcs != NULLMAP)
-        {
-#ifndef WIN32
-          setenv (mapcs->name, mapcs->value, 1);
-#ifdef DEBUG
-          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
-                   mapcs->value);
-#endif
-#else
-          if (mapcs->value[strlen (mapcs->value) - 2] == '\r')
-            {
-#ifdef DEBUG
-              fprintf (stderr, "[ZOO: Env var finish with \r]\n");
-#endif
-              mapcs->value[strlen (mapcs->value) - 1] = 0;
-            }
-#ifdef DEBUG
-          if (SetEnvironmentVariable (mapcs->name, mapcs->value) == 0)
-            {
-              fflush (stderr);
-              fprintf (stderr, "setting variable... %s\n", "OK");
-            }
-          else
-            {
-              fflush (stderr);
-              fprintf (stderr, "setting variable... %s\n", "OK");
-            }
-#else
-          SetEnvironmentVariable (mapcs->name, mapcs->value);
-#endif
-          char *toto =
-            (char *)
-            malloc ((strlen (mapcs->name) + strlen (mapcs->value) +
-                     2) * sizeof (char));
-          sprintf (toto, "%s=%s", mapcs->name, mapcs->value);
-          _putenv (toto);
-#ifdef DEBUG
-          fflush (stderr);
-#endif
-#endif
-
-#ifdef DEBUG
-          fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
-                   mapcs->value);
-          fflush (stderr);
-#endif
-          mapcs = mapcs->next;
-        }
-    }
+
+  initAllEnvironment(m,request_inputs,ntmp,"xrequest");
+
 
 #ifdef DEBUG
   dumpMap (request_inputs);
 #endif
-  
+
   map *status = getMap (request_inputs, "status");
   if(vid==0){
@@ -2164,193 +2944,6 @@
   int eres = SERVICE_STARTED;
   int cpid = zGetpid ();
-  
-  // Create a map containing a copy of the request map
-  maps *_tmpMaps = createMaps("request");
-  addMapToMap(&_tmpMaps->content,request_inputs);
-  addMapsToMaps (&m, _tmpMaps);
-  freeMaps (&_tmpMaps);
-  free (_tmpMaps);
-  /**
-   * Initialize the specific [lenv] section which contains runtime variables:
-   * 
-   *  - usid : it is an universally unique identifier  
-   *  - osid : it is an idenfitication number 
-   *  - sid : it is the process idenfitication number (OS)
-   *  - uusid : it is an universally unique identifier 
-   *  - status : value between 0 and 100 to express the  completude of 
-   * the operations of the running service 
-   *  - message : is a string where you can store error messages, in case 
-   * service is failing, or o provide details on the ongoing operation.
-   *  - cwd : the current working directory or servicePath if defined
-   *  - soap : is a boolean value, true if the request was contained in a SOAP 
-   * Envelop 
-   *  - sessid : string storing the session identifier (only when cookie is 
-   * used)
-   *  - cgiSid : only defined on Window platforms (for being able to identify 
-   * the created process)
-   *
-   */
-  _tmpMaps = createMaps("lenv");
-  char tmpBuff[100];
-  struct ztimeval tp;
-  if (zGettimeofday (&tp, NULL) == 0)
-    sprintf (tmpBuff, "%i", (cpid + ((int) tp.tv_sec + (int) tp.tv_usec)));
-  else
-    sprintf (tmpBuff, "%i", (cpid + (int) time (NULL)));
-  _tmpMaps->content = createMap ("osid", tmpBuff);
-  sprintf (tmpBuff, "%i", cpid);
-  addToMap (_tmpMaps->content, "sid", tmpBuff);
-  char* tmpUuid=get_uuid();
-  addToMap (_tmpMaps->content, "uusid", tmpUuid);
-  addToMap (_tmpMaps->content, "usid", tmpUuid);
-  free(tmpUuid);
-  addToMap (_tmpMaps->content, "status", "0");
-  if(cwdMap0!=NULL){
-    addToMap (_tmpMaps->content, "cwd", cwdMap0->value);
-    addToMap (_tmpMaps->content, "rcwd", ntmp);
-  }
-  else
-    addToMap (_tmpMaps->content, "cwd", ntmp);
-  addToMap (_tmpMaps->content, "message", _("No message provided"));
-  map *ltmp = getMap (request_inputs, "soap");
-  if (ltmp != NULL)
-    addToMap (_tmpMaps->content, "soap", ltmp->value);
-  else
-    addToMap (_tmpMaps->content, "soap", "false");
-  
-  // Parse the session file and add it to the main maps
-  char* originalCookie=NULL;
-  if (cgiCookie != NULL && strlen (cgiCookie) > 0)
-    {
-      int hasValidCookie = -1;
-      char *tcook = originalCookie = zStrdup (cgiCookie);
-      map *testing = getMapFromMaps (m, "main", "cookiePrefix");
-      parseCookie(&m,originalCookie);
-      map *sessId=getMapFromMaps(m,"cookies",(testing==NULL?"ID":testing->value));
-      if (sessId!=NULL)
-        {
-	  addToMap (_tmpMaps->content, "sessid", sessId->value);
-          char session_file_path[1024];
-          map *tmpPath = getMapFromMaps (m, "main", "sessPath");
-          if (tmpPath == NULL)
-            tmpPath = getMapFromMaps (m, "main", "tmpPath");
-          char *tmp1 = strtok (tcook, ";");
-          if (tmp1 != NULL)
-            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
-                     sessId->value);
-          else
-            sprintf (session_file_path, "%s/sess_%s.cfg", tmpPath->value,
-                     sessId->value);
-          free (tcook);
-          maps *tmpSess = (maps *) malloc (MAPS_SIZE);
-	  tmpSess->child=NULL;
-          struct stat file_status;
-          int istat = stat (session_file_path, &file_status);
-          if (istat == 0 && file_status.st_size > 0)
-            {
-	      int saved_stdout = zDup (fileno (stdout));
-	      zDup2 (fileno (stderr), fileno (stdout));
-              conf_read (session_file_path, tmpSess);
-              addMapsToMaps (&m, tmpSess);
-              freeMaps (&tmpSess);
-	      fflush(stdout);
-	      zDup2 (saved_stdout, fileno (stdout));
-	      zClose(saved_stdout);
-            }
-	  free (tmpSess);
-        }
-    }
-  addMapsToMaps (&m, _tmpMaps);
-  freeMaps (&_tmpMaps);
-  free (_tmpMaps);
+
   maps* bmap=NULL;
-#ifdef DEBUG
-  dumpMap (request_inputs);
-#endif
-  int ei = 1;
- 
-  _tmpMaps = createMaps("renv");	
-
-#ifdef WIN32
-  LPVOID orig = GetEnvironmentStrings();
-  LPTSTR s = (LPTSTR) orig;
-  
-  while (*s != NULL) {
-    char* env = strdup(s);
-    char* delim = strchr(env,'=');
-    if (delim != NULL) {
-      char* val = delim+1;
-      *delim = '\0';		
-      if(_tmpMaps->content == NULL) {
-        _tmpMaps->content = createMap(env,val);
-      }
-      else {
-        addToMap(_tmpMaps->content,env,val);
-      }			
-    }
-    s += strlen(s)+1;
-  } 
-  FreeEnvironmentStrings((LPCH)orig);	
-#else
-  char **orig = environ;
-  char *s=*orig;
-  
-  if(orig!=NULL)
-    for (; 
-       s;
-       ei++
-       ) {
-    if(strstr(s,"=")!=NULL && strlen(strstr(s,"="))>1){
-      int len=strlen(s);
-      char* tmpName=zStrdup(s);
-      char* tmpValue=strstr(s,"=")+1;
-      char* tmpName1=(char*)malloc((1+(len-(strlen(tmpValue)+1)))*sizeof(char));
-      snprintf(tmpName1,(len-strlen(tmpValue)),"%s",tmpName);
-      if(_tmpMaps->content == NULL)
-	_tmpMaps->content = createMap (tmpName1,tmpValue);
-      else
-	addToMap (_tmpMaps->content,tmpName1,tmpValue);
-      free(tmpName1);
-      free(tmpName);
-    }
-    s = *(orig+ei);
-  }  
-#endif
- 
-  if(_tmpMaps->content!=NULL && getMap(_tmpMaps->content,"HTTP_COOKIE")!=NULL){
-    addToMap(_tmpMaps->content,"HTTP_COOKIE1",&cgiCookie[0]);
-  }
-  addMapsToMaps (&m, _tmpMaps);
-  freeMaps (&_tmpMaps);
-  free (_tmpMaps);
-
-  if(postRequest!=NULL)
-    setMapInMaps (m, "renv", "xrequest", postRequest->value);
-  //dumpMaps(m);
-#ifdef WIN32
-  char *cgiSidL = NULL;
-  if (getenv ("CGISID") != NULL)
-    addToMap (request_inputs, "cgiSid", getenv ("CGISID"));
-
-  char* usidp;
-  if ( (usidp = getenv("USID")) != NULL ) {
-    setMapInMaps (m, "lenv", "usid", usidp);
-  }
-
-  map *test1 = getMap (request_inputs, "cgiSid");
-  if (test1 != NULL){
-    cgiSid = zStrdup(test1->value);
-    addToMap (request_inputs, "storeExecuteResponse", "true");
-    addToMap (request_inputs, "status", "true");
-    setMapInMaps (m, "lenv", "osid", test1->value);
-    status = getMap (request_inputs, "status");
-  }
-  test1 = getMap (request_inputs, "usid");
-  if (test1 != NULL){
-    setMapInMaps (m, "lenv", "usid", test1->value);
-    setMapInMaps (m, "lenv", "uusid", test1->value);
-  }
-#endif
-
   char *fbkp, *fbkpid, *fbkpres, *fbkp1, *flog;
   FILE *f0, *f1;
@@ -2360,5 +2953,4 @@
   if (status == NULLMAP)
     {
-	  
       if(validateRequest(&m,s1,request_inputs, &request_input_real_format,&request_output_real_format,&hInternet)<0){
 	freeService (&s1);
@@ -2699,5 +3291,5 @@
       if(cgiSid!=NULL)
 	free(cgiSid);
-      //InternetCloseHandle (&hInternet);
+      InternetCloseHandle (&hInternet);
       fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
       fflush(stderr);
