Index: /trunk/docs/services/zcfg-reference.txt
===================================================================
--- /trunk/docs/services/zcfg-reference.txt	(revision 468)
+++ /trunk/docs/services/zcfg-reference.txt	(revision 469)
@@ -19,5 +19,5 @@
 
 1. Main Metadata information
-2. List of Inputs metadata information
+2. List of Inputs metadata information (optional since `rev. 469 <http://zoo-project.org/trac/changeset/469>`__)
 3. List of Outputs metadata information
 
@@ -112,15 +112,14 @@
 - :ref:`ComplexData <ComplexData>`
 
-Except for ``LiteralData``, each *Type Of Data* node must have at least one ``<Default>`` and one ``<Supported>`` node. Even 
-if one of those are empty, it **has to be present** with an opening and closing tag on two different lines. So, something 
-like the following:
-
-.. code-block:: guess
-   :linenos:
-
-   <Default>
-   </Default>
-
-Otherwise, ZOO-Kernel won't be able to parse your ZCFG and will fail to process requests.
+Except for ``LiteralData``, each *Type Of Data* node must have at least one ``<Default>`` node. Even 
+if empty, it **has to be present**. So, something
+like the following should be present in your ZCFG file:
+
+.. code-block:: guess
+   :linenos:
+
+   <Default />
+
+Otherwise, ZOO-Kernel won't be able to parse your ZCFG correctly.
 
 .. _LiteralData:
@@ -132,4 +131,5 @@
 
 - one (optional) ``AllowedValues`` key containing all value allowed for this input
+- one (optional) ``range`` properties containing the range (``[``, ``]``)
 - one (optional) ``rangeMin`` (``rangeMax``) properties containing the minimum (maximum) value of this range
 - one (optional) ``rangeSpacing`` properties containing the regular distance or spacing between value in this range
@@ -178,4 +178,15 @@
    </LiteralData>
 
+Or more simply:
+
+.. code-block:: guess
+   :linenos:
+   
+   <LiteralData>
+     dataType = float
+     range = [0.0,100.0]
+     <Default />
+   </LiteralData>
+
 A typical ``<LiteralData>`` node, defining a ``string`` data type which
 support values ``hillshade``, ``slope``, ``aspect``, ``TRI``, ``TPI``
@@ -192,5 +203,31 @@
 
 Properties ``AllowedValues`` and ``range*`` can be conbined with both ``<Default>`` and
-``<Supported>`` nodes in the same ``<LiteralData>`` node.
+``<Supported>`` nodes in the same was as ``<LiteralData>`` node. For
+instance, the following is supported:
+
+.. code-block:: guess
+   :linenos:
+   
+   <LiteralData>
+     dataType = int
+     <Default>
+       value = 11
+       AllowedValues = -10,-8,-7,-5,-1
+       rangeMin = 0
+       rangeMin = 100
+       rangeClosure = co
+     </Default>
+     <Supported>
+       rangeMin = 200
+       rangeMin = 600
+       rangeClosure = co
+     </Supported>
+     <Supported>
+       rangeMin = 750
+       rangeMin = 990
+       rangeClosure = co
+       rangeSpacing = 10
+     </Supported>
+   </LiteralData>
 
 .. _BoundingBoxData:
Index: /trunk/zoo-project/zoo-kernel/service.h
===================================================================
--- /trunk/zoo-project/zoo-kernel/service.h	(revision 468)
+++ /trunk/zoo-project/zoo-kernel/service.h	(revision 469)
@@ -430,5 +430,5 @@
       map *tmp=getMap(m,n);
       if(tmp->value!=NULL)
-      	free(tmp->value);
+	free(tmp->value);
       tmp->value=zStrdup(v);
     }
@@ -450,9 +450,11 @@
 	while(_cursor->next!=NULL)
 	  _cursor=_cursor->next;
-	map* tmp1=getMap(_cursor,tmp->name);
-	if(tmp1==NULL)
+	map* tmp1=getMap(*mo,tmp->name);
+	if(tmp1==NULL){
 	  _cursor->next=createMap(tmp->name,tmp->value);
+	}
 	else{
-	  free(tmp1->value);
+	  if(tmp1->value!=NULL)
+	    free(tmp1->value);
 	  tmp1->value=zStrdup(tmp->value);
 	}
