Index: trunk/zoo-project/HISTORY.txt
===================================================================
--- trunk/zoo-project/HISTORY.txt	(revision 464)
+++ trunk/zoo-project/HISTORY.txt	(revision 465)
@@ -1,2 +1,16 @@
+Version 1.4.0-dev
+  * Add the optional YAML ZCFG support #4 and the zcfg2yaml converter
+  * Return error messages that enable the service provider to quickly identify the root cause of errors due to configuration file syntax (ticket #90)
+  * Fix logic in addMapToMap (ticket #91)
+  * Enable AllowedValue and multiple Range definitions using default and supported blocks
+  * Add the lastest revision number in version.h (available in Python ZOO-API)
+  * Add the optional Ruby Language Support to the ZOO-Kernel with an API similar to the Python ZOO-API
+  * Small rewrite of Python support
+  * Inputs can be requested over https protocol (ticket #86)
+  * Add capability to define both percentage of execution and a message (ticket #87). 
+  * Add usid in lenv section used to generate an unique identifier based on time and the process identifier.
+  * Add gdal_contour service
+  * Add dynamic definition of serverAddress from the main section
+
 Version 1.3.0-rc2
   * Fix POST Request issue (ticket #34)
Index: trunk/zoo-project/zoo-kernel/Makefile.in
===================================================================
--- trunk/zoo-project/zoo-kernel/Makefile.in	(revision 464)
+++ trunk/zoo-project/zoo-kernel/Makefile.in	(revision 465)
@@ -12,6 +12,6 @@
 JAVA_FILE=@JAVA_FILE@
 
-CFLAGS=-fpic ${MACOS_CFLAGS} ${MS_CFLAGS} -I../../thirds/cgic206 -I. -DLINUX_FREE_ISSUE #-DDEBUG #-DDEBUG_SERVICE_CONF
-LDFLAGS=-lcurl -L../../thirds/cgic206 -lcgic ${GDAL_LIBS} ${XML2LDFLAGS} ${PYTHONLDFLAGS} ${PERLLDFLAGS}  ${PHPLDFLAGS} ${JAVALDFLAGS} ${JSLDFLAGS} -lfcgi -lcrypto ${MS_LDFLAGS} ${MACOS_LD_FLAGS}
+CFLAGS=-fpic ${YAML_CFLAGS} ${MACOS_CFLAGS} ${MS_CFLAGS} -I../../thirds/cgic206 -I. -DLINUX_FREE_ISSUE #-DDEBUG #-DDEBUG_SERVICE_CONF
+LDFLAGS=-lcurl -L../../thirds/cgic206 -lcgic ${GDAL_LIBS} ${XML2LDFLAGS} ${PYTHONLDFLAGS} ${PERLLDFLAGS}  ${PHPLDFLAGS} ${JAVALDFLAGS} ${JSLDFLAGS} -lfcgi -lcrypto ${MS_LDFLAGS} ${MACOS_LD_FLAGS} ${YAML_LDFLAGS} 
 
 PHPCFLAGS=@PHP_CPPFLAGS@
@@ -27,5 +27,8 @@
 
 
-all: zoo_loader.cgi
+all: version.h zoo_loader.cgi ${YAML_FILE1}
+
+version.h:
+	echo "#define ZOO_VERSION \"`svnversion -q -c -n .`\"" > version.h
 
 main_conf_read.tab.c: main_conf_read.y service.h
@@ -57,5 +60,8 @@
 
 service_internal.o: service_internal.c service.h
-	gcc ${JS_ENABLED} ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service_internal.c
+	g++ ${JS_ENABLED} ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service_internal.c
+
+service_yaml.o: service_yaml.c service.h
+	gcc ${YAML_CFLAGS} ${XML2CFLAGS} ${CFLAGS} -fPIC -c service_yaml.c
 
 service_internal_ms.o: service_internal_ms.c
@@ -86,7 +92,11 @@
 	g++ -g -O2 ${XML2CFLAGS} ${CFLAGS} ${PYTHONCFLAGS} ${JAVACFLAGS} ${JSCFLAGS} ${PERLCFLAGS} ${PHPCFLAGS} ${PYTHON_ENABLED} ${JS_ENABLED} ${PHP_ENABLED} ${PERL_ENABLED} ${JAVA_ENABLED} -c zoo_service_loader.c  -fno-common -DPIC -o zoo_service_loader.o
 
-zoo_loader.cgi: zoo_loader.c zoo_service_loader.o  ulinet.o service.h lex.sr.o service_conf.tab.o service_conf.y ulinet.o main_conf_read.tab.o lex.cr.o service_internal.o ${MS_FILE} ${PYTHON_FILE} ${PHP_FILE} ${JAVA_FILE} ${JS_FILE} ${PERL_FILE} ${RUBY_FILE}
+zoo_loader.cgi: zoo_loader.c zoo_service_loader.o  ulinet.o service.h lex.sr.o service_conf.tab.o service_conf.y ulinet.o main_conf_read.tab.o lex.cr.o service_internal.o ${MS_FILE} ${PYTHON_FILE} ${PHP_FILE} ${JAVA_FILE} ${JS_FILE} ${PERL_FILE} ${RUBY_FILE} ${YAML_FILE}
 	g++ -g -O2 ${JSCFLAGS} ${PHPCFLAGS}  ${PERLCFLAGS} ${RUBYCFLAGS}  ${JAVACFLAGS} ${XML2CFLAGS} ${PYTHONCFLAGS} ${CFLAGS} -c zoo_loader.c  -fno-common -DPIC -o zoo_loader.o
-	g++  ${JSCFLAGS} ${GDAL_CFLAGS} ${XML2CFLAGS} ${PHPCFLAGS} ${PERLCFLAGS} ${JAVACFLAGS} ${PYTHONCFLAGS} ${CFLAGS} zoo_loader.o zoo_service_loader.o service_internal.o ${MS_FILE} ${PYTHON_FILE}  ${PERL_FILE} ${PHP_FILE}  ${JS_FILE} ${JAVA_FILE} ulinet.o lex.cr.o lex.sr.o service_conf.tab.o main_conf_read.tab.o -o zoo_loader.cgi ${LDFLAGS}
+	g++  ${JSCFLAGS} ${GDAL_CFLAGS} ${XML2CFLAGS} ${PHPCFLAGS} ${PERLCFLAGS} ${JAVACFLAGS} ${PYTHONCFLAGS} ${CFLAGS} zoo_loader.o zoo_service_loader.o service_internal.o ${MS_FILE} ${PYTHON_FILE}  ${PERL_FILE} ${PHP_FILE}  ${JS_FILE} ${JAVA_FILE} ${YAML_FILE} ulinet.o lex.cr.o lex.sr.o service_conf.tab.o main_conf_read.tab.o -o zoo_loader.cgi ${LDFLAGS}
+
+zcfg2yaml: zcfg2yaml.c  ulinet.o service.h lex.sr.o service_conf.tab.o service_conf.y ulinet.o main_conf_read.tab.o lex.cr.o service_internal.o ${MS_FILE} ${JS_FILE} ${RUBY_FILE}  ${YAML_FILE}
+	g++ -g -O2 ${JSCFLAGS} ${RUBYCFLAGS} ${XML2CFLAGS} ${CFLAGS} -c zcfg2yaml.c  -fno-common -DPIC -o zcfg2yaml.o
+	g++  ${JSCFLAGS} ${XML2CFLAGS} ${CFLAGS} zcfg2yaml.o service_internal.o ${MS_FILE} ${JS_FILE}  ulinet.o lex.cr.o lex.sr.o service_conf.tab.o main_conf_read.tab.o  ${YAML_FILE} -o zcfg2yaml ${LDFLAGS}
 
 install:
Index: trunk/zoo-project/zoo-kernel/ZOOMakefile.opts.in
===================================================================
--- trunk/zoo-project/zoo-kernel/ZOOMakefile.opts.in	(revision 464)
+++ trunk/zoo-project/zoo-kernel/ZOOMakefile.opts.in	(revision 465)
@@ -5,4 +5,9 @@
 	MACOS_CFLAGS=-arch $(shell uname -m)
 endif
+
+YAML_CFLAGS=@YAML_CPPFLAGS@
+YAML_LDFLAGS=@YAML_LDFLAGS@
+YAML_FILE=@YAML_FILE@
+YAML_FILE1=@YAML_FILE1@
 
 GDAL_CFLAGS=@GDAL_CFLAGS@
Index: trunk/zoo-project/zoo-kernel/configure.ac
===================================================================
--- trunk/zoo-project/zoo-kernel/configure.ac	(revision 464)
+++ trunk/zoo-project/zoo-kernel/configure.ac	(revision 465)
@@ -14,5 +14,4 @@
 AC_CHECK_LIB([fl], [main])
 AC_CHECK_LIB([pthread], [main])
-AC_CHECK_LIB([fcgi], [main])
 AC_CHECK_LIB([ssl], [main])
 
@@ -68,4 +67,41 @@
 
 # ===========================================================================
+# Detect if libyaml is available
+# ===========================================================================
+
+AC_ARG_WITH([yaml],
+        [AS_HELP_STRING([--with-yaml=PATH], [specify an alternative location for the fastcgi library])],
+        [YAMLPATH="$withval"], [YAMLPATH=""])
+
+if test -z "$YAMLPATH"
+then
+	YAML_LDFLAGS=""
+	YAML_CPPFLAGS=""
+	YAML_FILE=""
+	YAML_FILE1=""
+else
+
+	# Extract the linker and include flags
+	YAML_LDFLAGS="-L$YAMLPATH/lib -lyaml"
+	YAML_CPPFLAGS="-I$YAMLPATH/include -DYAML"
+	YAML_FILE="service_yaml.o"
+	YAML_FILE1="zcfg2yaml"
+	
+	# Check headers file
+	CPPFLAGS_SAVE="$CPPFLAGS"
+	CPPFLAGS="$YAML_CPPFLAGS"
+	LDFLAGS_SAVE="$LDFLAGS"
+	LDFLAGS="YAML_LDFLAGS"
+	AC_CHECK_LIB([yaml], [yaml_parser_initialize,yaml_parser_set_input_file,yaml_parser_scan])
+	AC_CHECK_HEADERS([yaml.h],
+                 [], [AC_MSG_ERROR([could not find headers include related to YAML])])
+
+fi
+AC_SUBST([YAML_CPPFLAGS])
+AC_SUBST([YAML_LDFLAGS])
+AC_SUBST([YAML_FILE])
+AC_SUBST([YAML_FILE1])
+
+# ===========================================================================
 # Detect if fastcgi is available
 # ===========================================================================
@@ -73,5 +109,5 @@
 AC_ARG_WITH([fastcgi],
         [AS_HELP_STRING([--with-fastcgi=PATH], [specify an alternative location for the fastcgi library])],
-        [FCGIPATH="$withval"], [FCGIPATH=""])
+        [FCGIPATH="$withval"], [FCGIPATH="/usr"])
 
 # Extract the linker and include flags
@@ -82,4 +118,7 @@
 CPPFLAGS_SAVE="$CPPFLAGS"
 CPPFLAGS="$FCGI_CPPFLAGS"
+LDFLAGS_SAVE="LDFLAGS"
+LDFLAGS="$FCGI_LDFLAGS"
+AC_CHECK_LIB([fcgi], [main])
 AC_CHECK_HEADERS([fcgi_stdio.h],
                  [], [AC_MSG_ERROR([could not find headers include related to fastcgi])])
Index: trunk/zoo-project/zoo-kernel/main.cfg
===================================================================
--- trunk/zoo-project/zoo-kernel/main.cfg	(revision 464)
+++ trunk/zoo-project/zoo-kernel/main.cfg	(revision 465)
@@ -1,30 +1,114 @@
-[main]
-encoding = utf-8
-version = 1.0.0
-serverAddress = http://www.zoo-project.org/zoo/
-lang = fr-FR,en-CA
-tmpPath=/YourFullTmpPathHere/
-tmpUrl = ../TmpPathRelativeToServerAdress/
-dataPath = /YouFullDataPathHere/
+[mm]
+biLayerAlias=Carte,Ortophoto,Ortophoto 2005,Parcels,Etat Major,Cassini,Elev
+editingToolbar=select,add,edit
+navName=Authenticate,Permalink,Twitter sharing,Facebook sharing,Scroll,Pan,Geolocate,Track my position,Zoom Box,Zoom To Max Extent,Identify,Identify Circle,Mesure Distance,Mesure Area,Print,Profile
+scales=443744273,221872136,110936068,55468034,27734017,13867008,6933504,3466752,1733376,866688,433344,216672,108336,54168,27084,13542,6771,3385,1692
+rasterToolbarAlias=Profile,Contour,Shaded Relief,Color Relief,Slope Map,Clip
+supportedDbs=PostGIS,MySQL
+mapcacheUrl=http://127.0.0.1/cache/
+biLayers=GEOGRAPHICALGRIDSYSTEMS.MAPS,ORTHOIMAGERY.ORTHOPHOTOS,ORTHOIMAGERY.ORTHOPHOTOS2000-2005,CADASTRALPARCELS.PARCELS,GEOGRAPHICALGRIDSYSTEMS.ETATMAJOR40,GEOGRAPHICALGRIDSYSTEMS.CASSINI,ELEVATION.SLOPES
+bgLayers=google.maps.MapTypeId.TERRAIN,null,google.maps.MapTypeId.SATELLITE,google.maps.MapTypeId.HYBRID
+bpDefault=g
+bgName=Google
+bbLayers=Road,Aerial,AerialWithLabels
+navIcon=auth,permalink,tshare,fshare,scroll,pan,geoloc,track,zoom-in,zoomtomaxextent,info,infocircle,dist,area,print,terrain-profile
+bbName=Bing
+boLayerAlias=OpenStreetMap
+bmLayerAlias=Streets,Satelite
+toolbars=Vector
+navId=authenticate,permalink,tshare,fshare,scroll,control,geolocate,track,zoomin,zoomtomaxextent,getFeature,getFeatureCircle,line,polygon,print,profile
+navIdX=authenticate,permalink,tshare,fshare,zoomtomaxextent,print
+navIdXX=scroll
+navIdF=loadLoginForm,permalink,shareOnTwitter,shareOnFB,gotoMaxExtent,printIntoDocument
+nvIID=getFeature,getFeatureCircle
+osmApiUrl=http://open.mapquestapi.com/xapi/api/0.6/
+vectorToolbar=buffer,spatial-buffer,centroid,boundary,convexhull,simplify,spatial-query
+bmLayers=Map,Aerial
+boName=OSM
+editingToolbarAlias=Select feature,Add feature,Edit feature
+boLayers=OSM
+address=http://127.0.0.1/mm
+bmName=MapQuest
+bpList=g,b,i
+uomsName=Foot,Meter,Deegree
+adminTheme=green
+vectorToolbarAlias=Buffer,BufferMask,Centroid,Boundary,ConvexHull,Simplify,SpatialQuery
+mapcacheCfg=/Users/djay/Sites/mapcache.xml
+dateFormat=%A %d %B %Y
+uomsId=english,metric,geographic
+oldToolbars=Editing,Raster
+rasterToolbar=profile,contour,shaded_relief,color_relief,slope_map,clip
+bgLayerAlias=Physical,Streets,Satelite,Hybrid
+bbLayerAlias=Streets,Satelite,Hybrid
+sizeLimit=100M
+biName=IGN
+
+[headers]
+X-Powered-By=ZOO-Project@MapMint
 
 [identification]
-title = The Zoo WPS Development Server
-abstract = Development version of ZooWPS. See http://www.zoo-project.org
-fees = None
-accessConstraints = none
-keywords = WPS,GIS,buffer
+keywords=WPS,GIS,buffer,MapMint,ZOO-Project
+title=ZOO-Project WPS Production Server
+abstract=Development version of ZooWPS. See http://www.zoo-project.org
+accessConstraints=none
+fees=None
 
 [provider]
-providerName=ZOO Project
-providerSite=http://www.zoo-project.org
+positionName=Developer
+providerName=GeoLabs SARL
+addressAdministrativeArea=False
+addressDeliveryPoint=1280, avenue des Platanes
+addressCountry=fr
+phoneVoice=+33 4 67 43 09 95
+addressPostalCode=34970
+role=Dev
+providerSite=http://www.geolabs.fr
+phoneFacsimile=False
+addressElectronicMailAddress=gerald@geolabs.fr
+addressCity=Lattes
 individualName=Gerald FENOY
-positionName=Developer
-role=Dev
-addressDeliveryPoint=1280, avenue des Platanes
-addressCity=Lattes
-addressAdministrativeArea=False
-addressPostalCode=34970
-addressCountry=fr
-addressElectronicMailAddress=gerald@geolabs.fr
-phoneVoice=False
-phoneFacsimile=False
+
+[main]
+encoding=utf-8
+isTrial=true
+dataPath=/Users/djay/Sites/data
+tmpPath=/Users/djay/Sites/tmp
+supportedDbs=PostGIS,MySQL,WFS
+cacheDir=/Users/djay/Sites/cache
+rootUrl=/~djay/mm-np/public/
+publicationUrl=/~djay/pm-np/
+dblink=/Users/djay/Sites/mm.db
+mmPath=/Users/djay/Sites/mm-np/
+sessPath=/Users/djay/Sites/tmp
+version=1.0.0
+dbuser=npdb
+dcount=3
+dbuserName=np
+3D=false
+Rpy2=true
+applicationAddress=http://127.0.0.1/~djay/mm-np/
+mmAddress=/~djay/mm-np/
+publicationPath=/Users/djay/Sites/pm-np/
+msOgcVersion=1.0.0
+serverAddress=http://127.0.0.1/np-bin/zoo_loader.cgi
+lang=fr-FR,en-US,ja-JP
+mapserverAddress=http://127.0.0.1/np-bin/mapserv.cgi
+tmpUrl=http://127.0.0.1/~djay/tmp/
+templatesPath=/Users/djay/Sites/mm-np/templates/
+templatesAddress=http://127.0.0.1/~djay/pm-np/tmpl/
+crs=IGNF:LAMB93
+jsCache=dev
+cssCache=prod
+cookiePrefix=MMID
+
+[npdb]
+host=127.0.0.1
+schema=velo
+user=postgres
+dbname=demogis
+port=5432
+
+[oo]
+external=true
+path=/Applications/LibreOffice.app/Contents/program/python
+ghostscript=/usr/local/bin/gs
Index: trunk/zoo-project/zoo-kernel/main_conf_read.y
===================================================================
--- trunk/zoo-project/zoo-kernel/main_conf_read.y	(revision 464)
+++ trunk/zoo-project/zoo-kernel/main_conf_read.y	(revision 465)
@@ -8,15 +8,9 @@
 #include <service.h>
 
-static int defaultsc=0;
 static maps* my_maps=NULL;
 static maps* current_maps=NULL;
-static map* previous_content=NULL;
 static map* current_content=NULL;
-static elements* current_element=NULL;
-static map* scontent=NULL;
 static char* curr_key;
 static int debug=0;
-static int previous_data=0;
-static int current_data=0;
 using namespace std;
 
Index: trunk/zoo-project/zoo-kernel/makefile.vc
===================================================================
--- trunk/zoo-project/zoo-kernel/makefile.vc	(revision 464)
+++ trunk/zoo-project/zoo-kernel/makefile.vc	(revision 465)
@@ -9,4 +9,10 @@
 
 all:  zoo_loader.cgi
+
+version.h:
+	svnversion -q -c -n . > version_0.h
+	set /p VERS=<version_0.h
+	rm version_0.h
+	echo #define ZOO_VERSION "%VERS%" > version.h
 
 main_conf_read.tab.c: main_conf_read.y service.h
Index: trunk/zoo-project/zoo-kernel/service.h
===================================================================
--- trunk/zoo-project/zoo-kernel/service.h	(revision 464)
+++ trunk/zoo-project/zoo-kernel/service.h	(revision 465)
@@ -82,4 +82,5 @@
 #define SHMSZ     27
 
+#include "version.h" 
 
 #ifdef DEBUG_STACK
@@ -133,5 +134,5 @@
   static void _dumpMap(map* t){
     if(t!=NULL){
-      fprintf(stderr,"[%s] => [%s] \n",t->name,t->value);
+      fprintf(stderr,"%s: %s\n",t->name,t->value);
       fflush(stderr);
 	}else{
@@ -437,18 +438,8 @@
     map* tmp=mi;
     map* _cursor=*mo;
-    if(tmp==NULL){
-      if(_cursor!=NULL){
-	while(_cursor!=NULL)
-	  _cursor=_cursor->next;
-	_cursor=NULL;
-      }else
-	*mo=NULL;
-    }
     while(tmp!=NULL){
       if(_cursor==NULL){
-	if(*mo==NULL)
-	  *mo=createMap(tmp->name,tmp->value);
-	else
-	  addToMap(*mo,tmp->name,tmp->value);
+	*mo=createMap(tmp->name,tmp->value);
+	(*mo)->next=NULL;
       }
       else{
@@ -457,9 +448,15 @@
 	dumpMap(_cursor);
 #endif
-	while(_cursor!=NULL)
+	while(_cursor->next!=NULL)
 	  _cursor=_cursor->next;
-	_cursor=createMap(tmp->name,tmp->value);
-	_cursor->next=NULL;
-      }
+	map* tmp1=getMap(_cursor,tmp->name);
+	if(tmp1==NULL)
+	  _cursor->next=createMap(tmp->name,tmp->value);
+	else{
+	  free(tmp1->value);
+	  tmp1->value=zStrdup(tmp->value);
+	}
+      }
+      _cursor=*mo;
       tmp=tmp->next;
 #ifdef DEBUG
@@ -568,10 +565,14 @@
       if(_cursor==NULL){
 	*mo=dupMaps(&mi);
-	(*mo)->next=NULL;
       }
       else{
+	maps* tmp1=getMaps(*mo,tmp->name);
 	while(_cursor->next!=NULL)
 	  _cursor=_cursor->next;
-	_cursor->next=dupMaps(&tmp);
+	if(tmp1==NULL)
+	  _cursor->next=dupMaps(&tmp);
+	else
+	  addMapToMap(&tmp1->content,tmp->content);
+	_cursor=*mo;
       }
       tmp=tmp->next;
@@ -603,10 +604,10 @@
     else
       sprintf(tmp,"%s",key);
-    map* tmpSize=getMapArray(m,"size",index);
+    map* tmpSize=getMapArray(m,(char*)"size",index);
     if(tmpSize!=NULL && strncasecmp(key,"value",5)==0){
 #ifdef DEBUG
       fprintf(stderr,"%s\n",tmpSize->value);
 #endif
-      map* ptr=getMapOrFill(m,tmp,"");
+      map* ptr=getMapOrFill(m,tmp,(char *)"");
       free(ptr->value);
       ptr->value=(char*)malloc((atoi(tmpSize->value)+1)*sizeof(char));
@@ -618,5 +619,5 @@
 
   static map* getMapType(map* mt){
-    map* tmap=getMap(mt,"mimeType");
+    map* tmap=getMap(mt,(char *)"mimeType");
     if(tmap==NULL){
       tmap=getMap(mt,"dataType");
@@ -646,12 +647,12 @@
 
     char *tmpV[8]={
-      "size",
-      "value",
-      "uom",
-      "Reference",
-      "xlink:href",
+      (char*)"size",
+      (char*)"value",
+      (char*)"uom",
+      (char*)"Reference",
+      (char*)"xlink:href",
       typ,
-      "schema",
-      "encoding"
+      (char*)"schema",
+      (char*)"encoding"
     };
     sprintf(tmpLen,"%d",len+1);
@@ -730,4 +731,75 @@
   }
 
+  static void dumpElementsAsYAML(elements* e){
+    elements* tmp=e;
+    while(tmp!=NULL){
+      for(int i=0;i<2;i++)
+	fprintf(stderr," ");
+      fprintf(stderr,"%s:\n",tmp->name);
+      map* mcurs=tmp->content;
+      while(mcurs!=NULL){
+	for(int i=0;i<4;i++)
+	  fprintf(stderr," ");
+	_dumpMap(mcurs);
+	mcurs=mcurs->next;
+      }
+      mcurs=tmp->metadata;
+      if(mcurs!=NULL){
+	for(int i=0;i<4;i++)
+	  fprintf(stderr," ");
+	fprintf(stderr,"MetaData:\n");
+	while(mcurs!=NULL){
+	  for(int i=0;i<6;i++)
+	    fprintf(stderr," ");
+	  _dumpMap(mcurs);
+	  mcurs=mcurs->next;
+	}
+      }
+      for(int i=0;i<4;i++)
+	fprintf(stderr," ");
+      fprintf(stderr,"%s:\n",tmp->format);
+      iotype* tmpio=tmp->defaults;
+      int ioc=0;
+      while(tmpio!=NULL){
+	for(int i=0;i<6;i++)
+	  fprintf(stderr," ");
+	fprintf(stderr,"default:\n");
+	mcurs=tmpio->content;
+	while(mcurs!=NULL){
+	  for(int i=0;i<8;i++)
+	    fprintf(stderr," ");
+	  if(strcasecmp(mcurs->name,"range")==0){
+	    fprintf(stderr,"range: \"%s\"\n",mcurs->value);
+	  }else
+	    _dumpMap(mcurs);
+	  mcurs=mcurs->next;
+	}
+	tmpio=tmpio->next;
+	ioc++;
+      }
+      tmpio=tmp->supported;
+      ioc=0;
+      while(tmpio!=NULL){
+	for(int i=0;i<6;i++)
+	  fprintf(stderr," ");
+	fprintf(stderr,"supported:\n");
+	mcurs=tmpio->content;
+	while(mcurs!=NULL){
+	  for(int i=0;i<8;i++)
+	    fprintf(stderr," ");
+	  if(strcasecmp(mcurs->name,"range")==0){
+	    fprintf(stderr,"range: \"%s\"\n",mcurs->value);
+	  }else
+	    _dumpMap(mcurs);
+	  mcurs=mcurs->next;
+	}
+	tmpio=tmpio->next;
+	ioc++;
+      }
+      tmp=tmp->next;
+    }
+  }
+
+
   static elements* dupElements(elements* e){
     elements* cursor=e;
@@ -805,4 +877,31 @@
     }
     fprintf(stderr,"++++++++++++++++++\n");
+  }
+
+  static void dumpServiceAsYAML(service* s){
+    int level=0;
+    fprintf(stderr,"# %s\n\n",s->name);
+    if(s->content!=NULL){
+      map* mcurs=s->content;
+      dumpMap(mcurs);
+      mcurs=s->metadata;
+      if(mcurs!=NULL){
+	fprintf(stderr,"MetaData:\n");
+	while(mcurs!=NULL){
+	  for(int i=0;i<2;i++)
+	    fprintf(stderr," ");
+	  _dumpMap(mcurs);
+	  mcurs=mcurs->next;
+	}
+      }
+    }
+    if(s->inputs!=NULL){
+      fprintf(stderr,"\ninputs:\n",s->name);
+      dumpElementsAsYAML(s->inputs);
+    }
+    if(s->outputs!=NULL){
+      fprintf(stderr,"\noutputs:\n",s->name);
+      dumpElementsAsYAML(s->outputs);
+    }
   }
 
Index: trunk/zoo-project/zoo-kernel/service_conf.l
===================================================================
--- trunk/zoo-project/zoo-kernel/service_conf.l	(revision 464)
+++ trunk/zoo-project/zoo-kernel/service_conf.l	(revision 465)
@@ -22,5 +22,5 @@
 #endif
 
-
+char *lmsg;
 int attentionImpossibleDeTrouverXMLDeclapres = 0 ;
 
@@ -41,5 +41,5 @@
 
 attname	[a-zA-Z0-9_\-]+
-attvalue1	[\^\*\+,;@a-zA-Z0-9_\-::.:" "\"\'/\\\(\)\t\|\$\&>]+
+attvalue1	[\^\*\+,;@a-zA-Z0-9_\-::.:" "\"\'/\\\(\)\t\|\$\&>\[\]]+
 
 attvalue		\"[^"]*\"|\'[^']*\'\(\)
@@ -118,5 +118,5 @@
 
 
-<INITIAL,DANSBALISE,HORSBALISE>.|\n	{fprintf(stderr,"error : ligne %d : caractere non reconnu '%s'\n",srlineno,yytext);}
+<INITIAL,DANSBALISE,HORSBALISE>.|\n	{lmsg=(char*)malloc(1024*sizeof(char));sprintf(lmsg,"error: line %d: character not allowed '%s'",srlineno,yytext);fprintf(stderr,"%s \n",lmsg);srlval.chaine=lmsg;return -1;}
 
 %%
Index: trunk/zoo-project/zoo-kernel/service_conf.y
===================================================================
--- trunk/zoo-project/zoo-kernel/service_conf.y	(revision 464)
+++ trunk/zoo-project/zoo-kernel/service_conf.y	(revision 465)
@@ -24,10 +24,7 @@
 static bool wait_outputs=false;
 static bool wait_data=false;
-static int services_c=0;
 static service* my_service=NULL;
-static map* previous_content=NULL;
 static map* current_content=NULL;
 static elements* current_element=NULL;
-static map* scontent=NULL;
 static char* curr_key;
 static int debug=0;
@@ -772,19 +769,19 @@
  * definition file.
  */
-int getServiceFromFile(const char* file,service** service){
-
-  freeMap(&previous_content);
-  previous_content=NULL;
-  freeMap(&current_content);
-  current_content=NULL;
-  freeMap(&scontent);
+int getServiceFromFile(maps* conf,const char* file,service** service){
+  if(current_content!=NULL){
+    freeMap(&current_content);
+    free(current_content);
+    current_content=NULL;
+  }
 #ifdef DEBUG_SERVICE_CONF
   fprintf(stderr,"(STARTING)FREE current_element\n");
 #endif
-  freeElements(&current_element);
-  free(current_element);
-  current_element=NULL;
+  if(current_element!=NULL){
+    freeElements(&current_element);
+    free(current_element);
+    current_element=NULL;
+  }
   my_service=NULL;
-  scontent=NULL;
 
   wait_maincontent=true;
@@ -810,4 +807,7 @@
   int resultatYYParse = srparse() ;
   
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"RESULT: %d %d\n",resultatYYParse,wait_outputs);
+#endif
   if(wait_outputs && current_element!=NULL && current_element->name!=NULL){
     if(my_service->outputs==NULL){      
@@ -848,5 +848,13 @@
   dumpService(my_service);
 #endif
-  *service=my_service;
+  if(wait_outputs<0 || my_service==NULL || my_service->name==NULL || my_service->content==NULL || my_service->inputs==NULL || my_service->outputs==NULL){
+    setMapInMaps(conf,"lenv","message",srlval.chaine);
+#ifndef WIN32
+    srlex_destroy();
+#endif
+    return -1;
+  }
+  else
+    *service=my_service;
 
 #ifndef WIN32
Index: trunk/zoo-project/zoo-kernel/service_internal.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal.c	(revision 464)
+++ trunk/zoo-project/zoo-kernel/service_internal.c	(revision 465)
@@ -34,4 +34,14 @@
 #define FALSE -1
 #endif
+
+int readServiceFile(maps* conf, char* file,service** service,char *name){
+  int t=getServiceFromFile(conf,file,service);
+#ifdef YAML
+  if(t<0){
+    t=getServiceFromYAML(conf,file,service,name);
+  }
+#endif
+  return t;
+}
 
 void printHeaders(maps* m){
@@ -883,5 +893,5 @@
 
 void printFullDescription(elements *elem,const char* type,xmlNsPtr ns_ows,xmlNodePtr nc1){
-  char *orderedFields[12];
+  char *orderedFields[13];
   orderedFields[0]="mimeType";
   orderedFields[1]="encoding";
@@ -892,8 +902,9 @@
   orderedFields[6]="value";
   orderedFields[7]="AllowedValues";
-  orderedFields[8]="rangeMin";
-  orderedFields[9]="rangeMax";
-  orderedFields[10]="rangeClosure";
-  orderedFields[11]="rangeSpace";
+  orderedFields[8]="range";
+  orderedFields[9]="rangeMin";
+  orderedFields[10]="rangeMax";
+  orderedFields[11]="rangeClosure";
+  orderedFields[12]="rangeSpace";
 
   xmlNodePtr nc2,nc3,nc4,nc5,nc6,nc7,nc8;
@@ -935,4 +946,5 @@
 	nc3 = xmlNewNode(NULL, BAD_CAST e->format);
     }
+    iotype* _tmp0=NULL;
     iotype* _tmp=e->defaults;
     int datatype=0;
@@ -961,5 +973,5 @@
       int dcnt=0;
       int oI=0;
-      for(oI=0;oI<12;oI++)
+      for(oI=0;oI<13;oI++)
 	if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
 	  //while(tmp1!=NULL){
@@ -1018,5 +1030,6 @@
 		  token=strtok_r(NULL,",",&saveptr1);
 		}
-		if(getMap(_tmp->content,"rangeMin")!=NULL ||
+		if(getMap(_tmp->content,"range")!=NULL ||
+		   getMap(_tmp->content,"rangeMin")!=NULL ||
 		   getMap(_tmp->content,"rangeMax")!=NULL ||
 		   getMap(_tmp->content,"rangeClosure")!=NULL )
@@ -1029,6 +1042,57 @@
 		  nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
 		doRange:
+		  
+		  /**
+		   * Range: Table 46 OGC Web Services Common Standard
+		   */
 		  nc8 = xmlNewNode(ns_ows, BAD_CAST "Range");
-		  map *tmp0=getMap(tmp1,"rangeMin");
+
+		  map* tmp0=getMap(tmp1,"range");
+		  if(tmp0!=NULL){
+		    char* pToken;
+		    char* orig=zStrdup(tmp0->value);
+		    /**
+		     * RangeClosure: Table 47 OGC Web Services Common Standard
+		     */
+		    char *tmp="closed";
+		    if(orig[0]=='[' && orig[strlen(orig)-1]=='[')
+		      tmp="closed-open";
+		    else
+		      if(orig[0]==']' && orig[strlen(orig)-1]==']')
+			tmp="open-closed";
+		      else
+			if(orig[0]==']' && orig[strlen(orig)-1]=='[')
+			  tmp="open";
+		    xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
+		    pToken=strtok(orig,",");
+		    int nci0=0;
+		    while(pToken!=NULL){
+		      char *tmpStr=(char*) malloc((strlen(pToken))*sizeof(char));
+		      if(nci0==0){
+			nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
+			int nci=1;
+			for(nci=1;nci<strlen(pToken);nci++){
+			  tmpStr[nci-1]=pToken[nci];
+			}
+		      }else{
+			nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
+			int nci=0;
+			for(nci=0;nci<strlen(pToken)-1;nci++){
+			  tmpStr[nci]=pToken[nci];
+			}
+		      }
+		      xmlAddChild(nc7,xmlNewText(BAD_CAST tmpStr));
+		      xmlAddChild(nc8,nc7);
+		      nci0++;
+		      pToken = strtok(NULL,",");
+		    }		    
+		    if(getMap(tmp1,"rangeSpacing")==NULL){
+		      nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
+		      xmlAddChild(nc7,xmlNewText(BAD_CAST "1"));
+		      xmlAddChild(nc8,nc7);
+		    }
+		  }else{
+
+		  tmp0=getMap(tmp1,"rangeMin");
 		  if(tmp0!=NULL){
 		    nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
@@ -1068,8 +1132,23 @@
 		  }else
 		    xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST "closed");
+		  }
+		  if(_tmp0==NULL){
+		    xmlAddChild(nc6,nc8);
+		    _tmp0=e->supported;
+		    tmp1=_tmp0->content;
+		    goto doRange;
+		  }else{
+		    _tmp0=_tmp0->next;
+		    if(_tmp0!=NULL){
+		      xmlAddChild(nc6,nc8);
+		      tmp1=_tmp0->content;
+		      goto doRange;
+		    }
+		  
+		  }
+		  xmlAddChild(nc6,nc8);
+		  xmlAddChild(nc3,nc6);
+		  isAnyValue=-1;
 		}
-		xmlAddChild(nc6,nc8);
-		xmlAddChild(nc3,nc6);
-		isAnyValue=-1;
 	      }
 	    }
@@ -1096,4 +1175,16 @@
 	  avcnt++;
 	}
+      }
+      
+      map* metadata=e->metadata;
+      xmlNodePtr n;
+      int xlinkId=zooXmlAddNs(n,"http://www.w3.org/1999/xlink","xlink");
+      xmlNsPtr ns_xlink=usedNs[xlinkId];
+
+      while(metadata!=NULL){
+	nc6=xmlNewNode(ns_ows, BAD_CAST "MetaData");
+	xmlNewNsProp(nc6,ns_xlink,BAD_CAST metadata->name,BAD_CAST metadata->value);
+	xmlAddChild(nc2,nc6);
+	metadata=metadata->next;
       }
     }
Index: trunk/zoo-project/zoo-kernel/service_internal.h
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal.h	(revision 464)
+++ trunk/zoo-project/zoo-kernel/service_internal.h	(revision 465)
@@ -65,5 +65,5 @@
 #include "ulinet.h"
 
-extern   int getServiceFromFile(const char*,service**);
+extern   int getServiceFromFile(maps*,const char*,service**);
 extern   int conf_read(const char*,maps*);
 
@@ -88,4 +88,8 @@
   static char* nsName[10];
   static int nbNs=0;
+
+  int getServiceFromYAML(maps*,char*,service**,char *name);
+  int readServiceFile(maps*, char*,service**,char *);
+  
 
   void printHeaders(maps*);
Index: trunk/zoo-project/zoo-kernel/service_internal_python.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 464)
+++ trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 465)
@@ -101,4 +101,8 @@
   tmp = PyInt_FromLong(4);
   PyDict_SetItemString(d, "SERVICE_FAILED", tmp);
+  Py_DECREF(tmp);
+
+  tmp = PyString_FromString(ZOO_VERSION);
+  PyDict_SetItemString(d, "VERSION", tmp);
   Py_DECREF(tmp);
 
Index: trunk/zoo-project/zoo-kernel/service_yaml.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_yaml.c	(revision 465)
+++ trunk/zoo-project/zoo-kernel/service_yaml.c	(revision 465)
@@ -0,0 +1,453 @@
+/**
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2014 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 <stdio.h>
+#include <ctype.h>
+#include <service.h>
+#include <yaml.h>
+
+static service* my_service=NULL;
+static map* current_content=NULL;
+static elements* current_element=NULL;
+static char* curr_key;
+
+/**
+ * getServiceFromFile :
+ * set service given as second parameter with informations extracted from the
+ * definition file.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getServiceFromYAML(maps* conf, char* file,service** service,char *name){
+  FILE *fh = fopen("test.yml", "r");
+  if(current_content!=NULL){
+    freeMap(&current_content);
+    free(current_content);
+    current_content=NULL;
+  }
+#ifdef DEBUG_SERVICE_CONF
+  fprintf(stderr,"(STARTING)FREE current_element\n");
+#endif
+  if(current_element!=NULL){
+    freeElements(&current_element);
+    free(current_element);
+    current_element=NULL;
+  }
+  my_service=NULL;
+  
+  my_service=*service;
+  my_service->name=strdup(name);
+  my_service->content=NULL;
+  my_service->metadata=NULL;
+  my_service->inputs=NULL;
+  my_service->outputs=NULL;
+  fh = fopen(file,"r");
+  if (fh==NULL){
+    fprintf(stderr,"error : file not found\n") ;
+    return -1;
+  }
+  yaml_parser_t parser;
+  yaml_token_t  token;   /* new variable */
+
+  /* Initialize parser */
+  if(!yaml_parser_initialize(&parser))
+    fputs("Failed to initialize parser!\n", stderr);
+  if(fh == NULL)
+    fputs("Failed to open file!\n", stderr);
+  /* Set input file */
+  yaml_parser_set_input_file(&parser, fh);
+  /* BEGIN new code */
+  int level=0;
+  int plevel=level;
+  int ilevel=-1;
+  int blevel=-1;
+  int ttype=0;
+  int wait_metadata=-1;
+  char *cur_key;
+  do {
+    yaml_parser_scan(&parser, &token);
+    switch(token.type)
+    {
+    /* Stream start/end */
+    case YAML_STREAM_START_TOKEN: 
+#ifdef DEBUG_YAML
+      puts("STREAM START"); 
+#endif
+      break;
+    case YAML_STREAM_END_TOKEN:   
+#ifdef DEBUG_YAML
+      puts("STREAM END");   
+#endif
+      break;
+    /* Token types (read before actual token) */
+    case YAML_KEY_TOKEN:   
+#ifdef DEBUG_YAML
+      printf("(Key token)   "); 
+#endif
+      ttype=0;
+      break;
+    case YAML_VALUE_TOKEN: 
+#ifdef DEBUG_YAML
+      printf("(Value token) "); 
+#endif
+      ttype=1;
+      break;
+    /* Block delimeters */
+    case YAML_BLOCK_SEQUENCE_START_TOKEN: 
+#ifdef DEBUG_YAML
+      puts("<b>Start Block (Sequence)</b>"); 
+#endif
+      break;
+    case YAML_BLOCK_ENTRY_TOKEN:          
+#ifdef DEBUG_YAML
+      puts("<b>Start Block (Entry)</b>");    
+#endif
+      break;
+    case YAML_BLOCK_END_TOKEN:      
+      blevel--;
+      if(ilevel>=0)
+	ilevel--;
+#ifdef DEBUG_YAML
+      printf("<b>End block</b> (%d,%d,%d,%d)\n", blevel,level,ilevel,ttype); 
+#endif
+      break;
+    /* Data */
+    case YAML_BLOCK_MAPPING_START_TOKEN:  
+#ifdef DEBUG_YAML
+      puts("[Block mapping]");            
+#endif
+      blevel++;
+      break;
+    case YAML_SCALAR_TOKEN:  
+      if(ttype==0){
+	cur_key=zStrdup(token.data.scalar.value);
+      }
+      if(ttype==1){
+	if(current_content==NULL){
+	  current_content=createMap(cur_key,token.data.scalar.value);
+	}else{
+	  addToMap(current_content,cur_key,token.data.scalar.value);
+	}
+	free(cur_key);
+	cur_key=NULL;
+      }
+
+      if(ttype==0 && blevel==0 && level==0 && strcasecmp(token.data.scalar.value,"MetaData")==0 && blevel==0){
+	addMapToMap(&my_service->content,current_content);
+#ifdef DEBUG_YAML
+	fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	freeMap(&current_content);
+	free(current_content);
+	current_content=NULL;
+	wait_metadata=1;
+      }
+      if(ttype==0 && blevel>0 && level>0 && strcasecmp(token.data.scalar.value,"MetaData")==0){
+	if(current_element->content==NULL && current_content!=NULL)
+	  addMapToMap(&current_element->content,current_content);
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	freeMap(&current_content);
+	free(current_content);
+	current_content=NULL;
+	wait_metadata=1;
+      }
+      if(ttype==0 && strcasecmp(token.data.scalar.value,"inputs")==0 && blevel==0){
+	if(wait_metadata>0){
+	  addMapToMap(&my_service->metadata,current_content);
+	  wait_metadata=-1;
+	}else{
+	  if(current_content!=NULL && my_service->content==NULL)
+	    addMapToMap(&my_service->content,current_content);
+	}
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	freeMap(&current_content);
+	free(current_content);
+	current_content=NULL;
+	wait_metadata=false;
+	level++;
+      }
+      if(ttype==0 && strcasecmp(token.data.scalar.value,"outputs")==0 && blevel==1){
+	level++;
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	printf("\n***\n%d (%d,%d,%d,%d)\n+++\n", current_element->defaults==NULL,blevel,level,ilevel,ttype); 
+#endif
+	if(current_element->defaults==NULL && current_content!=NULL && ilevel<0){
+	  current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+	  current_element->defaults->content=NULL;
+	  current_element->defaults->next=NULL;
+	  addMapToMap(&current_element->defaults->content,current_content);
+#ifdef DEBUG_YAML
+	  dumpElements(current_element);
+	  dumpMap(current_content);
+	  fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	  freeMap(&current_content);
+	  free(current_content);
+	  current_content=NULL;
+	}else{
+	  if(current_content!=NULL && ilevel<=0){
+	    addMapToIoType(&current_element->supported,current_content);
+#ifdef DEBUG_YAML
+	    dumpElements(current_element);
+	    dumpMap(current_content);
+	    fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	    freeMap(&current_content);
+	    free(current_content);
+	    current_content=NULL;
+	  }
+	}
+      }
+      if(level==1 && strcasecmp(token.data.scalar.value,"default")==0){
+	ilevel=0;
+      }
+      if(level==1 && strcasecmp(token.data.scalar.value,"supported")==0){
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	printf("\n***\n%d (%d,%d,%d,%d)\n+++\n", current_element->defaults==NULL,blevel,level,ilevel,ttype); 
+#endif
+	if(current_element->defaults==NULL && current_content!=NULL && ilevel<0){
+	  current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+	  current_element->defaults->content=NULL;
+	  current_element->defaults->next=NULL;
+	  addMapToMap(&current_element->defaults->content,current_content);
+#ifdef DEBUG_YAML
+	  dumpElements(current_element);
+	  dumpMap(current_content);
+	  fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	  freeMap(&current_content);
+	  free(current_content);
+	  current_content=NULL;
+	}else{
+	  if(current_content!=NULL && ilevel<=0){
+	    if(current_element->supported==NULL){
+	      current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
+	      current_element->supported->content=NULL;
+	      current_element->supported->next=NULL;
+	    }
+	    addMapToMap(&current_element->supported->content,current_content);
+#ifdef DEBUG_YAML
+	    dumpElements(current_element);
+	    fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	    freeMap(&current_content);
+	    free(current_content);
+	    current_content=NULL;
+	  }
+	}
+	ilevel=1;
+      }
+
+
+      if(strncasecmp(token.data.scalar.value,"ComplexData",11)==0 || strncasecmp(token.data.scalar.value,"LiteralData",10)==0
+	 || strncasecmp(token.data.scalar.value,"ComplexOutput",13)==0 || strncasecmp(token.data.scalar.value,"LiteralOutput",12)==0
+	 || strncasecmp(token.data.scalar.value,"BoundingBoxOutput",13)==0 || strncasecmp(token.data.scalar.value,"BoundingBoxData",12)==0){
+	current_element->format=zStrdup(token.data.scalar.value);
+	free(cur_key);
+	cur_key=NULL;
+	if(wait_metadata>0 && current_content!=NULL){
+	  addMapToMap(&current_element->metadata,current_content);
+	  wait_metadata=-1;
+	}else{
+	  if(current_content!=NULL){
+	    addMapToMap(&current_element->content,current_content);
+	  }
+	}
+#ifdef DEBUG_YAML
+	dumpMap(current_content);
+	fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+	freeMap(&current_content);
+	free(current_content);
+	current_content=NULL;
+#ifdef DEBUG_YAML
+	dumpElements(current_element);
+#endif
+      }
+
+      if(blevel==1 && level==1){
+	if(current_element!=NULL && current_content!=NULL){
+	  if(current_element->defaults==NULL){
+	    current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+	    current_element->defaults->content=NULL;
+	    current_element->defaults->next=NULL;
+	    addMapToMap(&current_element->defaults->content,current_content);
+	  }else{
+	    if(current_element->supported==NULL){
+	      current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
+	      current_element->supported->content=NULL;
+	      current_element->supported->next=NULL;
+	      addMapToMap(&current_element->supported->content,current_content);
+	    }else
+	      addMapToIoType(&current_element->supported,current_content);
+	  }
+	}
+	if(current_element!=NULL){
+	  if(my_service->inputs==NULL)
+	    my_service->inputs=dupElements(current_element);
+	  else
+	    addToElements(&my_service->inputs,current_element);
+	  freeElements(&current_element);
+	  free(current_element);
+	}
+	plevel=level;
+	current_element=(elements*)malloc(ELEMENTS_SIZE);
+	current_element->name=strdup(token.data.scalar.value);
+	current_element->content=NULL;
+	current_element->metadata=NULL;
+	current_element->format=NULL;
+	current_element->defaults=NULL;
+	current_element->supported=NULL;
+	current_element->next=NULL;
+	
+      }
+      if(blevel==1 && level==2){
+	if(current_element!=NULL && current_content!=NULL){
+	  if(current_element->defaults==NULL){
+	    current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+	    current_element->defaults->content=NULL;
+	    current_element->defaults->next=NULL;
+	    addMapToMap(&current_element->defaults->content,current_content);
+	  }else{
+	    if(current_element->supported==NULL){
+	      current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
+	      current_element->supported->content=NULL;
+	      current_element->supported->next=NULL;
+	      addMapToMap(&current_element->supported->content,current_content);
+	    }else
+	      addMapToIoType(&current_element->supported,current_content);
+	  }
+	}
+	if(current_element!=NULL){
+	  if(plevel==level){
+	    if(my_service->outputs==NULL)
+	      my_service->outputs=dupElements(current_element);
+	    else
+	      addToElements(&my_service->outputs,current_element);
+	  }else{
+	    if(my_service->inputs==NULL)
+	      my_service->inputs=dupElements(current_element);
+	    else
+	      addToElements(&my_service->inputs,current_element);
+	  }
+	  freeElements(&current_element);
+	  free(current_element);
+	}
+	plevel=level;
+	current_element=(elements*)malloc(ELEMENTS_SIZE);
+	current_element->name=strdup(token.data.scalar.value);
+	current_element->content=NULL;
+	current_element->metadata=NULL;
+	current_element->format=NULL;
+	current_element->defaults=NULL;
+	current_element->supported=NULL;
+	current_element->next=NULL;
+	
+      }
+
+
+#ifdef DEBUG_YAML
+      printf("scalar %s (%d,%d,%d,%d,%d)\n", token.data.scalar.value,blevel,level,plevel,ilevel,ttype); 
+#endif
+      break;
+    /* Others */
+    default:
+      if(token.type==0){
+	char tmp[1024];
+	sprintf(tmp,"Wrong charater found in %s: \\t",name);
+	setMapInMaps(conf,"lenv","message",tmp);
+	return -1;
+      }
+#ifdef DEBUG_YAML
+      printf("Got token of type %d\n", token.type);
+#endif
+      break;
+    }
+    if(token.type != YAML_STREAM_END_TOKEN )
+      yaml_token_delete(&token);
+  } while(token.type != YAML_STREAM_END_TOKEN);
+  yaml_token_delete(&token);
+
+
+#ifdef DEBUG_YAML
+  fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+  if(current_element!=NULL && current_content!=NULL){
+    if(current_element->defaults==NULL){
+      current_element->defaults=(iotype*)malloc(IOTYPE_SIZE);
+      current_element->defaults->content=NULL;
+      current_element->defaults->next=NULL;
+      addMapToMap(&current_element->defaults->content,current_content);
+    }else{
+      if(current_element->supported==NULL){
+	current_element->supported=(iotype*)malloc(IOTYPE_SIZE);
+	current_element->supported->content=NULL;
+	current_element->supported->next=NULL;
+	addMapToMap(&current_element->supported->content,current_content);
+      }else
+	addMapToIoType(&current_element->supported,current_content);
+    }
+#ifdef DEBUG_YAML
+    dumpMap(current_content);
+    fprintf(stderr,"MSG: %s %d \n",__FILE__,__LINE__);
+#endif
+    freeMap(&current_content);
+    free(current_content);
+    current_content=NULL;
+  }
+  if(current_element!=NULL){
+    if(my_service->outputs==NULL)
+      my_service->outputs=dupElements(current_element);
+    else
+      addToElements(&my_service->outputs,current_element);
+    freeElements(&current_element);
+    free(current_element);
+    current_element=NULL;
+  }
+  /* END new code */
+
+  /* Cleanup */
+  yaml_parser_delete(&parser);
+  fclose(fh);
+
+#ifdef DEBUG_YAML
+  dumpService(my_service);
+#endif
+  *service=my_service;
+
+  return 1;
+}
+#ifdef __cplusplus
+}
+#endif
Index: trunk/zoo-project/zoo-kernel/zcfg2yaml.c
===================================================================
--- trunk/zoo-project/zoo-kernel/zcfg2yaml.c	(revision 465)
+++ trunk/zoo-project/zoo-kernel/zcfg2yaml.c	(revision 465)
@@ -0,0 +1,40 @@
+/**
+ * Author : Gérald FENOY
+ *
+ *  Copyright 2014 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 "service.h"
+#include "service_internal.h"
+
+int main(int argc, char** argv){
+  service* s1=NULL;
+  maps *m;
+  char conf_file[1024];
+  snprintf(conf_file,1024,"%s",argv[1]);
+  s1=(service*)malloc(SERVICE_SIZE);
+  if(s1 == NULL){ 
+    return errorException(m, _("Unable to allocate memory."),"InternalError",NULL);
+  }
+  readServiceFile(m,argv[1],&s1,argv[2]);
+  dumpServiceAsYAML(s1);
+  return 0;
+}
Index: trunk/zoo-project/zoo-kernel/zoo_loader.c
===================================================================
--- trunk/zoo-project/zoo-kernel/zoo_loader.c	(revision 464)
+++ trunk/zoo-project/zoo-kernel/zoo_loader.c	(revision 465)
@@ -117,5 +117,4 @@
     }else{
       char *buffer=new char[cgiContentLength+1];
-      int r=0;
       if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)>=0){
 	buffer[cgiContentLength]=0;
@@ -223,7 +222,6 @@
 	  if(req!=NULL && req->nodeNr==1){
 	    addToMap(tmpMap,"soap","true");
-	    int k=0;
-	    for(k;k < req->nodeNr;k++){
-	      xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
+	    for(int k=0;k < req->nodeNr;k++){
+	      //xmlNsPtr ns=xmlNewNs(req->nodeTab[k],BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",BAD_CAST "xsi");
 	      xmlDocSetRootElement(doc, req->nodeTab[k]);
 	      xmlChar *xmlbuff;
@@ -231,5 +229,4 @@
 	      xmlDocDumpFormatMemoryEnc(doc, &xmlbuff, &buffersize, "utf-8", 1);
 	      addToMap(tmpMap,"xrequest",(char*)xmlbuff);
-	      char *tmp=(char*)xmlbuff;
 	      xmlFree(xmlbuff);
 	    }
Index: trunk/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 464)
+++ trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 465)
@@ -239,5 +239,5 @@
   map* r_inputs=NULL;
 #ifndef WIN32
-  char* pntmp=getcwd(ntmp,1024);
+  getcwd(ntmp,1024);
 #else
   _getcwd(ntmp,1024);
@@ -560,5 +560,5 @@
   char ntmp[1024];
 #ifndef WIN32
-  char *pntmp=getcwd(ntmp,1024);
+  getcwd(ntmp,1024);
 #else
   _getcwd(ntmp,1024);
@@ -760,4 +760,5 @@
     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);
@@ -769,5 +770,17 @@
 	fprintf(stderr,"#################\n%s\n#################\n",tmps1);
 #endif
-	t=getServiceFromFile(tmps1,&s1);
+	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);
@@ -828,5 +841,8 @@
 
       r_inputs=getMap(request_inputs,"Identifier");
-      char *tmps=strtok(r_inputs->value,",");
+      
+      char *saveptr;
+      char *orig=zStrdup(r_inputs->value);
+      char *tmps=strtok_r(orig,",",&saveptr);
       
       char buff[256];
@@ -839,5 +855,5 @@
 	memset(buff1,0,1024);
 #ifdef DEBUG
-	printf("\n#######%s\n########\n",buff1);
+	printf("\n#######%s\n########\n",buff);
 #endif
 	while ((dp = readdir(dirp)) != NULL)
@@ -852,7 +868,23 @@
 	    }
 #ifdef DEBUG
-	    printf("#################\n%s\n#################\n",buff1);
-#endif
-	    t=getServiceFromFile(buff1,&s1);
+	    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);
@@ -861,12 +893,14 @@
 	    freeService(&s1);
 	    free(s1);
+	    s1=NULL;
 	    scount++;
 	  }
 	rewinddir(dirp);
-	tmps=strtok(NULL,",");
+	tmps=strtok_r(NULL,",",&saveptr);
       }
       closedir(dirp);
       fflush(stdout);
       dup2(saved_stdout,fileno(stdout));
+      free(orig);
       printDocument(m,doc,getpid());
       freeMaps(&m);
@@ -917,5 +951,5 @@
   int saved_stdout = dup(fileno(stdout));
   dup2(fileno(stderr),fileno(stdout));
-  t=getServiceFromFile(tmps1,&s1);
+  t=readServiceFile(m,tmps1,&s1,r_inputs->value);
   fflush(stdout);
   dup2(saved_stdout,fileno(stdout));
@@ -2181,6 +2215,6 @@
   addToMap(_tmpMaps->content,"sid",tmpBuff);
   addToMap(_tmpMaps->content,"status","0");
+  addToMap(_tmpMaps->content,"cwd",ntmp);
   addToMap(_tmpMaps->content,"message",_("No message provided"));
-  addToMap(_tmpMaps->content,"cwd",ntmp);
   map* ltmp=getMap(request_inputs,"soap");
   if(ltmp!=NULL)
@@ -2248,5 +2282,5 @@
   freeMaps(&_tmpMaps);
   free(_tmpMaps);
-
+  
 #ifdef DEBUG
   dumpMap(request_inputs);
@@ -2265,5 +2299,4 @@
   }
 #endif
-  int hrstd=-1;
   char *fbkp,*fbkp1;
   FILE *f0,*f1;
Index: trunk/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/CentroidPy.zcfg
===================================================================
--- trunk/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/CentroidPy.zcfg	(revision 464)
+++ trunk/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/CentroidPy.zcfg	(revision 465)
@@ -1,23 +1,16 @@
-[CentroidPy]
- Title = Get the centroid of a polygon. 
- Abstract = Compute the geometry centroid.
- Profile = urn:ogc:wps:1.0.0:centroid
- processVersion = 2
+[Clean]
+ Title = Extract the feature that have a valid geometry field. 
+ Abstract = Extract the feature that have a valid geometry field.
+ processVersion = 1
  storeSupported = true
  statusSupported = true
  serviceProvider = ogr_sp
  serviceType = Python
- <MetaData>
-   title = Demo
- </MetaData>
  <DataInputs>
-  [InputPolygon]
+  [InputData]
    Title = Polygon to get the centroid
    Abstract = The centroid which is not necessarily within the geometry.
    minOccurs = 1
    maxOccurs = 1
-   <MetaData>
-    title = Mon test  
-   </MetaData>   
    <ComplexData>
     <Default>
@@ -37,7 +30,4 @@
    Title = The Centroid
    Abstract = JSON String / GML Entity of the centroid
-   <MetaData>
-    title = Mon test  
-   </MetaData>   
    <ComplexData>
     <Default>
Index: trunk/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ogr_sp.py
===================================================================
--- trunk/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ogr_sp.py	(revision 464)
+++ trunk/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ogr_sp.py	(revision 465)
@@ -52,5 +52,5 @@
         print >> sys.stderr,e
         return []
-
+    
 def buildFeatureFromGeomtry(conf,geom,driverName,ext):
     drv = osgeo.ogr.GetDriverByName( driverName )
@@ -69,8 +69,11 @@
 def createGeometryFromWFS(conf,my_wfs_response):
     try:
-        geom=osgeo.ogr.CreateGeometryFromGML(my_wfs_response.replace('<?xml version="1.0" encoding="utf-8"?>\n',''))
-    except:
+        geom=osgeo.ogr.CreateGeometryFromGML(my_wfs_response.replace('<?xml version="1.0" encoding="utf-8"?>\n','').replace('<?xml version=\'1.0\' encoding="utf-8"?>\n',''))
+    except Exception,e:
+        print >> sys.stderr,"**"
+        print >> sys.stderr,e
         geom=None
     try:
+        print >> sys.stderr,geom is None
         if geom is None:
             if not(conf["lenv"].has_key("cnt")):
@@ -98,18 +101,31 @@
     
 def outputResult(conf,obj,geom):
-    driverName = "GML"
-    extension = [ ".xml" , ".xsd" ]
+    if obj["mimeType"].count("text/xml")>0:
+        driverName = "GML"
+        extension = [ ".xml" , ".xsd" ]
+        format_list = { "2.": 'GML2', "3.1.1": 'GML3', "3.1": 'GML3Deegree', "3.2": 'GML3.2' }
+        opts=['FORMAT=%s,GML3_LONGSRS=YES',format_list["3.2"]]
+        for i in format_list:
+            if obj["mimeType"].count(i)>0:
+                opts=['FORMAT=%s,GML3_LONGSRS=YES',format_list[i]]
     if obj["mimeType"]=="application/json":
         driverName = "GeoJSON"
         extension = [ ".js" ]
+        opts=None
     if obj.keys().count("schema")>0 and \
             obj["schema"]=="http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd":
         driverName = "KML"
         extension = [ ".kml" ]
+        opts=None
     drv = osgeo.ogr.GetDriverByName( driverName )
-    # Create virtual file 
-    ds = drv.CreateDataSource( "/vsimem/store"+conf["lenv"]["sid"]+extension[0] )
+    print >> sys.stderr,drv
+    # Create virtual file
+    ds = drv.CreateDataSource( "/vsimem/store"+conf["lenv"]["sid"]+extension[0],options = opts)
+    print >> sys.stderr,ds
     lyr = ds.CreateLayer( "Result", None, osgeo.ogr.wkbUnknown )
-    i=0
+    print >> sys.stderr,lyr
+    i=0
+    print >> sys.stderr,driverName
+    print >> sys.stderr,extension
     while i < len(geom):
         if i==0 and driverName!="GeoJSON":
@@ -123,5 +139,8 @@
                     oFieldDefn.SetPrecision( poSrcFieldDefn.GetPrecision() )
                     lyr.CreateField( oFieldDefn )
-        lyr.CreateFeature(geom[i])
+        try:
+            lyr.CreateFeature(geom[i])
+        except:
+            pass
         geom[i].Destroy()
         i+=1
@@ -157,4 +176,54 @@
     outputResult(conf,outputs["Result"],rgeometries)
     i=0
+    return zoo.SERVICE_SUCCEEDED
+
+def Clean(conf,inputs,outputs):
+    from shapely.wkb import loads
+    print >> sys.stderr, "Starting service ..."
+    features=extractInputs(conf,inputs["InputData"])
+    i=0
+    rgeometries=[]
+    while i < len(features):
+        tmp=features[i].Clone()
+        resg=features[i].GetGeometryRef()
+        if resg is not None:
+            geom = loads(resg.ExportToWkb())
+            if geom.is_valid:
+                tmp.SetGeometryDirectly(resg)
+                rgeometries+=[tmp]
+                print >> sys.stderr,"valid !"
+            else:
+                print >> sys.stderr,"invalid !"
+                print >> sys.stderr,geom.wkt[0:50]
+        features[i].Destroy()
+        resg.thisown=False 
+        tmp.thisown=False
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    i=0
+    print >> sys.stderr,"Return"
+    return zoo.SERVICE_SUCCEEDED
+
+def TransformService(conf,inputs,outputs):
+    from osgeo import osr
+    geometry=extractInputs(conf,inputs["InputData"])
+    sourceRef = osr.SpatialReference()
+    tmp=inputs["SourceCRS"]["value"].split(":")
+    sourceRef.ImportFromEPSG(int(tmp[len(tmp)-1]))
+    targetRef = osr.SpatialReference()    
+    tmp=inputs["TargetCRS"]["value"].split(":")
+    targetRef.ImportFromEPSG(int(tmp[len(tmp)-1]))
+    transform = osr.CoordinateTransformation(sourceRef, targetRef)
+    i=0
+    rgeometries=[]
+    while i < len(geometry):
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef()
+        resg.Transform(transform)
+        tmp.SetGeometryDirectly(resg.Clone())
+        rgeometries+=[tmp]
+        geometry[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["TransformedData"],rgeometries)
     return zoo.SERVICE_SUCCEEDED
 