@@ -567,7 +569,7 @@
       }
       else{
-	maps* tmp1=getMaps(*mo,tmp->name);
 	while(_cursor->next!=NULL)
 	  _cursor=_cursor->next;
+	maps* tmp1=getMaps(*mo,tmp->name);
 	if(tmp1==NULL)
 	  _cursor->next=dupMaps(&tmp);
@@ -687,5 +689,11 @@
 	_ztmpm->value=zStrdup(value);
       }else{
-	addToMap(_tmpm->content,subkey,value);
+	maps *tmp=(maps*)malloc(MAPS_SIZE);
+	tmp->name=zStrdup(key);
+	tmp->content=createMap(subkey,value);
+	tmp->next=NULL;
+	addMapsToMaps(&_tmpm,tmp);
+	freeMaps(&tmp);
+	free(tmp);
       }
     }else{
Index: /trunk/zoo-project/zoo-kernel/service_conf.y
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_conf.y	(revision 468)
+++ /trunk/zoo-project/zoo-kernel/service_conf.y	(revision 469)
@@ -204,10 +204,12 @@
 	dumpService(my_service);
 #endif	
-	if(my_service->inputs==NULL){
+	if(my_service->inputs==NULL && current_element!=NULL && current_element->name!=NULL){
 	  my_service->inputs=dupElements(current_element);
 	  my_service->inputs->next=NULL;
+	  freeElements(&current_element);
 	}
 	else if(current_element!=NULL && current_element->name!=NULL){
 	  addToElements(&my_service->inputs,current_element);
+	  freeElements(&current_element);
 	}
 #ifdef DEBUG_SERVICE_CONF
@@ -218,5 +220,4 @@
 	fprintf(stderr,"(DATAOUTPUTS) FREE current_element\n");
 #endif
-	freeElements(&current_element);
 	free(current_element);
 	current_element=NULL;
@@ -848,5 +849,5 @@
   dumpService(my_service);
 #endif
-  if(wait_outputs<0 || my_service==NULL || my_service->name==NULL || my_service->content==NULL || my_service->inputs==NULL || my_service->outputs==NULL){
+  if(wait_outputs<0 || my_service==NULL || my_service->name==NULL || my_service->content==NULL || my_service->outputs==NULL){
     setMapInMaps(conf,"lenv","message",srlval.chaine);
 #ifndef WIN32
Index: /trunk/zoo-project/zoo-kernel/service_internal.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal.c	(revision 468)
+++ /trunk/zoo-project/zoo-kernel/service_internal.c	(revision 469)
@@ -756,4 +756,36 @@
 }
 
+void addPrefix(maps* conf,map* level,service* serv){
+  if(level!=NULL){
+    char key[25];
+    char* prefix=NULL;
+    int clevel=atoi(level->value);
+    int cl=0;
+    for(cl=0;cl<clevel;cl++){
+      sprintf(key,"sprefix_%d",cl);
+      map* tmp2=getMapFromMaps(conf,"lenv",key);
+      if(tmp2!=NULL){
+	if(prefix==NULL)
+	  prefix=zStrdup(tmp2->value);
+	else{
+	  int plen=strlen(prefix);
+	  prefix=(char*)realloc(prefix,(plen+strlen(tmp2->value)+2)*sizeof(char));
+	  memcpy(prefix+plen,tmp2->value,strlen(tmp2->value)*sizeof(char));
+	  prefix[plen+strlen(tmp2->value)]=0;
+	}
+      }
+    }
+    if(prefix!=NULL){
+      char* tmp0=strdup(serv->name);
+      free(serv->name);
+      serv->name=(char*)malloc((strlen(prefix)+strlen(tmp0)+1)*sizeof(char));
+      sprintf(serv->name,"%s%s",prefix,tmp0);
+      free(tmp0);
+      free(prefix);
+      prefix=NULL;
+    }
+  }
+}
+
 void printGetCapabilitiesForProcess(maps* m,xmlNodePtr nc,service* serv){
   xmlNsPtr ns,ns_ows,ns_xlink;
@@ -776,4 +808,6 @@
     if(tmp1!=NULL)
       xmlNewNsProp(nc1,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);
+    map* tmp3=getMapFromMaps(m,"lenv","level");
+    addPrefix(m,tmp3,serv);
     printDescription(nc1,ns_ows,serv->name,serv->content);
     tmp1=serv->metadata;
@@ -816,5 +850,5 @@
 }
 
-void printDescribeProcessForProcess(maps* m,xmlNodePtr nc,service* serv,int sc){
+void printDescribeProcessForProcess(maps* m,xmlNodePtr nc,service* serv){
   xmlNsPtr ns,ns_ows,ns_xlink,ns_xsi;
   xmlNodePtr nr,n,nc1,nc2,nc3,nc4,nc5,nc6,pseudor;
@@ -851,4 +885,6 @@
   }
   
+  tmp1=getMapFromMaps(m,"lenv","level");
+  addPrefix(m,tmp1,serv);
   printDescription(nc,ns_ows,serv->name,serv->content);
 
@@ -1860,4 +1896,5 @@
 void printDescription(xmlNodePtr root,xmlNsPtr ns_ows,const char* identifier,map* amap){
   xmlNodePtr nc2 = xmlNewNode(ns_ows, BAD_CAST "Identifier");
+  
   xmlAddChild(nc2,xmlNewText(BAD_CAST identifier));
   xmlAddChild(root,nc2);
@@ -1904,4 +1941,6 @@
 
 void printExceptionReportResponse(maps* m,map* s){
+  if(getMapFromMaps(m,"lenv","hasPrinted")!=NULL)
+    return;
   int buffersize;
   xmlDocPtr doc;
@@ -1958,4 +1997,5 @@
   xmlCleanupParser();
   zooXmlCleanupNs();
+  setMapInMaps(m,"lenv","hasPrinted","true");
 }
 
@@ -1969,15 +2009,16 @@
   maps* tmpMap=getMaps(m,"main");
 
-  int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows/1.1","ows");
+  int nsid=zooXmlAddNs(NULL,"http://www.opengis.net/ows","ows");
   ns=usedNs[nsid];
   n = xmlNewNode(ns, BAD_CAST "ExceptionReport");
 
   if(use_ns==1){
-    ns_ows=xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1",BAD_CAST "ows");
+    ns_ows=xmlNewNs(n,BAD_CAST "http://www.opengis.net/ows/1.1.0",BAD_CAST "ows");
     int xsiId=zooXmlAddNs(n,"http://www.w3.org/2001/XMLSchema-instance","xsi");
     ns_xsi=usedNs[xsiId];
+    ns_xsi=xmlNewNs(n,BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
+    xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd");
     int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
     ns_xlink=usedNs[xlinkId];
-    xmlNewNsProp(n,ns_xsi,BAD_CAST "schemaLocation",BAD_CAST "http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd");
   }
   addLangAttr(n,m);
@@ -2848,2 +2889,77 @@
   return -1;
 }
+
+#ifdef USE_MS
+char *readVSIFile(maps* conf,const char* dataSource){
+    VSILFILE * fichier=VSIFOpenL(dataSource,"rb");
+    VSIStatBufL file_status;
+    VSIStatL(dataSource, &file_status);
+    if(fichier==NULL){
+      char tmp[1024];
+      sprintf(tmp,"Failed to open file %s for reading purpose. File seems empty %d.",
+	      dataSource,file_status.st_size);
+      setMapInMaps(conf,"lenv","message",tmp);
+      return NULL;
+    }
+    char *res1=(char *)malloc(file_status.st_size*sizeof(char));
+    VSIFReadL(res1,1,(file_status.st_size)*sizeof(char),fichier);
+    VSIFCloseL(fichier);
+    VSIUnlink(dataSource);
+    return res1;
+}
+#endif
+
+void parseIdentifier(maps* conf,char* conf_dir,char *identifier,char* buffer){
+  char *saveptr1;
+  char *tmps1=strtok_r(identifier,".",&saveptr1);
+  int level=0;
+  char key[25];
+  char levels[18];
+  while(tmps1!=NULL){
+    char *test=zStrdup(tmps1);
+    char* tmps2=(char*)malloc((strlen(test)+2)*sizeof(char));
+    sprintf(key,"sprefix_%d",level);
+    sprintf(tmps2,"%s.",test);
+    sprintf(levels,"%d",level);
+    setMapInMaps(conf,"lenv","level",levels);
+    setMapInMaps(conf,"lenv",key,tmps2);
+    free(tmps2);
+    level++;
+    tmps1=strtok_r(NULL,".",&saveptr1);
+  }
+  int i=0;
+  sprintf(buffer,"%s",conf_dir);
+  for(i=0;i<level;i++){
+    char *tmp0=zStrdup(buffer);
+    sprintf(key,"sprefix_%d",i);
+    map* tmp00=getMapFromMaps(conf,"lenv",key);
+    sprintf(buffer,"%s/%s",tmp0,tmp00->value);
+    free(tmp0);
+    buffer[strlen(buffer)-1]=0;
+    if(i+1<level){
+      map* tmpMap=getMapFromMaps(conf,"lenv","metapath");
+      if(tmpMap==NULL || strlen(tmpMap->value)==0){
+	char *tmp01=zStrdup(tmp00->value);
+	tmp01[strlen(tmp01)-1]=0;
+	setMapInMaps(conf,"lenv","metapath",tmp01);
+	free(tmp01);
+      }
+      else{
+	char *value=(char*)malloc((strlen(tmp00->value)+strlen(tmpMap->value)+2)*sizeof(char));
+	sprintf(value,"%s/%s",tmpMap->value,tmp00->value);
+	value[strlen(value)-1]=0;
+	setMapInMaps(conf,"lenv","metapath",value);
+	free(value);
+      }
+    }else{
+      char *tmp0=zStrdup(tmp00->value);
+      tmp0[strlen(tmp0)-1]=0;
+      setMapInMaps(conf,"lenv","Identifier",tmp0);
+      free(tmp0);
+    }
+  }
+  char *tmp0=zStrdup(buffer);
+  sprintf(buffer,"%s.zcfg",tmp0);
+  free(tmp0);
+}
+
Index: /trunk/zoo-project/zoo-kernel/service_internal.h
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal.h	(revision 468)
+++ /trunk/zoo-project/zoo-kernel/service_internal.h	(revision 469)
@@ -38,9 +38,9 @@
 #include <sys/stat.h>
 #include <sys/types.h>
+#include "cgic.h"
 #ifndef WIN32
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #else
-#include "cgic.h"
 #include <direct.h>
 #endif
@@ -56,4 +56,5 @@
 #include <xlocale.h>
 #endif
+#include <dirent.h>
 #include "service.h"
 #include <openssl/sha.h>
@@ -118,5 +119,5 @@
   void printGetCapabilitiesForProcess(maps*,xmlNodePtr,service*);
   xmlNodePtr printDescribeProcessHeader(xmlDocPtr,const char*,maps*);
-  void printDescribeProcessForProcess(maps*,xmlNodePtr,service*,int);
+  void printDescribeProcessForProcess(maps*,xmlNodePtr,service*);
   void printFullDescription(elements*,const char*,xmlNsPtr,xmlNodePtr);
   void printDocument(maps*,xmlDocPtr,int);
@@ -144,4 +145,9 @@
   int loadRemoteFile(maps*,map*,HINTERNET,char*);
 
+#ifdef USE_MS
+  char *readVSIFile(maps*,const char*);
+#endif
+  void parseIdentifier(maps*,char*,char*,char*);
+
 #ifdef __cplusplus
 }
Index: /trunk/zoo-project/zoo-kernel/service_internal_python.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 468)
+++ /trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 469)
@@ -289,5 +289,5 @@
 #if PY_MAJOR_VERSION < 3
   PyGILState_Release(gstate);
-  PyEval_AcquireLock();
+  PyEval_ReleaseLock();
 #endif
   PyThreadState_Swap(mainstate);
Index: /trunk/zoo-project/zoo-kernel/service_internal_python.h
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_python.h	(revision 468)
+++ /trunk/zoo-project/zoo-kernel/service_internal_python.h	(revision 469)
@@ -28,7 +28,7 @@
 #pragma once 
 
-#include "service.h"
 #include "service_internal.h"
 #include <Python.h>
+#include "cgic.h"
 #ifdef WIN32
 #include <windows.h>
Index: /trunk/zoo-project/zoo-kernel/zcfg2yaml.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/zcfg2yaml.c	(revision 468)
+++ /trunk/zoo-project/zoo-kernel/zcfg2yaml.c	(revision 469)
@@ -30,5 +30,5 @@
 int main(int argc, char** argv){
   service* s1=NULL;
-  maps *m;
+  maps *m=NULL;
   char conf_file[1024];
   snprintf(conf_file,1024,"%s",argv[1]);
@@ -37,5 +37,5 @@
     return errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
   }
-  int t=getServiceFromFile(conf,file,service);
+  int t=getServiceFromFile(m,conf_file,&s1);
   if(t>=0)
     dumpServiceAsYAML(s1);
Index: /trunk/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 468)
+++ /trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 469)
@@ -189,4 +189,100 @@
   }
   return 0;
+}
+
+int recursReaddirF(maps* m,xmlNodePtr n,char *conf_dir,char *prefix,int saved_stdout,int level,void (func) (maps*,xmlNodePtr,service*)){
+  struct dirent *dp;
+  int scount=0;
+
+  if(conf_dir==NULL)
+    return 1;
+  DIR *dirp = opendir(conf_dir);
+  if(dirp==NULL){ 
+    dup2(saved_stdout,fileno(stdout));
+    errorException(m, _("The specified path doesn't exist."),"InvalidParameterValue","metapath");
+    return -1;
+  }
+  char tmp1[25];
+  sprintf(tmp1,"sprefix_%d",level);
+  char levels[17];
+  sprintf(levels,"%d",level);
+  setMapInMaps(m,"lenv","level",levels);
+  while ((dp = readdir(dirp)) != NULL)
+    if((dp->d_type==DT_DIR || dp->d_type==DT_LNK) && dp->d_name[0]!='.' && strstr(dp->d_name,".")==NULL){
+
+      char *tmp=(char*)malloc((strlen(conf_dir)+strlen(dp->d_name)+2)*sizeof(char));
+      sprintf(tmp,"%s/%s",conf_dir,dp->d_name);
+
+      if(prefix!=NULL){
+	free(prefix);
+	prefix=NULL;
+      }
+      prefix=(char*)malloc((strlen(dp->d_name)+2)*sizeof(char));
+      sprintf(prefix,"%s.",dp->d_name);
+      
+      map* tmpMap=getMapFromMaps(m,"lenv",tmp1);
+      
+      int res;
+      if(prefix!=NULL){
+	setMapInMaps(m,"lenv",tmp1,prefix);
+	char *cprefix=zStrdup(prefix);
+	char levels1[17];
+	sprintf(levels1,"%d",level+1);
+	setMapInMaps(m,"lenv","level",levels1);
+	res=recursReaddirF(m,n,tmp,cprefix,saved_stdout,level+1,func);
+	sprintf(levels1,"%d",level);
+	setMapInMaps(m,"lenv","level",levels1);
+	free(prefix);
+	prefix=NULL;
+      }
+      free(tmp);
+      if(res<0){
+	return res;
+      }
+    }
+    else{
+      char* tmp0=strdup(dp->d_name);
+      if(dp->d_name[0]!='.' && strstr(dp->d_name,".zcfg")!=0){
+	int t;
+	char tmps1[1024];
+	memset(tmps1,0,1024);
+	snprintf(tmps1,1024,"%s/%s",conf_dir,dp->d_name);
+	service* s1=(service*)malloc(SERVICE_SIZE);
+	if(s1 == NULL){ 
+	  dup2(saved_stdout,fileno(stdout));
+	  errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
+	  return -1;
+	}
+#ifdef DEBUG
+	fprintf(stderr,"#################\n%s\n#################\n",tmps1);
+#endif
+	t=readServiceFile(m,tmps1,&s1,dp->d_name);
+	if(t<0){
+	  dumpMaps(m);
+	  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);
+	  dup2(saved_stdout,fileno(stdout));
+	  errorException(m, tmp01,"InternalError",NULL);
+	  freeMaps(&m);
+	  free(m);
+	  return -1;
+	}
+#ifdef DEBUG
+	dumpService(s1);
+	fflush(stdout);
+	fflush(stderr);
+#endif
+	func(m,n,s1);
+	freeService(&s1);
+	free(s1);
+	scount++;
+      }
+    }
+  (void)closedir(dirp);
+  return 1;
 }
 
@@ -277,5 +373,4 @@
     void* so = dlopen(tmps1, RTLD_LAZY);
 #endif
-#ifdef DEBUG
 #ifdef WIN32
     DWORD errstr;
@@ -285,5 +380,4 @@
     char *errstr;
     errstr = dlerror();
-#endif
 #endif
     if( so != NULL ) {
@@ -346,5 +440,5 @@
 #endif
 #endif
-	r_inputs=getMap(request_inputs,"Identifier");
+	r_inputs=getMapFromMaps(m,"lenv","Identifier");
 #ifdef DEBUG
 	fprintf(stderr,"Try to load function %s\n",r_inputs->value);
@@ -356,4 +450,18 @@
 	execute_t execute=(execute_t)dlsym(so,r_inputs->value);
 #endif
+
+	if(execute==NULL){
+#ifdef WIN32
+	  errstr = GetLastError();
+#else
+	  errstr = dlerror();
+#endif
+	  char *tmpMsg=(char*)malloc(2048+strlen(r_inputs->value));
+	  sprintf(tmpMsg,_("Error occured while running the %s function: %s"),r_inputs->value,errstr);
+	  errorException(m, tmpMsg, "InternalError",NULL);
+	  free(tmpMsg);
+	  fprintf(stderr,"Function %s error %s\n",r_inputs->value,errstr);
+	  return;
+	}
 
 #ifdef DEBUG
@@ -758,8 +866,4 @@
     dumpMap(r_inputs);
 #endif
-    DIR *dirp = opendir(conf_dir);
-    if(dirp==NULL){
-      return errorException(m, _("The specified path doesn't exist."),"InvalidParameterValue","metapath");
-    }
     xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
     r_inputs=NULL;
@@ -776,41 +880,6 @@
     int saved_stdout = dup(fileno(stdout));
     dup2(fileno(stderr),fileno(stdout));
-    while ((dp = readdir(dirp)) != NULL)
-      if(strstr(dp->d_name,".zcfg")!=0){
-	int t;
-	memset(tmps1,0,1024);
-	snprintf(tmps1,1024,"%s/%s",conf_dir,dp->d_name);
-	s1=(service*)malloc(SERVICE_SIZE);
-	if(s1 == NULL){ 
-	  return errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
-	}
-#ifdef DEBUG
-	fprintf(stderr,"#################\n%s\n#################\n",tmps1);
-#endif
-	t=readServiceFile(m,tmps1,&s1,dp->d_name);
-	if(t<0){
-	  dumpMaps(m);
-	  map* tmp00=getMapFromMaps(m,"lenv","message");
-	  char tmp01[1024];
-	  sprintf(tmp01,_("Unable to parse the ZCFG file: %s (%s)"),dp->d_name,tmp00->value);
-	  dup2(saved_stdout,fileno(stdout));
-	  errorException(m, tmp01,"InternalError",NULL);
-	  freeMaps(&m);
-	  free(m);
-	  return 1;
-	}
-
-#ifdef DEBUG
-	dumpService(s1);
-	fflush(stdout);
-	fflush(stderr);
-#endif
-	printGetCapabilitiesForProcess(m,n,s1);
-	freeService(&s1);
-	free(s1);
-	scount++;
-      }
-    (void)closedir(dirp);
-    fflush(stdout);
+    if(int res=recursReaddirF(m,n,conf_dir,NULL,saved_stdout,0,printGetCapabilitiesForProcess)<0)
+      return res;
     dup2(saved_stdout,fileno(stdout));
     printDocument(m,doc,getpid());
@@ -860,36 +929,24 @@
       r_inputs=getMap(request_inputs,"Identifier");
       
-      char *saveptr;
       char *orig=zStrdup(r_inputs->value);
-      char *tmps=strtok_r(orig,",",&saveptr);
-      
-      char buff[256];
-      char buff1[1024];
+
       int saved_stdout = dup(fileno(stdout));
       dup2(fileno(stderr),fileno(stdout));
-      while(tmps){
-	memset(buff,0,256);
-	snprintf(buff,256,"%s.zcfg",tmps);
-	memset(buff1,0,1024);
-#ifdef DEBUG
-	printf("\n#######%s\n########\n",buff);
-#endif
-	while ((dp = readdir(dirp)) != NULL)
-	  if((strcasecmp("all.zcfg",buff)==0 && strstr(dp->d_name,".zcfg")>0)
-	     || strcasecmp(dp->d_name,buff)==0){
-	    memset(buff1,0,1024);
-	    snprintf(buff1,1024,"%s/%s",conf_dir,dp->d_name);
+      if(strcasecmp("all",orig)==0){
+	if(int res=recursReaddirF(m,n,conf_dir,NULL,saved_stdout,0,printDescribeProcessForProcess)<0)
+	  return res;
+      }
+      else{
+	char *saveptr;
+	char *tmps=strtok_r(orig,",",&saveptr);
+	
+	char buff[256];
+	char buff1[1024];
+	while(tmps!=NULL){
+	  char *corig=strdup(tmps);
+	  if(strstr(corig,".")!=NULL){
+	    parseIdentifier(m,conf_dir,corig,buff1);
 	    s1=(service*)malloc(SERVICE_SIZE);
-	    if(s1 == NULL){
-	      dup2(saved_stdout,fileno(stdout));
-	      return errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
-	    }
-#ifdef DEBUG
-	    printf("#################\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);
+	    t=readServiceFile(m,buff1,&s1,corig);
 	    if(t<0){
 	      map* tmp00=getMapFromMaps(m,"lenv","message");
@@ -908,12 +965,60 @@
 	    dumpService(s1);
 #endif
-	    printDescribeProcessForProcess(m,n,s1,1);
+	    printDescribeProcessForProcess(m,n,s1);
 	    freeService(&s1);
 	    free(s1);
 	    s1=NULL;
 	    scount++;
+	    setMapInMaps(m,"lenv","level","0");
 	  }
-	rewinddir(dirp);
-	tmps=strtok_r(NULL,",",&saveptr);
+	  
+	  memset(buff,0,256);
+	  snprintf(buff,256,"%s.zcfg",tmps);
+	  memset(buff1,0,1024);
+#ifdef DEBUG
+	  printf("\n#######%s\n########\n",buff);
+#endif
+	  while ((dp = readdir(dirp)) != NULL)
+	    if( (strcasecmp("all.zcfg",buff)==0 && strstr(dp->d_name,".zcfg")>0)
+		|| strcasecmp(dp->d_name,buff)==0 ){
+	      memset(buff1,0,1024);
+	      snprintf(buff1,1024,"%s/%s",conf_dir,dp->d_name);
+	      s1=(service*)malloc(SERVICE_SIZE);
+	      if(s1 == NULL){
+		dup2(saved_stdout,fileno(stdout));
+		return errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
+	      }
+#ifdef DEBUG
+	      printf("#################\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);
+		dup2(saved_stdout,fileno(stdout));
+		errorException(m, tmp01,"InternalError",NULL);
+		freeMaps(&m);
+		free(m);
+		return 1;
+	      }
+#ifdef DEBUG
+	      dumpService(s1);
+#endif
+	      printDescribeProcessForProcess(m,n,s1);
+	      freeService(&s1);
+	      free(s1);
+	      s1=NULL;
+	      scount++;
+	    }
+	  rewinddir(dirp);
+	  tmps=strtok_r(NULL,",",&saveptr);
+	}
       }
       closedir(dirp);
@@ -967,4 +1072,13 @@
   fprintf(stderr,"Trying to load %s\n", tmps1);
 #endif
+  if(strstr(r_inputs->value,".")!=NULL){
+    char *identifier=zStrdup(r_inputs->value);
+    parseIdentifier(m,conf_dir,identifier,tmps1);
+    map* tmpMap=getMapFromMaps(m,"lenv","metapath");
+    if(tmpMap!=NULL)
+      addToMap(request_inputs,"metapath",tmpMap->value);
+    free(identifier);
+  }else
+    setMapInMaps(m,"lenv","Identifier",r_inputs->value);
   int saved_stdout = dup(fileno(stdout));
   dup2(fileno(stderr),fileno(stdout));
@@ -974,5 +1088,4 @@
   if(t<0){
     char *tmpMsg=(char*)malloc(2048+strlen(r_inputs->value));
-    
     sprintf(tmpMsg,_("The value for <indetifier> seems to be wrong (%s). Please, ensure that the process exist using the GetCapabilities request."),r_inputs->value);
     errorException(m, tmpMsg, "InvalidParameterValue","identifier");
Index: /trunk/zoo-project/zoo-services/cgal/Makefile
===================================================================
--- /trunk/zoo-project/zoo-services/cgal/Makefile	(revision 468)
+++ /trunk/zoo-project/zoo-services/cgal/Makefile	(revision 469)
@@ -1,10 +1,16 @@
-ZRPATH=../../..
+ZRPATH=../..
 include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
 CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
 CC=gcc
 
-cgi-env/cgal_service.zo: service.c
-	g++ ${CFLAGS} -shared -fpic -o cgi-env/cgal_service.zo ./service.c ${GDAL_LIBS} ${MACOS_LD_FLAGS} -lCGAL
+cgi-env/cgal_service.zo: delaunay.c voronoi.c cgal_service.o
+	g++ ${CFLAGS} -c ./delaunay.c
+	g++ ${CFLAGS} -c ./voronoi.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/cgal_service.zo ./delaunay.o ./voronoi.o ./cgal_service.o ${GDAL_LIBS} ${MACOS_LD_FLAGS} -lCGAL -lgmp
+
+cgal_service.o: cgal_service.c cgal_service.h
+	g++ ${CFLAGS} -c ./cgal_service.c
+
 
 clean:
-	rm -f cgi-env/*.zo
+	rm -f cgi-env/*.zo *.o
Index: /trunk/zoo-project/zoo-services/cgal/cgal_service.c
===================================================================
--- /trunk/zoo-project/zoo-services/cgal/cgal_service.c	(revision 469)
+++ /trunk/zoo-project/zoo-services/cgal/cgal_service.c	(revision 469)
@@ -0,0 +1,81 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "cgal_service.h"
+
+int parseInput(maps* conf,maps* inputs, std::vector<Point>* points,char* filename){
+  map* tmpm=NULL;
+  tmpm=getMapFromMaps(inputs,"InputPoints","value");
+  VSILFILE *ifile=VSIFileFromMemBuffer(filename,(GByte*)tmpm->value,strlen(tmpm->value),FALSE);
+  VSIFCloseL(ifile);
+  OGRDataSource* ipoDS = OGRSFDriverRegistrar::Open(filename,FALSE);
+  if( ipoDS == NULL )
+    {
+      OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
+      
+      fprintf( stderr, "FAILURE:\n"
+	       "Unable to open datasource `%s' with the following drivers.\n",
+	       filename );
+      
+      for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+        {
+	  fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
+        }
+      char tmp[1024];
+      sprintf(tmp,"Unable to open datasource `%s' with the following drivers.",filename);
+      setMapInMaps(conf,"lenv","message",tmp);
+      return SERVICE_FAILED;
+    }
+  for( int iLayer = 0; iLayer < ipoDS->GetLayerCount();
+       iLayer++ )
+    {
+      OGRLayer        *poLayer = ipoDS->GetLayer(iLayer);
+      
+      if( poLayer == NULL )
+	{
+	  fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
+		   iLayer );
+#ifdef ZOO_SERVICE
+	  char tmp[1024];
+	  sprintf(tmp,"Couldn't fetch advertised layer %d!",iLayer);
+	  setMapInMaps(conf,"lenv","message",tmp);
+	  return SERVICE_FAILED;
+#else
+	  exit( 1 );
+#endif
+	}
+      
+      OGRFeature  *poFeature;
+      while(TRUE){
+	poFeature = poLayer->GetNextFeature();
+	if( poFeature == NULL )
+	  break;
+	if(poFeature->GetGeometryRef() != NULL){
+	  points->push_back(Point(OGR_G_GetX(poFeature->GetGeometryRef(),0),OGR_G_GetY(poFeature->GetGeometryRef(),0)));
+	}
+      }
+    }
+  return SERVICE_SUCCEEDED;
+}
+
+
Index: /trunk/zoo-project/zoo-services/cgal/cgal_service.h
===================================================================
--- /trunk/zoo-project/zoo-services/cgal/cgal_service.h	(revision 469)
+++ /trunk/zoo-project/zoo-services/cgal/cgal_service.h	(revision 469)
@@ -0,0 +1,45 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef ZOO_CGAL_SERVICE_H
+#define ZOO_CGAL_SERVICE_H
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_vertex_base_with_info_2.h>
+#include <vector>
+
+#include "cpl_minixml.h"
+#include "ogr_api.h"
+#include "ogrsf_frmts.h"
+#include "service.h"
+#include "service_internal.h"
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel            Kernel;
+typedef Kernel::Point_2                                                Point;
+
+int parseInput(maps*,maps*, std::vector<Point>*,char*);
+
+#endif
+
Index: /trunk/zoo-project/zoo-services/cgal/delaunay.c
===================================================================
--- /trunk/zoo-project/zoo-services/cgal/delaunay.c	(revision 469)
+++ /trunk/zoo-project/zoo-services/cgal/delaunay.c	(revision 469)
@@ -0,0 +1,187 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "cgal_service.h"
+typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Kernel> Vb;
+typedef CGAL::Triangulation_data_structure_2<Vb>                       Tds;
+typedef CGAL::Delaunay_triangulation_2<Kernel, Tds>                    DelaunayT;
+
+extern "C" {
+
+  int Delaunay(maps*& conf,maps*& inputs,maps*& outputs){
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print\nStarting\n");
+#endif
+    maps* cursor=inputs;
+    OGRGeometryH geometry,res;
+    int bufferDistance;
+    map* tmpm=NULL;
+    OGRRegisterAll();
+
+    std::vector<Point> points;
+    if(int res=parseInput(conf,inputs,&points,"/vsimem/tmp")!=SERVICE_SUCCEEDED)
+      return res;
+
+    DelaunayT T;
+    T.insert(points.begin(), points.end());
+
+    /* -------------------------------------------------------------------- */
+    /*      Try opening the output datasource as an existing, writable      */
+    /* -------------------------------------------------------------------- */
+    OGRDataSource       *poODS;
+    
+    OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
+    OGRSFDriver          *poDriver = NULL;
+    int                  iDriver;
+
+    map *tmpMap=getMapFromMaps(outputs,"Result","mimeType");
+    const char *oDriver;
+    oDriver="GeoJSON";
+    if(tmpMap!=NULL){
+      if(strcmp(tmpMap->value,"text/xml")==0){
+	oDriver="GML";
+      }
+    }
+    
+    for( iDriver = 0;
+	 iDriver < poR->GetDriverCount() && poDriver == NULL;
+	 iDriver++ )
+      {
+#ifdef DEBUG
+	fprintf(stderr,"D:%s\n",poR->GetDriver(iDriver)->GetName());
+#endif
+	if( EQUAL(poR->GetDriver(iDriver)->GetName(),oDriver) )
+	  {
+	    poDriver = poR->GetDriver(iDriver);
+	  }
+      }
+
+    if( poDriver == NULL )
+      {
+	char emessage[8192];
+	sprintf( emessage, "Unable to find driver `%s'.\n", oDriver );
+	sprintf( emessage,  "%sThe following drivers are available:\n",emessage );
+        
+	for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    sprintf( emessage,  "%s  -> `%s'\n", emessage, poR->GetDriver(iDriver)->GetName() );
+	  }
+
+	setMapInMaps(conf,"lenv","message",emessage);
+	return SERVICE_FAILED;
+
+      }
+
+    if( !poDriver->TestCapability( ODrCCreateDataSource ) ){
+      char emessage[1024];
+      sprintf( emessage,  "%s driver does not support data source creation.\n",
+	       "json" );
+      setMapInMaps(conf,"lenv","message",emessage);
+      return SERVICE_FAILED;
+    }
+
+    /* -------------------------------------------------------------------- */
+    /*      Create the output data source.                                  */
+    /* -------------------------------------------------------------------- */
+    char *pszDestDataSource=(char*)malloc(100);
+    char **papszDSCO=NULL;
+    sprintf(pszDestDataSource,"/vsimem/result_%d",getpid());
+    poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
+    if( poODS == NULL ){
+      char emessage[1024];      
+      sprintf( emessage,  "%s driver failed to create %s\n", 
+	       "json", pszDestDataSource );
+      setMapInMaps(conf,"lenv","message",emessage);
+      return SERVICE_FAILED;
+    }
+
+    /* -------------------------------------------------------------------- */
+    /*      Create the layer.                                               */
+    /* -------------------------------------------------------------------- */
+    if( !poODS->TestCapability( ODsCCreateLayer ) )
+      {
+	char emessage[1024];
+	sprintf( emessage, 
+		 "Layer %s not found, and CreateLayer not supported by driver.", 
+		 "Result" );
+	setMapInMaps(conf,"lenv","message",emessage);
+	return SERVICE_FAILED;
+      }
+    
+    CPLErrorReset();
+    
+    OGRLayer *poDstLayer = poODS->CreateLayer( "Result", NULL,wkbPolygon,NULL);
+    if( poDstLayer == NULL ){
+      setMapInMaps(conf,"lenv","message","Layer creation failed.\n");
+      return SERVICE_FAILED;
+    }
+
+
+    for(DelaunayT::Finite_faces_iterator fit = T.finite_faces_begin();
+	fit != T.finite_faces_end(); ++fit) {
+      DelaunayT::Face_handle face = fit;
+      OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( poDstLayer ) );
+      OGRGeometryH hCollection = OGR_G_CreateGeometry( wkbGeometryCollection );
+      OGRGeometryH currLine=OGR_G_CreateGeometry(wkbLinearRing);
+      OGRGeometryH currPoly=OGR_G_CreateGeometry(wkbPolygon);
+      OGR_G_AddPoint_2D(currLine,T.triangle(face)[0].x(),T.triangle(face)[0].y());
+      OGR_G_AddPoint_2D(currLine,T.triangle(face)[1].x(),T.triangle(face)[1].y());
+      OGR_G_AddPoint_2D(currLine,T.triangle(face)[2].x(),T.triangle(face)[2].y());
+      OGR_G_AddPoint_2D(currLine,T.triangle(face)[0].x(),T.triangle(face)[0].y());
+      OGR_G_AddGeometryDirectly( currPoly, currLine ); 
+      OGR_G_AddGeometryDirectly( hCollection, currPoly ); 
+      OGR_F_SetGeometry( hFeature, hCollection ); 
+      OGR_G_DestroyGeometry(hCollection);
+      if( OGR_L_CreateFeature( poDstLayer, hFeature ) != OGRERR_NONE ){
+	setMapInMaps(conf,"lenv","message","Failed to create feature in file.\n");
+	return SERVICE_FAILED;
+      }
+      OGR_F_Destroy( hFeature );
+    }
+    OGR_DS_Destroy( poODS );
+
+#ifdef DEBUG
+    std::cerr << "The Voronoi diagram has " << ns << " finite edges "
+	      << " and " << nr << " rays" << std::endl;
+#endif
+
+    char *res1=readVSIFile(conf,pszDestDataSource);
+    if(res1==NULL)
+      return SERVICE_FAILED;
+
+    setMapInMaps(outputs,"Result","value",res1);
+    free(res1);
+
+    if(strcmp(oDriver,"GML")==0)
+      setMapInMaps(outputs,"Result","mimeType","text/xml");
+    else
+      setMapInMaps(outputs,"Result","mimeType","text/plain");
+
+    setMapInMaps(outputs,"Result","encoding","UTF-8");
+    OGRCleanupAll();
+    
+    return SERVICE_SUCCEEDED;
+  }
+
+}
Index: unk/zoo-project/zoo-services/cgal/service.c
===================================================================
--- /trunk/zoo-project/zoo-services/cgal/service.c	(revision 468)
+++ 	(revision )
@@ -1,296 +1,0 @@
-/**
- * Author : Gérald FENOY
- *
- * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
-#include <CGAL/Triangulation_euclidean_traits_xy_3.h>
-#include <CGAL/Delaunay_triangulation_2.h>
-#include <CGAL/Constrained_Delaunay_triangulation_2.h>
-#include <CGAL/Triangulation_conformer_2.h>
-#include <CGAL/Triangulation_face_base_2.h>
-
-#include <fstream>
-
-#include "cpl_minixml.h"
-#include "ogr_api.h"
-#include "ogrsf_frmts.h"
-#include "service.h"
-
-typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
-
-typedef CGAL::Delaunay_triangulation_2<K>  Triangulation;
-typedef Triangulation::Edge_iterator  Edge_iterator;
-typedef Triangulation::Point          Point;
-
-typedef CGAL::Constrained_Delaunay_triangulation_2<K> CDT;
-typedef CDT::Point Point;
-typedef CDT::Vertex_handle Vertex_handle;
-
-typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
-typedef CGAL::Triangulation_euclidean_traits_xy_3<K>  Gt;
-typedef CGAL::Delaunay_triangulation_2<Gt> DelaunayTriangulation;
-
-typedef Triangulation::Vertex_circulator Vertex_circulator;
-
-typedef K::Point_3   Point1;
-
-extern "C" {
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-
-#include <openssl/sha.h>
-#include <openssl/hmac.h>
-#include <openssl/evp.h>
-#include <openssl/bio.h>
-#include <openssl/buffer.h>
-
-  xmlNodeSet* extractFromDoc(xmlDocPtr,char*);
-  void printExceptionReportResponse(maps*,map*);
-
-  int Voronoi(maps*& conf,maps*& inputs,maps*& outputs){
-#ifdef DEBUG
-    fprintf(stderr,"\nService internal print\nStarting\n");
-#endif
-    maps* cursor=inputs;
-    OGRGeometryH geometry,res;
-    int bufferDistance;
-    xmlInitParser();
-    map* tmpm=NULL;
-    tmpm=getMapFromMaps(inputs,"InputPoints","value");
-    
-    xmlInitParser();
-    xmlDocPtr doc =
-      xmlParseMemory(tmpm->value,strlen(tmpm->value));
-    xmlNodePtr cur = xmlDocGetRootElement(doc);
-    /**
-     * Parse every Input in DataInputs node.
-     */
-    maps* tempMaps=NULL;
-    xmlXPathContextPtr xpathCtx;
-    xmlXPathObjectPtr xpathObj;
-    xpathCtx = xmlXPathNewContext(doc);
-    xpathObj = xmlXPathEvalExpression(BAD_CAST "/*/*[local-name()='featureMember']/*/*/*[local-name()='Point']/*[local-name()='coordinates']",xpathCtx);
-    xmlXPathFreeContext(xpathCtx); 
-    xmlNodeSet* nSet=xpathObj->nodesetval;
-
-    if(nSet==NULL){
-      setMapInMaps(conf,"lenv","message","Unable to continue !!!");
-      return SERVICE_FAILED;
-    }
-    char filepath[2048];
-    map* tmpMap=getMapFromMaps(conf,"main","tmpPath");
-    if(tmpMap!=NULL){
-      sprintf(filepath,"%s/varonoi_%d.tmp",tmpMap->value,getpid());
-    }
-    FILE *fo=fopen(filepath,"w");
-#ifdef DEBUG
-    fprintf(stderr,"File Creation (%s) OK\nPrinting %d Points.\n",filepath,nSet->nodeNr);
-#endif
-    for(int k=0;k<nSet->nodeNr;k++){
-      xmlNodePtr cur=nSet->nodeTab[k];
-      char *val=
-	(char*)xmlNodeListGetString(doc,cur->xmlChildrenNode,1);
-      char *tmp=strstr(val,",");
-      char tmp1[1024];
-      strncpy(tmp1,val,strlen(val)-strlen(tmp));
-      tmp1[strlen(val)-strlen(tmp)]=0;
-      char buff[1024];
-      sprintf(buff,"%s %s\n",tmp1,tmp+1);
-      fwrite(buff,1,strlen(buff)*sizeof(char),fo);
-    }
-    fclose(fo);
-#ifdef DEBUG
-    fprintf(stderr,"File Close (%s) OK\n",filepath);
-#endif
-
-    std::ifstream in(filepath);
-    std::istream_iterator<Point> begin(in);
-    std::istream_iterator<Point> end;
-    Triangulation T;
-    T.insert(begin, end);
-
-    OGRRegisterAll();
-    /* -------------------------------------------------------------------- */
-    /*      Try opening the output datasource as an existing, writable      */
-    /* -------------------------------------------------------------------- */
-    OGRDataSource       *poODS;
-    
-    OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
-    OGRSFDriver          *poDriver = NULL;
-    int                  iDriver;
-
-    tmpMap=getMapFromMaps(outputs,"Result","mimeType");
-    const char *oDriver;
-    oDriver="GeoJSON";
-    if(tmpMap!=NULL){
-      if(strcmp(tmpMap->value,"text/xml")==0){
-	oDriver="GML";
-      }
-    }
-    
-    for( iDriver = 0;
-	 iDriver < poR->GetDriverCount() && poDriver == NULL;
-	 iDriver++ )
-      {
-#ifdef DEBUG
-	fprintf(stderr,"D:%s\n",poR->GetDriver(iDriver)->GetName());
-#endif
-	if( EQUAL(poR->GetDriver(iDriver)->GetName(),oDriver) )
-	  {
-	    poDriver = poR->GetDriver(iDriver);
-	  }
-      }
-
-    if( poDriver == NULL )
-      {
-	char emessage[8192];
-	sprintf( emessage, "Unable to find driver `%s'.\n", oDriver );
-	sprintf( emessage,  "%sThe following drivers are available:\n",emessage );
-        
-	for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
-	  {
-	    sprintf( emessage,  "%s  -> `%s'\n", emessage, poR->GetDriver(iDriver)->GetName() );
-	  }
-
-	setMapInMaps(conf,"lenv","message",emessage);
-	return SERVICE_FAILED;
-
-      }
-
-    if( !poDriver->TestCapability( ODrCCreateDataSource ) ){
-      char emessage[1024];
-      sprintf( emessage,  "%s driver does not support data source creation.\n",
-	       "json" );
-      setMapInMaps(conf,"lenv","message",emessage);
-      return SERVICE_FAILED;
-    }
-
-    /* -------------------------------------------------------------------- */
-    /*      Create the output data source.                                  */
-    /* -------------------------------------------------------------------- */
-    map* tpath=getMapFromMaps(conf,"main","tmpPath");
-    char *pszDestDataSource=(char*)malloc(strlen(tpath->value)+20);
-    char **papszDSCO=NULL;
-    sprintf(pszDestDataSource,"%s/result_%d.json",tpath->value,getpid());
-    poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
-    if( poODS == NULL ){
-      char emessage[1024];      
-      sprintf( emessage,  "%s driver failed to create %s\n", 
-	       "json", pszDestDataSource );
-      setMapInMaps(conf,"lenv","message",emessage);
-      return SERVICE_FAILED;
-    }
-
-    /* -------------------------------------------------------------------- */
-    /*      Create the layer.                                               */
-    /* -------------------------------------------------------------------- */
-    if( !poODS->TestCapability( ODsCCreateLayer ) )
-      {
-	char emessage[1024];
-	sprintf( emessage, 
-		 "Layer %s not found, and CreateLayer not supported by driver.", 
-		 "Result" );
-	setMapInMaps(conf,"lenv","message",emessage);
-	return SERVICE_FAILED;
-      }
-    
-    CPLErrorReset();
-    
-    OGRLayer *poDstLayer = poODS->CreateLayer( "Result", NULL,wkbLineString,NULL);
-    if( poDstLayer == NULL ){
-      setMapInMaps(conf,"lenv","message","Layer creation failed.\n");
-      return SERVICE_FAILED;
-    }
-
-
-    int ns = 0;
-    int nr = 0;
-    Edge_iterator eit =T.edges_begin();
-    for ( ; eit !=T.edges_end(); ++eit) {
-      CGAL::Object o = T.dual(eit);
-      if (const K::Segment_2 *tmp=CGAL::object_cast<K::Segment_2>(&o)) {
-	const K::Point_2 p1=tmp->source();
-	const K::Point_2 p2=tmp->target();
-#ifdef DEBUG
-	fprintf(stderr,"P1 %d %d | P2 %d %d\n",p1.x(),p1.y(),p2.x(),p2.y());
-#endif
-	OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( poDstLayer ) );
-	OGRGeometryH currLine=OGR_G_CreateGeometry(wkbLineString);
-	OGR_G_AddPoint_2D(currLine,p1.x(),p1.y());
-	OGR_G_AddPoint_2D(currLine,p2.x(),p2.y());
-	OGR_F_SetGeometry( hFeature, currLine ); 
-	OGR_G_DestroyGeometry(currLine);
-	if( OGR_L_CreateFeature( poDstLayer, hFeature ) != OGRERR_NONE ){
-	  setMapInMaps(conf,"lenv","message","Failed to create feature in file.\n");
-	  return SERVICE_FAILED;
-	}
-	OGR_F_Destroy( hFeature );
-	++ns ;
-      }
-      else if (CGAL::object_cast<K::Ray_2>(&o)) {++nr;}
-    }
-    OGR_DS_Destroy( poODS );
-    OGRCleanupAll();
-
-#ifdef DEBUG
-    std::cerr << "The Voronoi diagram has " << ns << " finite edges "
-	      << " and " << nr << " rays" << std::endl;
-    sprintf(tmp1,"%d finite edges, %d rays",ns,nr);
-#endif
-    
-    char tmp1[1024];
-
-    FILE * fichier=fopen(pszDestDataSource,"r"); 
-    struct stat file_status;
-    stat(pszDestDataSource, &file_status);
-    char *res1=(char *)malloc(file_status.st_size*sizeof(char));
-    if(fichier==NULL){
-      char tmp[1024];
-      sprintf(tmp,"Failed to open file %s for reading purpose.\n",
-	      pszDestDataSource);
-      setMapInMaps(conf,"lenv","message",tmp);
-      return SERVICE_FAILED;
-    }
-    fread(res1,1,(file_status.st_size)*sizeof(char),fichier);
-    res1[strlen(res1)]=0;
-    fclose(fichier);
-    unlink(pszDestDataSource);
-    
-    setMapInMaps(outputs,"Result","value",res1);
-    
-    if(strcmp(oDriver,"GML")==0)
-      setMapInMaps(outputs,"Result","mimeType","text/xml");
-    else
-      setMapInMaps(outputs,"Result","mimeType","text/plain");
-
-    setMapInMaps(outputs,"Result","encoding","UTF-8");
-#ifdef DEBUG
-    fprintf(stderr,"\nService internal print\n===\n");
-#endif
-    xmlCleanupParser();
-    return SERVICE_SUCCEEDED;
-  }
-
-}
Index: /trunk/zoo-project/zoo-services/cgal/voronoi.c
===================================================================
--- /trunk/zoo-project/zoo-services/cgal/voronoi.c	(revision 469)
+++ /trunk/zoo-project/zoo-services/cgal/voronoi.c	(revision 469)
@@ -0,0 +1,228 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2009-2013 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
+#include <CGAL/Triangulation_euclidean_traits_xy_3.h>
+#include <CGAL/Delaunay_triangulation_2.h>
+#include <CGAL/Constrained_Delaunay_triangulation_2.h>
+#include <CGAL/Triangulation_conformer_2.h>
+#include <CGAL/Triangulation_face_base_2.h>
+
+#include <fstream>
+
+#include "cpl_minixml.h"
+#include "ogr_api.h"
+#include "ogrsf_frmts.h"
+#include "service.h"
+#include "cgal_service.h"
+
+typedef CGAL::Delaunay_triangulation_2<Kernel>  Triangulation;
+typedef Triangulation::Edge_iterator  Edge_iterator;
+typedef Triangulation::Vertex_circulator Vertex_circulator;
+
+extern "C" {
+
+  int Voronoi(maps*& conf,maps*& inputs,maps*& outputs){
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print\nStarting\n");
+#endif
+    maps* cursor=inputs;
+    OGRGeometryH geometry,res;
+    int bufferDistance;
+    map* tmpm=NULL;
+    tmpm=getMapFromMaps(inputs,"InputPoints","value");
+
+    OGRRegisterAll();
+
+    std::vector<Point> points;
+    if(int res=parseInput(conf,inputs,&points,"/vsimem/tmp")!=SERVICE_SUCCEEDED)
+      return res;
+    
+    Triangulation T;
+    T.insert(points.begin(), points.end());
+
+    OGRRegisterAll();
+    /* -------------------------------------------------------------------- */
+    /*      Try opening the output datasource as an existing, writable      */
+    /* -------------------------------------------------------------------- */
+    OGRDataSource       *poODS;
+    
+    OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
+    OGRSFDriver          *poDriver = NULL;
+    int                  iDriver;
+
+    map* tmpMap=getMapFromMaps(outputs,"Result","mimeType");
+    const char *oDriver;
+    oDriver="GeoJSON";
+    if(tmpMap!=NULL){
+      if(strcmp(tmpMap->value,"text/xml")==0){
+	oDriver="GML";
+      }
+    }
+    
+    for( iDriver = 0;
+	 iDriver < poR->GetDriverCount() && poDriver == NULL;
+	 iDriver++ )
+      {
+#ifdef DEBUG
+	fprintf(stderr,"D:%s\n",poR->GetDriver(iDriver)->GetName());
+#endif
+	if( EQUAL(poR->GetDriver(iDriver)->GetName(),oDriver) )
+	  {
+	    poDriver = poR->GetDriver(iDriver);
+	  }
+      }
+
+    if( poDriver == NULL )
+      {
+	char emessage[8192];
+	sprintf( emessage, "Unable to find driver `%s'.\n", oDriver );
+	sprintf( emessage,  "%sThe following drivers are available:\n",emessage );
+        
+	for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
+	  {
+	    sprintf( emessage,  "%s  -> `%s'\n", emessage, poR->GetDriver(iDriver)->GetName() );
+	  }
+
+	setMapInMaps(conf,"lenv","message",emessage);
+	return SERVICE_FAILED;
+
+      }
+
+    if( !poDriver->TestCapability( ODrCCreateDataSource ) ){
+      char emessage[1024];
+      sprintf( emessage,  "%s driver does not support data source creation.\n",
+	       "json" );
+      setMapInMaps(conf,"lenv","message",emessage);
+      return SERVICE_FAILED;
+    }
+
+    /* -------------------------------------------------------------------- */
+    /*      Create the output data source.                                  */
+    /* -------------------------------------------------------------------- */
+    map* tpath=getMapFromMaps(conf,"main","tmpPath");
+    char *pszDestDataSource=(char*)malloc(100);
+    char **papszDSCO=NULL;
+    sprintf(pszDestDataSource,"/vsimem/result_%d.json",tpath->value,getpid());
+    poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
+    if( poODS == NULL ){
+      char emessage[1024];      
+      sprintf( emessage,  "%s driver failed to create %s\n", 
+	       "json", pszDestDataSource );
+      setMapInMaps(conf,"lenv","message",emessage);
+      return SERVICE_FAILED;
+    }
+
+    /* -------------------------------------------------------------------- */
+    /*      Create the layer.                                               */
+    /* -------------------------------------------------------------------- */
+    if( !poODS->TestCapability( ODsCCreateLayer ) )
+      {
+	char emessage[1024];
+	sprintf( emessage, 
+		 "Layer %s not found, and CreateLayer not supported by driver.", 
+		 "Result" );
+	setMapInMaps(conf,"lenv","message",emessage);
+	return SERVICE_FAILED;
+      }
+    
+    CPLErrorReset();
+    
+    OGRLayer *poDstLayer = poODS->CreateLayer( "Result", NULL,wkbLineString,NULL);
+    if( poDstLayer == NULL ){
+      setMapInMaps(conf,"lenv","message","Layer creation failed.\n");
+      return SERVICE_FAILED;
+    }
+
+
+    int ns = 0;
+    int nr = 0;
+    Edge_iterator eit =T.edges_begin();
+    for ( ; eit !=T.edges_end(); ++eit) {
+      CGAL::Object o = T.dual(eit);
+      if (const Kernel::Segment_2 *tmp=CGAL::object_cast<Kernel::Segment_2>(&o)) {
+	const Point p1=tmp->source();
+	const Point p2=tmp->target();
+#ifdef DEBUG
+	fprintf(stderr,"P1 %d %d | P2 %d %d\n",p1.x(),p1.y(),p2.x(),p2.y());
+#endif
+	OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( poDstLayer ) );
+	OGRGeometryH currLine=OGR_G_CreateGeometry(wkbLineString);
+	OGR_G_AddPoint_2D(currLine,p1.x(),p1.y());
+	OGR_G_AddPoint_2D(currLine,p2.x(),p2.y());
+	OGR_F_SetGeometry( hFeature, currLine ); 
+	OGR_G_DestroyGeometry(currLine);
+	if( OGR_L_CreateFeature( poDstLayer, hFeature ) != OGRERR_NONE ){
+	  setMapInMaps(conf,"lenv","message","Failed to create feature in file.\n");
+	  return SERVICE_FAILED;
+	}
+	OGR_F_Destroy( hFeature );
+	++ns ;
+      }
+      else if (const Kernel::Ray_2 *tmp=CGAL::object_cast<Kernel::Ray_2>(&o)) { 
+	const Point p1=tmp->source();
+	const Point p2=tmp->point(2);
+	OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( poDstLayer ) );
+	OGRGeometryH currLine=OGR_G_CreateGeometry(wkbLineString);
+	OGR_G_AddPoint_2D(currLine,p1.x(),p1.y());
+	OGR_G_AddPoint_2D(currLine,p2.x(),p2.y());
+	OGR_F_SetGeometry( hFeature, currLine );
+	OGR_G_DestroyGeometry(currLine);
+	if( OGR_L_CreateFeature( poDstLayer, hFeature ) != OGRERR_NONE ){
+	  setMapInMaps(conf,"lenv","message","Failed to create feature in file.\n");
+	  return SERVICE_FAILED;
+	}
+	OGR_F_Destroy( hFeature );
+	++nr; 
+      }
+    }
+    OGR_DS_Destroy( poODS );
+
+#ifdef DEBUG
+    std::cerr << "The Voronoi diagram has " << ns << " finite edges "
+	      << " and " << nr << " rays" << std::endl;
+    sprintf(tmp1,"%d finite edges, %d rays",ns,nr);
+#endif
+    
+
+    char *res1=readVSIFile(conf,pszDestDataSource);
+    if(res1==NULL)
+      return SERVICE_FAILED;
+    
+    setMapInMaps(outputs,"Result","value",res1);
+    
+    if(strcmp(oDriver,"GML")==0)
+      setMapInMaps(outputs,"Result","mimeType","text/xml");
+    else
+      setMapInMaps(outputs,"Result","mimeType","text/plain");
+
+    setMapInMaps(outputs,"Result","encoding","UTF-8");
+#ifdef DEBUG
+    fprintf(stderr,"\nService internal print\n===\n");
+#endif
+    OGRCleanupAll();
+    return SERVICE_SUCCEEDED;
+  }
+
+}
