Index: /trunk/zoo-project/HISTORY.txt
===================================================================
--- /trunk/zoo-project/HISTORY.txt	(revision 789)
+++ /trunk/zoo-project/HISTORY.txt	(revision 790)
@@ -1,3 +1,4 @@
 Version 1.6.0-dev
+  * Add nested inputs and outputs support (WPS 2.0.0)
   * Add servicePath special key to specify the service location
   * Add --with-etc-dir option to specify the location of the main.cfg file
Index: /trunk/zoo-project/zoo-kernel/caching.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/caching.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/caching.c	(revision 790)
@@ -148,4 +148,116 @@
 
 /**
+ * Read the downloaded file for a specific input
+ *
+ * @param m the maps containing the settings of the main.cfg file
+ * @param in the input
+ * @param index the input index
+ * @param hInternet the internet connection
+ * @return 0 in case of success, 4 in case of failure
+ */
+int readCurrentInput(maps** m,maps** in,int* index,HINTERNET* hInternet){
+  map* tmp1;
+  char sindex[5];
+  maps* content=*in;
+  map* length=getMap(content->content,"length");
+  int shouldClean=-1;
+  if(length==NULL){
+    length=createMap("length","1");
+    shouldClean=1;
+  }
+  for(int i=0;i<atoi(length->value);i++){
+    char* fcontent;
+    char *mimeType=NULL;
+    int fsize=0;
+    char cname[15];
+    char vname[11];
+    char vname1[11];
+    char sname[9];
+    char mname[15];
+    char icname[14];
+    char xname[16];
+    char oname[12];
+    if(*index>0)
+      sprintf(vname1,"value_%d",*index);
+    else
+      sprintf(vname1,"value");
+    
+    if(i>0){
+      tmp1=getMap(content->content,cname);
+      sprintf(cname,"cache_file_%d",i);
+      sprintf(vname,"value_%d",i);
+      sprintf(sname,"size_%d",i);
+      sprintf(mname,"mimeType_%d",i);
+      sprintf(icname,"isCached_%d",i);
+      sprintf(xname,"Reference_%d",i);
+      sprintf(oname,"Order_%d",i);
+    }else{
+      sprintf(cname,"cache_file");
+      sprintf(vname,"value");
+      sprintf(sname,"size");
+      sprintf(mname,"mimeType");
+      sprintf(icname,"isCached");
+      sprintf(xname,"Reference");
+      sprintf(oname,"Order");
+    }
+    
+    map* tmap=getMap(content->content,oname);
+    sprintf(sindex,"%d",*index+1);
+    if((tmp1=getMap(content->content,xname))!=NULL && tmap!=NULL && strcasecmp(tmap->value,sindex)==0){
+      
+      if(getMap(content->content,icname)==NULL){
+	
+	fcontent=(char*)malloc((hInternet->ihandle[*index].nDataLen+1)*sizeof(char));
+	if(fcontent == NULL){
+	  return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
+	}
+	size_t dwRead;
+	InternetReadFile(hInternet->ihandle[*index], 
+			 (LPVOID)fcontent, 
+			 hInternet->ihandle[*index].nDataLen, 
+			 &dwRead);
+	fcontent[hInternet->ihandle[*index].nDataLen]=0;
+	fsize=hInternet->ihandle[*index].nDataLen;
+	if(hInternet->ihandle[*index].mimeType==NULL)
+	  mimeType=zStrdup("none");
+	else
+	  mimeType=zStrdup(hInternet->ihandle[*index].mimeType);	      
+	
+	map* tmpMap=getMapOrFill(&(*in)->content,vname,"");
+	free(tmpMap->value);
+	tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
+	if(tmpMap->value==NULL){
+	  return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
+	}
+	memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
+	
+	char ltmp1[256];
+	sprintf(ltmp1,"%d",fsize);
+	map* tmp=getMapFromMaps(*m,"main","cacheDir");
+	if(tmp!=NULL){
+	  char* md5str=getMd5(tmp1->value);
+	  char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
+	  sprintf(fname,"%s/%s.zca",tmp->value,md5str);
+	  addToMap((*in)->content,cname,fname);
+	  free(fname);
+	}
+	addToMap((*in)->content,sname,ltmp1);
+	addToMap((*in)->content,mname,mimeType);
+	addToCache(*m,tmp1->value,fcontent,mimeType,fsize, NULL, 0);
+	free(fcontent);
+	free(mimeType);
+	*index++;
+	
+      }
+    }
+  }
+  if(shouldClean>0){
+    freeMap(&length);
+    free(length);
+  }
+  return 0;
+}
+
+/**
  * Effectively run all the HTTP requests in the queue
  *
@@ -157,112 +269,20 @@
  */
 int runHttpRequests(maps** m,maps** inputs,HINTERNET* hInternet){
-  if(hInternet->nb>0){
+  if(hInternet!=NULL && hInternet->nb>0){
     processDownloads(hInternet);
     maps* content=*inputs;
-    map* tmp1;
     int index=0;
-    char sindex[5];
     while(content!=NULL){
-      
-      map* length=getMap(content->content,"length");
-      int shouldClean=-1;
-      if(length==NULL){
-	length=createMap("length","1");
-	shouldClean=1;
-      }
-      for(int i=0;i<atoi(length->value);i++){
-	char* fcontent;
-	char *mimeType=NULL;
-	int fsize=0;
-	char cname[15];
-	char vname[11];
-	char vname1[11];
-	char sname[9];
-	char mname[15];
-	char icname[14];
-	char xname[16];
-	char oname[12];
-	if(index>0)
-	  sprintf(vname1,"value_%d",index);
-	else
-	  sprintf(vname1,"value");
-
-	if(i>0){
-	  tmp1=getMap(content->content,cname);
-	  sprintf(cname,"cache_file_%d",i);
-	  sprintf(vname,"value_%d",i);
-	  sprintf(sname,"size_%d",i);
-	  sprintf(mname,"mimeType_%d",i);
-	  sprintf(icname,"isCached_%d",i);
-	  sprintf(xname,"Reference_%d",i);
-	  sprintf(oname,"Order_%d",i);
-	}else{
-	  sprintf(cname,"cache_file");
-	  sprintf(vname,"value");
-	  sprintf(sname,"size");
-	  sprintf(mname,"mimeType");
-	  sprintf(icname,"isCached");
-	  sprintf(xname,"Reference");
-	  sprintf(oname,"Order");
-	}
-
-	map* tmap=getMap(content->content,oname);
-	sprintf(sindex,"%d",index+1);
-	if((tmp1=getMap(content->content,xname))!=NULL && tmap!=NULL && strcasecmp(tmap->value,sindex)==0){
-
-	  if(getMap(content->content,icname)==NULL){
-	    
-	    fcontent=(char*)malloc((hInternet->ihandle[index].nDataLen+1)*sizeof(char));
-	    if(fcontent == NULL){
-	      return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
-	    }
-	    size_t dwRead;
-	    InternetReadFile(hInternet->ihandle[index], 
-			     (LPVOID)fcontent, 
-			     hInternet->ihandle[index].nDataLen, 
-			     &dwRead);
-	    fcontent[hInternet->ihandle[index].nDataLen]=0;
-	    fsize=hInternet->ihandle[index].nDataLen;
-	    if(hInternet->ihandle[index].mimeType==NULL)
-	      mimeType=strdup("none");
-	    else
-	      mimeType=strdup(hInternet->ihandle[index].mimeType);	      
-	    
-	    map* tmpMap=getMapOrFill(&content->content,vname,"");
-	    free(tmpMap->value);
-	    tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
-	    if(tmpMap->value==NULL){
-	      return errorException(*m, _("Unable to allocate memory"), "InternalError",NULL);
-	    }
-	    memcpy(tmpMap->value,fcontent,(fsize+1)*sizeof(char));
-	    
-	    char ltmp1[256];
-	    sprintf(ltmp1,"%d",fsize);
-	    map* tmp=getMapFromMaps(*m,"main","cacheDir");
-	    if(tmp!=NULL){
-	      char* md5str=getMd5(tmp1->value);
-	      char* fname=(char*)malloc(sizeof(char)*(strlen(tmp->value)+strlen(md5str)+6));
-	      sprintf(fname,"%s/%s.zca",tmp->value,md5str);
-	      addToMap(content->content,cname,fname);
-	      free(fname);
-	    }
-	    addToMap(content->content,sname,ltmp1);
-	    addToMap(content->content,mname,mimeType);
-	    addToCache(*m,tmp1->value,fcontent,mimeType,fsize, NULL, 0);
-	    free(fcontent);
-	    free(mimeType);
-	    index++;
-
-	  }
+      if(content->child!=NULL){
+	maps* cursor=content->child;
+	while(cursor!=NULL){
+	  readCurrentInput(m,&cursor,&index,hInternet);
+	  cursor=cursor->next;
 	}
       }
-      if(shouldClean>0){
-	freeMap(&length);
-	free(length);
-      }
-      
+      else
+	readCurrentInput(m,&content,&index,hInternet);
       content=content->next;
-    }
-    
+    } 
   }
   return 0;
@@ -281,8 +301,6 @@
   maps *oreq=getMaps(*m,"orequests");
   if(oreq==NULL){
-    oreq=(maps*)malloc(MAPS_SIZE);
-    oreq->name=zStrdup("orequests");
+    oreq=createMaps("orequests");
     oreq->content=createMap("value",url);
-    oreq->next=NULL;
     addMapsToMaps(m,oreq);
     freeMaps(&oreq);
@@ -351,5 +369,4 @@
     
   free(tmpMap->value);
-
   tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
   if(tmpMap->value==NULL || fcontent == NULL)
Index: /trunk/zoo-project/zoo-kernel/main_conf_read.y
===================================================================
--- /trunk/zoo-project/zoo-kernel/main_conf_read.y	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/main_conf_read.y	(revision 790)
@@ -111,8 +111,5 @@
      free(current_content);
      current_maps->next=NULL;
-     current_maps->next=(maps*)malloc(MAPS_SIZE);
-     current_maps->next->name=zStrdup($1);
-     current_maps->next->content=NULL;
-     current_maps->next->next=NULL;
+     current_maps->next=createMaps($1);
      current_maps=current_maps->next;
      current_content=current_maps->content;
Index: /trunk/zoo-project/zoo-kernel/request_parser.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/request_parser.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/request_parser.c	(revision 790)
@@ -60,7 +60,14 @@
   map *tmap = getMapType (tmpMaps->content);
   elements *el = getElements (elem, mi->name);
+  elements *cursor = elem;
+  while(cursor!=NULL && el==NULL){
+    if(cursor->child!=NULL)
+      el = getElements (cursor->child, mi->name);
+    cursor=cursor->next;
+  }
   int hasEl = 1;
   if (el == NULL)
     hasEl = -1;
+
   if (tmap == NULL)
     {
@@ -178,4 +185,6 @@
       }
     }
+    if(cursor->child!=NULL)
+      ensureDecodedBase64(&cursor->child);
     cursor=cursor->next;
   }
@@ -255,5 +264,5 @@
 	    if (tmpmaps == NULL)
 	      {
-		tmpmaps = (maps *) malloc (MAPS_SIZE);
+		tmpmaps = createMaps(tmpn);
 		if (tmpmaps == NULL)
 		  {
@@ -263,5 +272,4 @@
 					   "InternalError", NULL);
 		  }
-		tmpmaps->name = zStrdup (tmpn);
 		if (tmpv != NULL)
 		  {
@@ -433,5 +441,5 @@
 		  if (tmp_output == NULL)
 		    {
-		      tmp_output = (maps *) malloc (MAPS_SIZE);
+		      tmp_output = createMaps(tmpc);
 		      if (tmp_output == NULL)
 			{
@@ -442,7 +450,4 @@
 						 "InternalError", NULL);
 			}
-		      tmp_output->name = zStrdup (tmpc);
-		      tmp_output->content = NULL;
-		      tmp_output->next = NULL;
 		    }
 		}
@@ -491,5 +496,5 @@
 int defineMissingIdentifier(maps** main_conf,maps** mymaps){
   if (*mymaps == NULL){
-    *mymaps = (maps *) malloc (MAPS_SIZE);
+    *mymaps = createMaps("missingIndetifier");
     if (*mymaps == NULL){
       return errorException (*main_conf,
@@ -497,7 +502,4 @@
 			     "InternalError", NULL);
     }
-    (*mymaps)->name = zStrdup ("missingIndetifier");
-    (*mymaps)->content = NULL;
-    (*mymaps)->next = NULL;
   }
   return 0;
@@ -529,9 +531,6 @@
 	  // A specific Input node.
 	  if(vid==1){
-	    tmpmaps = (maps *) malloc (MAPS_SIZE);
 	    xmlChar *val = xmlGetProp (cur, BAD_CAST "id");
-	    tmpmaps->name = zStrdup ((char *) val);
-	    tmpmaps->content = NULL;
-	    tmpmaps->next = NULL;
+	    tmpmaps = createMaps((char *) val);
 	  }
 
@@ -552,5 +551,5 @@
 		  if (tmpmaps == NULL && val!=NULL)
 		    {
-		      tmpmaps = (maps *) malloc (MAPS_SIZE);
+		      tmpmaps = createMaps((char*)val);
 		      if (tmpmaps == NULL)
 			{
@@ -560,7 +559,4 @@
 						 "InternalError", NULL);
 			}
-		      tmpmaps->name = zStrdup ((char *) val);
-		      tmpmaps->content = NULL;
-		      tmpmaps->next = NULL;
 		      xmlFree (val);
 		    }
@@ -586,6 +582,26 @@
 		  }
 		}
-	      // InputDataFormChoice (Reference or Data ?) 
-	      if (xmlStrcasecmp (cur2->name, BAD_CAST "Reference") == 0)
+	      // InputDataFormChoice (Reference or Data ?) / 2.0.0 DataInputType / Input 
+	      if (xmlStrcasecmp (cur2->name, BAD_CAST "Input") == 0)
+		{
+		  char *xpathExpr=(char*)malloc(61+strlen(tmpmaps->name));
+		  sprintf(xpathExpr,"/*/*[local-name()='Input' and @id='%s']/*[local-name()='Input']",tmpmaps->name);
+		  xmlXPathObjectPtr tmpsptr = extractFromDoc (doc, xpathExpr);
+		  xmlNodeSet *tmps = tmpsptr->nodesetval;
+		  if(tmps!=NULL){
+		    maps* request_output1=NULL;
+		    if(xmlParseInputs(main_conf,s,&request_output1,doc,tmps,hInternet)<0)
+		      return -1;
+		    if(tmpmaps->child==NULL)
+		      tmpmaps->child=dupMaps(&request_output1);
+		    else
+		      addMapsToMaps(&tmpmaps->child,request_output1);
+		    freeMaps(&request_output1);
+		    free(request_output1);
+		  }
+		  while(cur2->next!=NULL)
+		    cur2=cur2->next;
+		}
+	      else if (xmlStrcasecmp (cur2->name, BAD_CAST "Reference") == 0)
 		{
 		  defineMissingIdentifier(main_conf,&tmpmaps);
@@ -848,5 +864,5 @@
 			cur4=cur4->next;
 		      if(cur4!=NULL){
-			if(cur4->content!=NULL)
+			if(cur4->content!=NULL){
 			  if (tmpmaps->content != NULL)
 			    addToMap (tmpmaps->content, "value",
@@ -855,4 +871,5 @@
 			    tmpmaps->content =
 			      createMap ("value", (char *) cur4->content);
+			}
 			cur4=cur4->next;
 		      }
@@ -955,6 +972,4 @@
 				     && cur5->type != XML_CDATA_SECTION_NODE)
 				cur5 = cur5->next;
-			      fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
-			      fflush(stderr);
 			      if (cur5 != NULL
 				  && cur5->type != XML_CDATA_SECTION_NODE)
@@ -1018,15 +1033,28 @@
 	  {
 	    map* test=getMap(tmpmaps->content,"value");
-	    if(test==NULL)
+	    if(test==NULL && tmpmaps->child==NULL)
 	      addToMap(tmpmaps->content,"value","");
-	    maps *testPresence =
-	      getMaps (*request_output, tmpmaps->name);
+	    maps *testPresence = getMaps (*request_output, tmpmaps->name);
+	    maps *cursor=*request_output;
+	    while(testPresence == NULL && cursor!=NULL){
+	      if(cursor->child!=NULL){
+		testPresence = getMaps (cursor->child, tmpmaps->name);
+	      }
+	      cursor=cursor->next;
+	    }
 	    if (testPresence != NULL)
 	      {
 		elements *elem = getElements (s->inputs, tmpmaps->name);
+		elements *cursor=s->inputs;
+		while(elem == NULL && cursor!=NULL){
+		  if(cursor->child!=NULL){
+		    elem = getElements (cursor->child, tmpmaps->name);
+		  }
+		  cursor=cursor->next;
+		}
 		if (elem != NULL)
 		  {
 		    if (appendMapsToMaps
-			(*main_conf, *request_output, tmpmaps, elem) < 0)
+			(*main_conf, testPresence, tmpmaps, elem) < 0)
 		      {
 			return errorException (*main_conf,
@@ -1066,12 +1094,10 @@
     xmlNodePtr cur = nodes->nodeTab[k];
     if (cur->type == XML_ELEMENT_NODE){
-      maps *tmpmaps = (maps *) malloc (MAPS_SIZE);
+      maps *tmpmaps = NULL;
       xmlChar *val = xmlGetProp (cur, BAD_CAST "id");
       if(val!=NULL)
-	tmpmaps->name = zStrdup ((char*)val);
+	tmpmaps = createMaps((char *)val);
       else
-	tmpmaps->name = zStrdup ("unknownIdentifier");
-      tmpmaps->content = NULL;
-      tmpmaps->next = NULL;
+	tmpmaps = createMaps("unknownIdentifier");
       const char ress[4][13] =
 	{ "mimeType", "encoding", "schema", "transmission" };
@@ -1091,8 +1117,26 @@
 	xmlFree (val);
       }
-      if (*request_output == NULL)
+      if(cur->children!=NULL){
+	xmlNodePtr ccur = cur->children;
+	while (ccur != NULL){
+	  if(ccur->type == XML_ELEMENT_NODE){
+	    char *xpathExpr=(char*)malloc(65+strlen(tmpmaps->name));
+	    sprintf(xpathExpr,"/*/*[local-name()='Output' and @id='%s']/*[local-name()='Output']",tmpmaps->name);
+	    xmlXPathObjectPtr tmpsptr = extractFromDoc (doc, xpathExpr);
+	    xmlNodeSet* cnodes = tmpsptr->nodesetval;
+	    xmlParseOutputs2(main_conf,request_inputs,&tmpmaps->child,doc,cnodes);
+	    break;
+	  }
+	  ccur = ccur->next;
+	}
+      }
+      if (*request_output == NULL){
 	*request_output = dupMaps(&tmpmaps);
-      else
+      }
+      else{
 	addMapsToMaps(request_output,tmpmaps);
+      }
+      freeMaps(&tmpmaps);
+      free(tmpmaps);
     }
   }
@@ -1119,5 +1163,5 @@
 	{
 
-	  maps *tmpmaps = (maps *) malloc (MAPS_SIZE);
+	  maps *tmpmaps = createMaps("unknownIdentifier");
 	  if (tmpmaps == NULL)
 	    {
@@ -1125,7 +1169,4 @@
 				     "InternalError", NULL);
 	    }
-	  tmpmaps->name = zStrdup ("unknownIdentifier");
-	  tmpmaps->content = NULL;
-	  tmpmaps->next = NULL;
 
 	  // Get every attribute from a RawDataOutput node
@@ -1210,5 +1251,5 @@
 	    }
 				
-	    maps *tmpmaps = (maps *) malloc (MAPS_SIZE); // one per Output node
+	    maps *tmpmaps = createMaps("unknownIdentifier"); // one per Output node
 	    if (tmpmaps == NULL) {
 	      return errorException (*main_conf,
@@ -1217,7 +1258,4 @@
 				     "InternalError", NULL);
 	    }
-	    tmpmaps->name = zStrdup ("unknownIdentifier");
-	    tmpmaps->content = NULL;
-	    tmpmaps->next = NULL;
 				
 	    xmlNodePtr elems = cur1->children;
@@ -1513,4 +1551,5 @@
   char *dfv1 =
     addDefaultValues (request_outputs, s->outputs, *main_conf, 1,&errO);
+
   if (strcmp (dfv1, "") != 0 || strcmp (dfv, "") != 0)
     {
Index: /trunk/zoo-project/zoo-kernel/response_print.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/response_print.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/response_print.c	(revision 790)
@@ -1489,7 +1489,26 @@
     
       xmlAddChild(nc2,nc3);
+    }else{
+      if(e->child!=NULL && vid!=0){
+	printFullDescription(in,e->child,type,ns,ns_ows,nc2,vid);
+      }
     }
     
-    xmlAddChild(nc1,nc2);
+    if(e->child!=NULL && vid==0){
+      elements* children=dupElements(e->child);
+      elements* cursor=children;
+      while(cursor!=NULL){
+	char* tmp=strdup(cursor->name);
+	free(cursor->name);
+	cursor->name=(char*)malloc((strlen(cursor->name)+strlen(e->name)+2)*sizeof(char));
+	sprintf(cursor->name,"%s.%s",e->name,tmp);
+	cursor=cursor->next;
+      }
+      printFullDescription(in,children,type,ns,ns_ows,nc2,vid);
+      xmlAddChild(nc1,nc2);
+      freeElements(&children);
+      free(children);
+    }else
+      xmlAddChild(nc1,nc2);
     
     e=e->next;
@@ -1958,176 +1977,189 @@
   }
 
-  /**
-   * IO type Reference or full Data ?
-   */
-  map *tmpMap=getMap(m->content,"Reference");
-  if(tmpMap==NULL){
-    nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
-    if(e!=NULL && e->format!=NULL){
-      if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
-	nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
+  // IO type nested outputs
+  if(m->child!=NULL){
+    maps* curs=m->child;
+    elements* ecurs=getElements(e,(e!=NULL?e->name:m->name));
+    ecurs=ecurs->child;
+    while(curs!=NULL && ecurs!=NULL){
+      map* inRequest=getMap(curs->content,"inRequest");
+      if(inRequest!=NULL && strncasecmp(inRequest->value,"true",4)==0)
+	printIOType(doc,nc1,ns_wps,ns_ows,ns_xlink,ecurs,curs,type,vid);
+      curs=curs->next;
+      ecurs=ecurs->next;
+    }
+  }
+  else{
+    map *tmpMap=getMap(m->content,"Reference");
+    if(tmpMap==NULL){
+      nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
+      if(e!=NULL && e->format!=NULL){
+	if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
+	  nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
+	else
+	  if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
+	    nc3=xmlNewNode(ns_wps, BAD_CAST "ComplexData");
+	  else if(strncasecmp(e->format,"BoundingBoxOutput",strlen(e->format))==0)
+	    nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
+	  else
+	    nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
+      }
+      else {
+	map* tmpV=getMapFromMaps(m,"format","value");
+	if(tmpV!=NULL)
+	  nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
+	else
+	  nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
+      } 
+      tmp=m->content;
+      
+      while(tmp!=NULL){
+	if(strcasecmp(tmp->name,"mimeType")==0 ||
+	   strcasecmp(tmp->name,"encoding")==0 ||
+	   strcasecmp(tmp->name,"schema")==0 ||
+	   strcasecmp(tmp->name,"datatype")==0 ||
+	   strcasecmp(tmp->name,"uom")==0) {
+	  
+	  if(vid==0)
+	    xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
+	  else{
+	    if(strcasecmp(tmp->name,"datatype")==0)
+	      xmlNewProp(nc2,BAD_CAST "mimeType",BAD_CAST "text/plain");
+	    else
+	      if(strcasecmp(tmp->name,"uom")!=0)
+		xmlNewProp(nc2,BAD_CAST tmp->name,BAD_CAST tmp->value);
+	  }
+	}
+	if(vid==0)
+	  xmlAddChild(nc2,nc3);
+	tmp=tmp->next;
+      }
+      if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0) {
+	map* bb=getMap(m->content,"value");
+	if(bb!=NULL) {
+	  map* tmpRes=parseBoundingBox(bb->value);
+	  printBoundingBox(ns_ows,nc3,tmpRes);
+	  freeMap(&tmpRes);
+	  free(tmpRes);
+	}
+      }
+      else {
+	if(e!=NULL)
+	  tmp=getMap(e->defaults->content,"mimeType");
+	else
+	  tmp=NULL;
+	
+	map* tmp1=getMap(m->content,"encoding");
+	map* tmp2=getMap(m->content,"mimeType");
+	map* tmp3=getMap(m->content,"value");
+	int hasValue=1;
+	if(tmp3==NULL){
+	  tmp3=createMap("value","");
+	  hasValue=-1;
+	}
+	
+	if( ( tmp1 != NULL && strncmp(tmp1->value,"base64",6) == 0 )     // if encoding is base64
+	    || 	                                                       // or if 
+	    ( tmp2 != NULL && ( strstr(tmp2->value,"text") == NULL       //  mime type is not text 
+				&&                                       //  nor 
+				strstr(tmp2->value,"xml") == NULL        //  xml
+				&&                                       // nor
+				strstr(tmp2->value,"javascript") == NULL // javascript
+				&&
+				strstr(tmp2->value,"json") == NULL
+				&&
+				strstr(tmp2->value,"ecmascript") == NULL
+				&&
+				// include for backwards compatibility,
+				// although correct mime type is ...kml+xml:
+				strstr(tmp2->value,"google-earth.kml") == NULL							)
+	      )
+	    ) { 	                                                 // then	
+	  map* rs=getMap(m->content,"size");                       // obtain size
+	  bool isSized=true;
+	  if(rs==NULL){
+	    char tmp1[1024];
+	    sprintf(tmp1,"%ld",strlen(tmp3->value));
+	    rs=createMap("size",tmp1);
+	    isSized=false;
+	  }
+	  
+	  xmlAddChild((vid==0?nc3:nc2),xmlNewText(BAD_CAST base64(tmp3->value, atoi(rs->value))));  // base 64 encode in XML
+	  
+	  if(tmp1==NULL || (tmp1!=NULL && strncmp(tmp1->value,"base64",6)!=0)) {
+	    xmlAttrPtr ap = xmlHasProp((vid==0?nc3:nc2), BAD_CAST "encoding");
+	    if (ap != NULL) {
+	      xmlRemoveProp(ap);
+	    }			
+	    xmlNewProp((vid==0?nc3:nc2),BAD_CAST "encoding",BAD_CAST "base64");
+	  }
+	  
+	  if(!isSized){
+	    freeMap(&rs);
+	    free(rs);
+	  }
+	}
+	else if (tmp2!=NULL) {                                 // else (text-based format) 
+	  if(strstr(tmp2->value, "javascript") != NULL ||      //    if javascript put code in CDATA block 
+	     strstr(tmp2->value, "json") != NULL ||            //    (will not be parsed by XML reader) 
+	     strstr(tmp2->value, "ecmascript") != NULL
+	   ) {
+	    xmlAddChild((vid==0?nc3:nc2),xmlNewCDataBlock(doc,BAD_CAST tmp3->value,strlen(tmp3->value)));
+	  }   
+	  else {                                                     // else
+	    if (strstr(tmp2->value, "xml") != NULL ||                 // if XML-based format
+		// include for backwards compatibility,
+	      // although correct mime type is ...kml+xml:		   
+		strstr(tmp2->value, "google-earth.kml") != NULL
+		) { 
+	      
+	      int li=zooXmlAddDoc(tmp3->value);
+	      xmlDocPtr doc = iDocs[li];
+	      xmlNodePtr ir = xmlDocGetRootElement(doc);
+	      xmlAddChild((vid==0?nc3:nc2),ir);
+	    }
+	    else                                                     // else	
+	      xmlAddChild((vid==0?nc3:nc2),xmlNewText(BAD_CAST tmp3->value));    //   add text node
+	  }
+	  xmlAddChild(nc2,nc3);
+	}
+	else {
+	  xmlAddChild((vid==0?nc3:nc2),xmlNewText(BAD_CAST tmp3->value));
+	}
+	
+	if(hasValue<0) {
+	  freeMap(&tmp3);
+	  free(tmp3);
+	}
+      }
+    }
+    else { // Reference
+      tmpMap=getMap(m->content,"Reference");
+      nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
+      /* Special case to avoid failing to validate against the WPS 2.0 schema */
+      if(strcasecmp(type,"Output")==0 && vid==0)
+	xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
       else
-        if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
-	  nc3=xmlNewNode(ns_wps, BAD_CAST "ComplexData");
-	else if(strncasecmp(e->format,"BoundingBoxOutput",strlen(e->format))==0)
-	  nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
-	else
-	  nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
-    }
-    else {
-      map* tmpV=getMapFromMaps(m,"format","value");
-      if(tmpV!=NULL)
-	nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
-      else
-	nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
-    } 
-    tmp=m->content;
-
-    while(tmp!=NULL){
-      if(strcasecmp(tmp->name,"mimeType")==0 ||
-	 strcasecmp(tmp->name,"encoding")==0 ||
-	 strcasecmp(tmp->name,"schema")==0 ||
-	 strcasecmp(tmp->name,"datatype")==0 ||
-	 strcasecmp(tmp->name,"uom")==0) {
-	
-	if(vid==0)
-	  xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
-	else{
+	xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
+      
+      tmp=m->content;
+      while(tmp!=NULL) {
+	if(strcasecmp(tmp->name,"mimeType")==0 ||
+	   strcasecmp(tmp->name,"encoding")==0 ||
+	   strcasecmp(tmp->name,"schema")==0 ||
+	   strcasecmp(tmp->name,"datatype")==0 ||
+	   strcasecmp(tmp->name,"uom")==0){
+	  
 	  if(strcasecmp(tmp->name,"datatype")==0)
-	    xmlNewProp(nc2,BAD_CAST "mimeType",BAD_CAST "text/plain");
+	    xmlNewProp(nc3,BAD_CAST "mimeType",BAD_CAST "text/plain");
 	  else
-	    if(strcasecmp(tmp->name,"uom")!=0)
-	      xmlNewProp(nc2,BAD_CAST tmp->name,BAD_CAST tmp->value);
-	}
-      }
-      if(vid==0)
+	    xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
+	}
+	tmp=tmp->next;
 	xmlAddChild(nc2,nc3);
-      tmp=tmp->next;
-    }
-    if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0) {
-      map* bb=getMap(m->content,"value");
-      if(bb!=NULL) {
-	map* tmpRes=parseBoundingBox(bb->value);
-	printBoundingBox(ns_ows,nc3,tmpRes);
-	freeMap(&tmpRes);
-	free(tmpRes);
-      }
-    }
-    else {
-      if(e!=NULL)
-	tmp=getMap(e->defaults->content,"mimeType");
-      else
-	tmp=NULL;
-	
-      map* tmp1=getMap(m->content,"encoding");
-      map* tmp2=getMap(m->content,"mimeType");
-      map* tmp3=getMap(m->content,"value");
-      int hasValue=1;
-      if(tmp3==NULL){
-	tmp3=createMap("value","");
-	hasValue=-1;
-      }
-
-      if( ( tmp1 != NULL && strncmp(tmp1->value,"base64",6) == 0 )     // if encoding is base64
-	  || 	                                                       // or if 
-	  ( tmp2 != NULL && ( strstr(tmp2->value,"text") == NULL       //  mime type is not text 
-			      &&                                       //  nor 
-			      strstr(tmp2->value,"xml") == NULL        //  xml
-			      &&                                       // nor
-			      strstr(tmp2->value,"javascript") == NULL // javascript
-			      &&
-			      strstr(tmp2->value,"json") == NULL
-			      &&
-			      strstr(tmp2->value,"ecmascript") == NULL
-			      &&
-			      // include for backwards compatibility,
-			      // although correct mime type is ...kml+xml:
-			      strstr(tmp2->value,"google-earth.kml") == NULL							)
-	    )
-	  ) { 	                                                 // then	
-	map* rs=getMap(m->content,"size");                       // obtain size
-	bool isSized=true;
-	if(rs==NULL){
-	  char tmp1[1024];
-	  sprintf(tmp1,"%ld",strlen(tmp3->value));
-	  rs=createMap("size",tmp1);
-	  isSized=false;
-	}
-	 
-	xmlAddChild((vid==0?nc3:nc2),xmlNewText(BAD_CAST base64(tmp3->value, atoi(rs->value))));  // base 64 encode in XML
-		
-	if(tmp1==NULL || (tmp1!=NULL && strncmp(tmp1->value,"base64",6)!=0)) {
-	  xmlAttrPtr ap = xmlHasProp((vid==0?nc3:nc2), BAD_CAST "encoding");
-	  if (ap != NULL) {
-	    xmlRemoveProp(ap);
-	  }			
-	  xmlNewProp((vid==0?nc3:nc2),BAD_CAST "encoding",BAD_CAST "base64");
-	}
-		
-	if(!isSized){
-	  freeMap(&rs);
-	  free(rs);
-	}
-      }
-      else if (tmp2!=NULL) {                                 // else (text-based format) 
-	if(strstr(tmp2->value, "javascript") != NULL ||      //    if javascript put code in CDATA block 
-	   strstr(tmp2->value, "json") != NULL ||            //    (will not be parsed by XML reader) 
-	   strstr(tmp2->value, "ecmascript") != NULL
-	   ) {
-	  xmlAddChild((vid==0?nc3:nc2),xmlNewCDataBlock(doc,BAD_CAST tmp3->value,strlen(tmp3->value)));
-	}   
-	else {                                                     // else
-	  if (strstr(tmp2->value, "xml") != NULL ||                 // if XML-based format
-	      // include for backwards compatibility,
-	      // although correct mime type is ...kml+xml:		   
-	      strstr(tmp2->value, "google-earth.kml") != NULL
-	      ) { 
-			  
-	    int li=zooXmlAddDoc(tmp3->value);
-	    xmlDocPtr doc = iDocs[li];
-	    xmlNodePtr ir = xmlDocGetRootElement(doc);
-	    xmlAddChild((vid==0?nc3:nc2),ir);
-	  }
-	  else                                                     // else	
-	    xmlAddChild((vid==0?nc3:nc2),xmlNewText(BAD_CAST tmp3->value));    //   add text node
-	}
-	xmlAddChild(nc2,nc3);
-      }
-      else {
-	xmlAddChild((vid==0?nc3:nc2),xmlNewText(BAD_CAST tmp3->value));
-      }
-	  
-      if(hasValue<0) {
-	freeMap(&tmp3);
-	free(tmp3);
-      }
-    }
-  }
-  else { // Reference
-    tmpMap=getMap(m->content,"Reference");
-    nc3=nc2=xmlNewNode(ns_wps, BAD_CAST "Reference");
-    if(strcasecmp(type,"Output")==0)
-      xmlNewProp(nc3,BAD_CAST "href",BAD_CAST tmpMap->value);
-    else
-      xmlNewNsProp(nc3,ns_xlink,BAD_CAST "href",BAD_CAST tmpMap->value);
-    
-    tmp=m->content;
-    while(tmp!=NULL) {
-      if(strcasecmp(tmp->name,"mimeType")==0 ||
-	 strcasecmp(tmp->name,"encoding")==0 ||
-	 strcasecmp(tmp->name,"schema")==0 ||
-	 strcasecmp(tmp->name,"datatype")==0 ||
-	 strcasecmp(tmp->name,"uom")==0){
-
-	if(strcasecmp(tmp->name,"datatype")==0)
-	  xmlNewProp(nc3,BAD_CAST "mimeType",BAD_CAST "text/plain");
-	else
-	  xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
-      }
-      tmp=tmp->next;
-      xmlAddChild(nc2,nc3);
-    }
-  }
-  xmlAddChild(nc1,nc2);
+      }
+    }
+    xmlAddChild(nc1,nc2);
+  }
   xmlAddChild(nc,nc1);
 }
@@ -2394,5 +2426,4 @@
       sprintf(tmpMsg,_("Unable to create the file \"%s\" for storing the session maps."),session_file_path);
       errorException(m,tmpMsg,"InternalError",NULL);
-
       return;
     }
@@ -2437,7 +2468,13 @@
 #endif
     maps* tmpI=request_outputs;
+    maps* stmpI=NULL;
     map* usid=getMapFromMaps(m,"lenv","usid");
     int itn=0;
+  NESTED0:
     while(tmpI!=NULL){
+      if(tmpI->child!=NULL){
+	stmpI=tmpI;
+	tmpI=tmpI->child;
+      }
 #ifdef USE_MS
       map* testMap=getMap(tmpI->content,"useMapserver");	
@@ -2462,4 +2499,7 @@
 	{
 	  elements* in=getElements(s->outputs,tmpI->name);
+	  if(in==NULL && s->outputs->child!=NULL){
+	    in=getElements(s->outputs->child,tmpI->name);
+	  }
 	  char *format=NULL;
 	  if(in!=NULL && in->format!=NULL){
@@ -2545,4 +2585,10 @@
 #endif
       tmpI=tmpI->next;
+    }
+    if(stmpI!=NULL){
+      tmpI=stmpI->next;
+      stmpI=NULL;
+      if(tmpI!=NULL)
+	goto NESTED0;
     }
 #ifdef DEBUG
Index: /trunk/zoo-project/zoo-kernel/server_internal.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/server_internal.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/server_internal.c	(revision 790)
@@ -583,7 +583,11 @@
   map *res=*err;
   elements* tmpInputs=in;
+  elements* tmpInputss=NULL;
   maps* out1=*out;
+  maps* out1s=NULL;
   char *result=NULL;
   int nb=0;
+  int inb=0;
+ loopOnInputs:
   if(type==1){
     while(out1!=NULL){
@@ -597,20 +601,19 @@
 	result=out1->name;
       }
+      inb++;
       out1=out1->next;
     }
     if(res!=NULL){
+      fflush(stderr);
       *err=res;
       return result;
     }
-    out1=*out;
+    if(out1==NULL && inb>=1)
+      out1=*out;
   }
   while(tmpInputs!=NULL){
     maps *tmpMaps=getMaps(out1,tmpInputs->name);
     if(tmpMaps==NULL){
-      maps* tmpMaps2=(maps*)malloc(MAPS_SIZE);
-      tmpMaps2->name=strdup(tmpInputs->name);
-      tmpMaps2->content=NULL;
-      tmpMaps2->next=NULL;
-      
+      maps* tmpMaps2=createMaps(tmpInputs->name);
       if(type==0){
 	map* tmpMapMinO=getMap(tmpInputs->content,"minOccurs");
@@ -651,5 +654,5 @@
 	}
       }
-
+      
       if(res==NULL){
 	iotype* tmpIoType=tmpInputs->defaults;
@@ -685,55 +688,62 @@
     }
     else{
-      iotype* tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
-					     tmpMaps->content);
-      if(type==0) {
-	/**
-	 * In case of an Input maps, then add the minOccurs and maxOccurs to the
-	 * content map.
-	 */
-	map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
-	if(tmpMap1!=NULL){
-	  if(tmpMaps->content==NULL)
-	    tmpMaps->content=createMap("minOccurs",tmpMap1->value);
-	  else
-	    addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
-	}
-	map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
-	if(tmpMaxO!=NULL){
-	  if(tmpMaps->content==NULL)
-	    tmpMaps->content=createMap("maxOccurs",tmpMaxO->value);
-	  else
-	    addToMap(tmpMaps->content,"maxOccurs",tmpMaxO->value);
-	}
-	map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
-	if(tmpMaxMB!=NULL){
-	  if(tmpMaps->content==NULL)
-	    tmpMaps->content=createMap("maximumMegabytes",tmpMaxMB->value);
-	  else
-	    addToMap(tmpMaps->content,"maximumMegabytes",tmpMaxMB->value);
-	}
-	/**
-	 * Parsing BoundingBoxData, fill the following map and then add it to
-	 * the content map of the Input maps: 
-	 * lowerCorner, upperCorner, srs and dimensions
-	 * cf. parseBoundingBox
-	 */
-	if(tmpInputs->format!=NULL && strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
-	  maps* tmpI=getMaps(*out,tmpInputs->name);
-	  if(tmpI!=NULL){
-	    map* tmpV=getMap(tmpI->content,"value");
-	    if(tmpV!=NULL){
-	      char *tmpVS=strdup(tmpV->value);
-	      map* tmp=parseBoundingBox(tmpVS);
-	      free(tmpVS);
-	      map* tmpC=tmp;
-	      while(tmpC!=NULL){
-		addToMap(tmpMaps->content,tmpC->name,tmpC->value);
-		tmpC=tmpC->next;
+      iotype* tmpIoType=NULL;
+      if(tmpMaps->content!=NULL){
+	tmpIoType=getIoTypeFromElement(tmpInputs,tmpInputs->name,
+				       tmpMaps->content);
+	if(type==0) {
+	  /**
+	   * In case of an Input maps, then add the minOccurs and maxOccurs to the
+	   * content map.
+	   */
+	  map* tmpMap1=getMap(tmpInputs->content,"minOccurs");
+	  if(tmpMap1!=NULL){
+	    if(tmpMaps->content==NULL)
+	      tmpMaps->content=createMap("minOccurs",tmpMap1->value);
+	    else
+	      addToMap(tmpMaps->content,"minOccurs",tmpMap1->value);
+	  }
+	  map* tmpMaxO=getMap(tmpInputs->content,"maxOccurs");
+	  if(tmpMaxO!=NULL){
+	    if(tmpMaps->content==NULL)
+	      tmpMaps->content=createMap("maxOccurs",tmpMaxO->value);
+	    else
+	      addToMap(tmpMaps->content,"maxOccurs",tmpMaxO->value);
+	  }
+	  map* tmpMaxMB=getMap(tmpInputs->content,"maximumMegabytes");
+	  if(tmpMaxMB!=NULL){
+	    if(tmpMaps->content==NULL)
+	      tmpMaps->content=createMap("maximumMegabytes",tmpMaxMB->value);
+	    else
+	      addToMap(tmpMaps->content,"maximumMegabytes",tmpMaxMB->value);
+	  }
+	  /**
+	   * Parsing BoundingBoxData, fill the following map and then add it to
+	   * the content map of the Input maps: 
+	   * lowerCorner, upperCorner, srs and dimensions
+	   * cf. parseBoundingBox
+	   */
+	  if(tmpInputs->format!=NULL && strcasecmp(tmpInputs->format,"BoundingBoxData")==0){
+	    maps* tmpI=getMaps(*out,tmpInputs->name);
+	    if(tmpI!=NULL){
+	      map* tmpV=getMap(tmpI->content,"value");
+	      if(tmpV!=NULL){
+		char *tmpVS=strdup(tmpV->value);
+		map* tmp=parseBoundingBox(tmpVS);
+		free(tmpVS);
+		map* tmpC=tmp;
+		while(tmpC!=NULL){
+		  addToMap(tmpMaps->content,tmpC->name,tmpC->value);
+		  tmpC=tmpC->next;
+		}
+		freeMap(&tmp);
+		free(tmp);
 	      }
-	      freeMap(&tmp);
-	      free(tmp);
 	    }
 	  }
+	}
+      }else{
+	if(tmpInputs!=NULL){
+	  tmpIoType=tmpInputs->defaults;
 	}
       }
@@ -807,7 +817,29 @@
       else
 	addToMap(tmpMaps->content,"inRequest","true");
-
-    }
-    tmpInputs=tmpInputs->next;
+      elements* tmpElements=getElements(in,tmpMaps->name);
+      if(tmpMaps->child!=NULL and tmpElements!=NULL and tmpElements->child!=NULL){
+	char *res=addDefaultValues(&tmpMaps->child,tmpElements->child,m,type,err);
+	if(strlen(res)>0){
+	  fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+	  return res;
+	}
+      }
+    }
+    if(tmpInputs->child!=NULL){
+      tmpInputss=tmpInputs->next;
+      tmpInputs=tmpInputs->child;
+      if(tmpMaps!=NULL){
+	out1=tmpMaps->child;
+	out1s=tmpMaps;
+      }
+    }else
+      tmpInputs=tmpInputs->next;
+  }
+  if(tmpInputss!=NULL){
+    out1=out1s;
+    tmpInputs=tmpInputss;
+    tmpInputss=NULL;
+    out1s=NULL;
+    goto loopOnInputs;
   }
   if(res!=NULL){
@@ -879,4 +911,5 @@
       maps *res = (maps *) malloc (MAPS_SIZE);
       conf_read (fbkpid, res);
+      res->child=NULL;
       map* status=getMapFromMaps(res,"status","status");
       addToMap(statusInfo,"Status",status->value);
Index: /trunk/zoo-project/zoo-kernel/service.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service.c	(revision 790)
@@ -74,8 +74,8 @@
 
 /**
- * Dump a map to a file
+ * Dump a map to a file 
  *
  * @param t the map to dump to file
- * @param file the file to store the map
+ * @param file the file pointer to store the map
  */
 void dumpMapToFile(map* t,FILE* file){
@@ -96,5 +96,8 @@
   while(tmp!=NULL){
     fprintf(stderr,"MAP => [%s] \n",tmp->name);
+    fprintf(stderr," * CONTENT [%s] \n",tmp->name);
     dumpMap(tmp->content);
+    fprintf(stderr," * CHILD [%s] \n",tmp->name);
+    dumpMaps(tmp->child);
     tmp=tmp->next;
   }
@@ -105,13 +108,15 @@
  *
  * @param m the map to dump
- * @param file_path the full path to the file name to store the map
- */
-void dumpMapsToFile(maps* m,char* file_path,int limit){
-  FILE* file=fopen(file_path,"w+");
+ * @param file the the file pointer to store the map
+ */
+void _dumpMapsToFile(maps* m,FILE* file,int limit){
   maps* tmp=m;
   int cnt=0;
   while(tmp!=NULL){
     fprintf(file,"[%s]\n",tmp->name);
-    dumpMapToFile(tmp->content,file);
+    if(tmp->child!=NULL){
+      _dumpMapsToFile(tmp->child,file,limit);
+    }else
+      dumpMapToFile(tmp->content,file);
     fflush(file);
     tmp=tmp->next;
@@ -121,4 +126,17 @@
   }
   fflush(file);
+}
+
+/**
+ * Dump a maps to a file, see _dumpMapsToFile().
+ *
+ * @param m the map to dump
+ * @param file_path the full path to the file name to store the map
+ * @param limit the number limiting the maps to be dumped
+ */
+void dumpMapsToFile(maps* m,char* file_path,int limit){
+  FILE* file=fopen(file_path,"w+");
+  _dumpMapsToFile(m,file,limit);
+  fflush(file);
   fclose(file);
 }
@@ -129,5 +147,5 @@
  * @param name the key to add to the map
  * @param value the corresponding value to add to the map
- * @return the allocated map
+ * @return a pointer to the allocated map 
  */
 map* createMap(const char* name,const char* value){
@@ -136,4 +154,19 @@
   tmp->value=zStrdup(value);
   tmp->next=NULL;
+  return tmp;
+}
+
+/**
+ * Create a new maps with the given name
+ *
+ * @param name of the maps
+ * @return the allocated map
+ */
+maps* createMaps(const char* name){
+  maps* tmp = (maps *) malloc (MAPS_SIZE);
+  tmp->name = zStrdup (name);
+  tmp->content = NULL;
+  tmp->child = NULL;
+  tmp->next = NULL;
   return tmp;
 }
@@ -283,4 +316,8 @@
       freeMap(&_cursor->content);
       free(_cursor->content);
+    }
+    if(_cursor->child!=NULL){
+      freeMaps(&_cursor->child);
+      free(_cursor->child);
     }
     if(_cursor->next!=NULL){
@@ -362,4 +399,8 @@
     if(tmp->format!=NULL)
       free(tmp->format);
+    if(tmp->child!=NULL){
+      freeElements(&tmp->child);
+      free(tmp->child);
+    }
     freeIOType(&tmp->defaults);
     if(tmp->defaults!=NULL)
@@ -593,19 +634,20 @@
 iotype* getIoTypeFromElement(elements* e,char *name, map* values){
   elements* cursor=e;
-  while(cursor!=NULL){
-    if(strcasecmp(cursor->name,name)==0){
-      if(contains(cursor->defaults->content,values)==true)
-	return cursor->defaults;
-      else{
-	iotype* tmp=cursor->supported;
-	while(tmp!=NULL){
-	  if(contains(tmp->content,values)==true)
-	    return tmp;	    
-	  tmp=tmp->next;
+  if(values!=NULL)
+    while(cursor!=NULL){
+      if(strcasecmp(cursor->name,name)==0 && (cursor->defaults!=NULL || cursor->supported!=NULL)){
+	if(contains(cursor->defaults->content,values)==true)
+	  return cursor->defaults;
+	else{
+	  iotype* tmp=cursor->supported;
+	  while(tmp!=NULL){
+	    if(contains(tmp->content,values)==true)
+	      return tmp;	    
+	    tmp=tmp->next;
+	  }
 	}
       }
-    }
-    cursor=cursor->next;
-  }
+      cursor=cursor->next;
+    }
   return NULL;
 }
@@ -677,12 +719,13 @@
   maps* res=NULL;
   if(_cursor!=NULL){
-    res=(maps*)malloc(MAPS_SIZE);
-    res->name=zStrdup(_cursor->name);
-    res->content=NULL;
-    res->next=NULL;
+    res=createMaps(_cursor->name);
     map* mc=_cursor->content;
     if(mc!=NULL){
       addMapToMap(&res->content,mc);
       loadMapBinaries(&res->content,mc);
+    }
+    maps* mcs=_cursor->child;
+    if(mcs!=NULL){
+      res->child=dupMaps(&mcs);
     }
     res->next=dupMaps(&_cursor->next);
@@ -709,8 +752,18 @@
 	_cursor=_cursor->next;
       maps* tmp1=getMaps(*mo,tmp->name);
-      if(tmp1==NULL)
+      if(tmp1==NULL){
 	_cursor->next=dupMaps(&tmp);
-      else
+	if(tmp->child!=NULL)
+	  _cursor->next->child=dupMaps(&tmp->child);
+	else
+	  _cursor->next->child=NULL;
+      }
+      else{
 	addMapToMap(&tmp1->content,tmp->content);
+	if(tmp->child!=NULL)
+	  tmp1->child=dupMaps(&tmp->child);
+	else
+	  tmp1->child=NULL;
+      }
       _cursor=*mo;
     }
@@ -872,8 +925,6 @@
       _ztmpm->value=zStrdup(value);
     }else{
-      maps *tmp=(maps*)malloc(MAPS_SIZE);
-      tmp->name=zStrdup(key);
+      maps *tmp=createMaps(key);
       tmp->content=createMap(subkey,value);
-      tmp->next=NULL;
       addMapsToMaps(&_tmpm,tmp);
       freeMaps(&tmp);
@@ -881,12 +932,65 @@
     }
   }else{
-    maps *tmp=(maps*)malloc(MAPS_SIZE);
-    tmp->name=zStrdup(key);
+    maps *tmp=createMaps(key);
     tmp->content=createMap(subkey,value);
-    tmp->next=NULL;
     addMapsToMaps(&m,tmp);
     freeMaps(&tmp);
     free(tmp);
   }
+}
+
+/**
+ * Create an empty elements
+ *
+ * @return a pointer to the allocated elements
+ */
+elements* createEmptyElements(){
+  elements* res=(elements*)malloc(ELEMENTS_SIZE);
+  res->name=NULL;
+  res->content=NULL;
+  res->metadata=NULL;
+  res->format=NULL;
+  res->defaults=NULL;
+  res->supported=NULL;
+  res->child=NULL;
+  res->next=NULL;
+  return res;
+}
+
+/**
+ * Create a named elements
+ *
+ * @param name the elements name
+ * @return a pointer to the allocated elements
+ */
+elements* createElements(char* name){
+  elements* res=(elements*)malloc(ELEMENTS_SIZE);
+  res->name=zStrdup(name);
+  res->content=NULL;
+  res->metadata=NULL;
+  res->format=NULL;
+  res->defaults=NULL;
+  res->supported=NULL;
+  res->child=NULL;
+  res->next=NULL;
+  return res;
+}
+
+/**
+ * Set the name of an elements
+ *
+ * @param name the elements name
+ * @return a pointer to the allocated elements
+ */
+void setElementsName(elements** elem,char* name){
+  elements* res=*elem;
+  res->name=zStrdup(name);
+  res->content=NULL;
+  res->metadata=NULL;
+  res->format=NULL;
+  res->defaults=NULL;
+  res->supported=NULL;
+  res->child=NULL;
+  res->next=NULL;
 }
 
@@ -921,4 +1025,8 @@
       ioc++;
     }
+    if(tmp->child!=NULL){
+      fprintf(stderr," > CHILD \n");
+      dumpElements(tmp->child);
+    }
     fprintf(stderr,"------------------\n");
     tmp=tmp->next;
@@ -931,14 +1039,14 @@
  * @param e the elements to dump
  */
-void dumpElementsAsYAML(elements* e){
+void dumpElementsAsYAML(elements* e,int level){
   elements* tmp=e;
   int i;
   while(tmp!=NULL){
-    for(i=0;i<2;i++)
+    for(i=0;i<2+(4*level);i++)
       fprintf(stderr," ");
     fprintf(stderr,"%s:\n",tmp->name);
     map* mcurs=tmp->content;
     while(mcurs!=NULL){
-      for(i=0;i<4;i++)
+      for(i=0;i<4+(4*level);i++)
 	fprintf(stderr," ");
       _dumpMap(mcurs);
@@ -947,9 +1055,9 @@
     mcurs=tmp->metadata;
     if(mcurs!=NULL){
-      for(i=0;i<4;i++)
+      for(i=0;i<4+(4*level);i++)
 	fprintf(stderr," ");
       fprintf(stderr,"MetaData:\n");
       while(mcurs!=NULL){
-	for(i=0;i<6;i++)
+	for(i=0;i<6+(4*level);i++)
 	  fprintf(stderr," ");
 	_dumpMap(mcurs);
@@ -957,16 +1065,22 @@
       }
     }
-    for(i=0;i<4;i++)
+    for(i=0;i<4+(4*level);i++)
       fprintf(stderr," ");
-    fprintf(stderr,"%s:\n",tmp->format);
+    if(tmp->format!=NULL)
+      fprintf(stderr,"%s:\n",tmp->format);
+    else{
+      fprintf(stderr,"Child:\n");
+      if(tmp->child!=NULL)
+	dumpElementsAsYAML(tmp->child,level+1);
+    }
     iotype* tmpio=tmp->defaults;
     int ioc=0;
     while(tmpio!=NULL){
-      for(i=0;i<6;i++)
+      for(i=0;i<6+(4*level);i++)
 	fprintf(stderr," ");
       fprintf(stderr,"default:\n");
       mcurs=tmpio->content;
       while(mcurs!=NULL){
-	for(i=0;i<8;i++)
+	for(i=0;i<8+(4*level);i++)
 	  fprintf(stderr," ");
 	if(strcasecmp(mcurs->name,"range")==0){
@@ -982,10 +1096,10 @@
     ioc=0;
     while(tmpio!=NULL){
-      for(i=0;i<6;i++)
+      for(i=0;i<6+(4*level);i++)
 	fprintf(stderr," ");
       fprintf(stderr,"supported:\n");
       mcurs=tmpio->content;
       while(mcurs!=NULL){
-	for(i=0;i<8;i++)
+	for(i=0;i<8+(4*level);i++)
 	  fprintf(stderr," ");
 	if(strcasecmp(mcurs->name,"range")==0){
@@ -1055,4 +1169,8 @@
     else
       tmp->supported=NULL;
+    if(cursor->child!=NULL)
+      tmp->child=dupElements(cursor->child);
+    else
+      tmp->child=NULL;
     tmp->next=dupElements(cursor->next);
   }
@@ -1075,5 +1193,19 @@
   }
 }
-  
+
+/**
+ * Set the name of a service
+ *
+ * @param name the service name
+ */
+void setServiceName(service** serv,char* name){
+  service* res=*serv;
+  res->name=zStrdup(name);
+  res->content=NULL;
+  res->metadata=NULL;
+  res->inputs=NULL;
+  res->outputs=NULL;
+}
+
 /**
  * Dump a service on stderr
@@ -1126,9 +1258,9 @@
   if(s->inputs!=NULL){
     fprintf(stderr,"\ninputs:\n");
-    dumpElementsAsYAML(s->inputs);
+    dumpElementsAsYAML(s->inputs,0);
   }
   if(s->outputs!=NULL){
     fprintf(stderr,"\noutputs:\n");
-    dumpElementsAsYAML(s->outputs);
+    dumpElementsAsYAML(s->outputs,0);
   }
 }
Index: /trunk/zoo-project/zoo-kernel/service.h
===================================================================
--- /trunk/zoo-project/zoo-kernel/service.h	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service.h	(revision 790)
@@ -154,5 +154,5 @@
  */
 //#define MAPS_SIZE (2*sizeof(char*))+sizeof(map*)+MAP_SIZE
-#define MAPS_SIZE sizeof(char*)+sizeof(map*)+sizeof(maps*)
+#define MAPS_SIZE sizeof(char*)+sizeof(map*)+(2*sizeof(maps*))
 /**
  * The memory size to create a service
@@ -205,4 +205,5 @@
     char* name; //!< the maps name
     struct map* content; //!< the content map
+    struct maps* child; //!< the child maps
     struct maps* next; //!< the pointer to the next maps if any or NULL
   } maps;
@@ -268,4 +269,5 @@
   ZOO_DLL_EXPORT void dumpMapsToFile(maps*,char*,int);
   ZOO_DLL_EXPORT map* createMap(const char*,const char*);
+  ZOO_DLL_EXPORT maps* createMaps(const char*);
   ZOO_DLL_EXPORT int count(map*);
   ZOO_DLL_EXPORT bool hasKey(map*,const char*);
@@ -278,8 +280,12 @@
   
 
+  ZOO_DLL_EXPORT elements* createEmptyElements();
+  ZOO_DLL_EXPORT elements* createElements(char*);
+  ZOO_DLL_EXPORT void setElementsName(elements**,char*);
   ZOO_DLL_EXPORT bool hasElement(elements*,const char*);
   ZOO_DLL_EXPORT elements* getElements(elements*,char*);
   ZOO_DLL_EXPORT void freeIOType(iotype**);
   ZOO_DLL_EXPORT void freeElements(elements**);
+  ZOO_DLL_EXPORT void setServiceName(service**,char*);
   ZOO_DLL_EXPORT void freeService(service**);
   ZOO_DLL_EXPORT void addToMap(map*,const char*,const char*);
@@ -301,5 +307,5 @@
   ZOO_DLL_EXPORT void setMapInMaps(maps*,const char*,const char*,const char*);
   ZOO_DLL_EXPORT void dumpElements(elements*);
-  ZOO_DLL_EXPORT void dumpElementsAsYAML(elements*);
+  ZOO_DLL_EXPORT void dumpElementsAsYAML(elements*,int);
   ZOO_DLL_EXPORT elements* dupElements(elements*);
   ZOO_DLL_EXPORT void addToElements(elements**,elements*);
Index: /trunk/zoo-project/zoo-kernel/service_conf.y
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_conf.y	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_conf.y	(revision 790)
@@ -34,4 +34,5 @@
 static bool wait_mainmetadata=false;
 static bool wait_metadata=false;
+static bool wait_nested=false;
 static bool wait_inputs=false;
 static bool wait_defaults=false;
@@ -47,4 +48,5 @@
 static int previous_data=0;
 static int current_data=0;
+static int nested_level=0;
 // namespace
 using namespace std;
@@ -145,5 +147,5 @@
   dumpMap(current_content);
 #endif
-  if(my_service->content==NULL){
+  if(my_service->content==NULL && current_content!=NULL){
 #ifdef DEBUG_SERVICE_CONF
     fprintf(stderr,"NO CONTENT\n");
@@ -156,4 +158,15 @@
     wait_maincontent=false;
   }
+  if(strncasecmp($2,"EndNested",9)==0){
+#ifdef DEBUG_SERVICE_CONF
+      fprintf(stderr,"(ENDNESTED - %d) \n",__LINE__);
+      fflush(stderr);
+#endif
+      nested_level-=1;
+      if(nested_level==0){
+	wait_nested=false;
+      }
+  }
+
   if(strncasecmp($2,"DataInputs",10)==0){
     if(current_element==NULL){
@@ -167,13 +180,5 @@
 #endif
       current_element=NULL;
-      current_element=(elements*)malloc(ELEMENTS_SIZE);
-      current_element->name=NULL;
-      current_element->content=NULL;
-      current_element->metadata=NULL;
-      current_element->format=NULL;
-      current_element->defaults=NULL;
-      current_element->supported=NULL;
-      current_element->child=NULL;
-      current_element->next=NULL;
+      current_element=createEmptyElements();
     }
     wait_inputs=true;
@@ -217,13 +222,5 @@
 	fflush(stderr);
 #endif
-	current_element=(elements*)malloc(ELEMENTS_SIZE);
-	current_element->name=NULL;
-	current_element->content=NULL;
-	current_element->metadata=NULL;
-	current_element->format=NULL;
-	current_element->defaults=NULL;
-	current_element->supported=NULL;
-	current_element->child=NULL;
-	current_element->next=NULL;
+	current_element=createEmptyElements();
       }
       wait_outputs=1;
@@ -269,4 +266,5 @@
 	  current_element->defaults=NULL;
 	  current_element->supported=NULL;
+	  current_element->child=NULL;
 	  current_content=NULL;
 	}
@@ -285,6 +283,6 @@
 	    }
 #ifdef DEBUG_SERVICE_CONF
-  printf("* Identifiant : %s\n",$2);
-  fflush(stdout);
+  fprintf(stderr,"* Identifiant : %s\n",$2);
+  fflush(stderr);
 #endif
 }
@@ -340,5 +338,50 @@
      current_content=NULL;
      current_element->supported=NULL;
+     current_element->child=NULL;
      current_element->next=NULL;
+   }
+   if(strncasecmp($2,"EndNested",9)==0){
+     if(current_data==1){
+       elements* cursor=my_service->inputs;
+       while(cursor->next!=NULL)
+	 cursor=cursor->next;
+       if(nested_level>1){
+	 for(int j=0;j<nested_level-1;j++){
+	   cursor=cursor->child;
+	   while(cursor->next!=NULL)
+	     cursor=cursor->next;
+	 }
+       }
+       if(cursor->child==NULL){
+	 cursor->child=dupElements(current_element);
+       }else{
+	 addToElements(&cursor->child,current_element);
+       }
+     }else{
+       if(current_element->name!=NULL){
+	 elements* cursor=my_service->outputs;
+	 while(cursor->next!=NULL)
+	   cursor=cursor->next;
+	 if(nested_level>1){
+	   for(int j=0;j<nested_level-1;j++){
+	     cursor=cursor->child;
+	     while(cursor->next!=NULL)
+	       cursor=cursor->next;
+	   }
+	 }
+	 if(cursor->child==NULL){
+	   cursor->child=dupElements(current_element);
+	 }else
+	   addToElements(&cursor->child,current_element);
+       }
+     }
+     freeElements(&current_element);
+     free(current_element);
+     current_element=NULL;
+     current_element=createEmptyElements();
+     nested_level-=1;
+     if(nested_level==0){
+       wait_nested=false;       
+     }
    }
  }
@@ -395,4 +438,5 @@
 	current_element->defaults=NULL;
 	current_element->supported=NULL;
+	current_element->child=NULL;
       }else{
 	if(wait_mainmetadata){
@@ -428,4 +472,5 @@
     current_content=NULL;
     current_element->supported=NULL;
+    current_element->child=NULL;
     current_element->next=NULL;
   }
@@ -443,4 +488,5 @@
       }else{
 	current_element->supported=NULL;
+	current_element->child=NULL;
 	current_element->next=NULL;
       }
@@ -553,20 +599,13 @@
   fprintf(stderr,"processid (%s %d) %s\n",__FILE__,__LINE__,$1);
 #endif
-//  if(data==-1){
-//    data=1;
   if(::data==-1){ // knut: add namespace to avoid ambiguous symbol
     ::data=1;	
     if($1!=NULL){
       char *cen=zStrdup($1);
-      my_service->name=(char*)malloc((strlen(cen)-1)*sizeof(char*));
       cen[strlen(cen)-1]=0;
       cen+=1;
-      sprintf(my_service->name,"%s",cen);
+      setServiceName(&my_service,cen);
       cen-=1;
       free(cen);
-      my_service->content=NULL;
-      my_service->metadata=NULL;
-      my_service->inputs=NULL;
-      my_service->outputs=NULL;
     }
   } else {
@@ -579,5 +618,42 @@
 	}
 	else{
-	  addToElements(&my_service->inputs,current_element);
+	  if(wait_nested){
+	    elements* cursor=my_service->inputs;
+	    while(cursor->next!=NULL)
+	      cursor=cursor->next;
+	    if(nested_level>1){
+	      for(int j=0;j<nested_level-1;j++){
+		cursor=cursor->child;
+		while(cursor->next!=NULL)
+		  cursor=cursor->next;
+	      }
+	    }
+	    if(cursor->child==NULL){
+	      cursor->child=dupElements(current_element);
+	    }else{
+	      addToElements(&cursor->child,current_element);
+	    }
+	  }else
+	    addToElements(&my_service->inputs,current_element);
+	}
+	if(current_element->format==NULL){
+	  wait_nested=true;
+	  nested_level+=1;
+	  if(current_content!=NULL){
+	    elements* cursor=my_service->inputs;
+	    while(cursor->next!=NULL)
+	      cursor=cursor->next;
+	    if(nested_level>1){
+	      for(int j=0;j<nested_level-1;j++){
+		cursor=cursor->child;
+		while(cursor->next!=NULL)
+		  cursor=cursor->next;
+	      }
+	    }
+	    addMapToMap(&cursor->content,current_content);
+	    freeMap(&current_content);
+	    free(current_content);
+	    current_content=NULL;
+	  }
 	}
 #ifdef DEBUG_SERVICE_CONF
@@ -593,12 +669,5 @@
 	fprintf(stderr,"(DATAINPUTS - 489) ALLOCATE current_element\n");
 #endif
-	current_element=(elements*)malloc(ELEMENTS_SIZE);
-	current_element->name=NULL;
-	current_element->content=NULL;
-	current_element->metadata=NULL;
-	current_element->format=NULL;
-	current_element->defaults=NULL;
-	current_element->supported=NULL;
-	current_element->next=NULL;
+	current_element=createEmptyElements();
       }
       if(current_element->name==NULL){
@@ -613,8 +682,7 @@
 	if($1!=NULL){ 
 	  char *cen=zStrdup($1);
-	  current_element->name=(char*)malloc((strlen(cen)-1)*sizeof(char*));
 	  cen[strlen(cen)-1]=0;
 	  cen+=1;
-	  sprintf(current_element->name,"%s",cen);
+	  setElementsName(&current_element,cen);
 	  cen-=1;
 	  free(cen);
@@ -622,10 +690,4 @@
 	  fprintf(stderr,"NAME IN %s (current - %s)\n",$1,current_element->name);
 #endif
-	  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_SERVICE_CONF
 	  fprintf(stderr,"NAME IN %s (current - %s)\n",$1,current_element->name);
@@ -659,12 +721,5 @@
 	    fprintf(stderr,"(DATAOUTPUTS -%d) ALLOCATE current_element %s \n",__LINE__,__FILE__);
 #endif
-	    current_element=(elements*)malloc(ELEMENTS_SIZE);
-	    current_element->name=NULL;
-	    current_element->content=NULL;
-	    current_element->metadata=NULL;
-	    current_element->format=NULL;
-	    current_element->defaults=NULL;
-	    current_element->supported=NULL;
-	    current_element->next=NULL;
+	    current_element=createEmptyElements();
 	  }
 	  if(current_element->name==NULL){
@@ -675,16 +730,9 @@
 	    if($1!=NULL){ 
 	      char *cen=zStrdup($1);
-	      current_element->name=(char*)malloc((strlen(cen)-1)*sizeof(char));
 	      cen[strlen(cen)-1]=0;
 	      cen+=1;
-	      sprintf(current_element->name,"%s",cen);
+	      setElementsName(&current_element,cen);
 	      cen-=1;
 	      free(cen);
-	      current_element->content=NULL;
-	      current_element->metadata=NULL;
-	      current_element->format=NULL;
-	      current_element->defaults=NULL;
-	      current_element->supported=NULL;
-	      current_element->next=NULL;
 	    }
 	  }
@@ -696,6 +744,44 @@
 	    if(my_service->outputs==NULL)
 	      my_service->outputs=dupElements(current_element);
-	    else
-	      addToElements(&my_service->outputs,current_element);
+	    else{
+	      if(wait_nested){
+		elements* cursor=my_service->outputs;
+		while(cursor->next!=NULL)
+		  cursor=cursor->next;
+		if(nested_level>1){
+		  for(int j=0;j<nested_level-1;j++){
+		    cursor=cursor->child;
+		    while(cursor->next!=NULL)
+		      cursor=cursor->next;
+		  }
+		}
+		if(cursor->child==NULL){
+		  cursor->child=dupElements(current_element);
+		}else
+		  addToElements(&cursor->child,current_element);
+	      }else
+		addToElements(&my_service->outputs,current_element);
+	    }
+	    if(current_element->format==NULL){
+	      wait_nested=true;
+	      nested_level+=1;
+	      if(current_content!=NULL){
+		elements* cursor=my_service->outputs;
+		while(cursor->next!=NULL)
+		  cursor=cursor->next;
+		if(nested_level>1){
+		  for(int j=0;j<nested_level-1;j++){
+		    cursor=cursor->child;
+		    while(cursor->next!=NULL)
+		      cursor=cursor->next;
+		  }
+		}
+		addMapToMap(&cursor->content,current_content);
+		freeMap(&current_content);
+		free(current_content);
+		current_content=NULL;
+	      }
+	    }
+
 #ifdef DEBUG_SERVICE_CONF
 	    fprintf(stderr,"ADD TO OUTPUTS Elements\n");
@@ -705,18 +791,11 @@
 	    free(current_element);
 	    current_element=NULL;
-	    current_element=(elements*)malloc(ELEMENTS_SIZE);
+	    
 	    char *cen=zStrdup($1);
-	    current_element->name=(char*)malloc((strlen(cen)-1)*sizeof(char));
 	    cen[strlen(cen)-1]=0;
 	    cen+=1;
-	    sprintf(current_element->name,"%s",cen);
+	    current_element=createElements(cen);
 	    cen-=1;
 	    free(cen);
-	    current_element->content=NULL;
-	    current_element->metadata=NULL;
-	    current_element->format=NULL;
-	    current_element->defaults=NULL;
-	    current_element->supported=NULL;
-	    current_element->next=NULL;
 	  }
 	  else{
@@ -727,5 +806,4 @@
 	    if($1!=NULL){ 
 	      char *cen=zStrdup($1);
-	      current_element->name=(char*)malloc((strlen(cen))*sizeof(char*));
 	      cen[strlen(cen)-1]=0;
 #ifdef DEBUG
@@ -733,13 +811,7 @@
 #endif
 	      cen+=1;
-	      sprintf(current_element->name,"%s",cen);
+	      setElementsName(&current_element,cen);
 	      cen-=1;
 	      free(cen);
-	      current_element->content=NULL;
-	      current_element->metadata=NULL;
-	      current_element->format=NULL;
-	      current_element->defaults=NULL;
-	      current_element->supported=NULL;
-	      current_element->next=NULL;
 	    }
 	  }
@@ -780,6 +852,8 @@
   }
 #ifdef DEBUG_SERVICE_CONF
-  fprintf(stderr,"(STARTING)FREE current_element\n");
-#endif
+  fprintf(stderr,"(STARTING)FREE current_element %s\n",file);
+#endif
+  fflush(stderr);
+  fflush(stdout);
   if(current_element!=NULL){
     freeElements(&current_element);
@@ -797,4 +871,5 @@
   wait_outputs=-1;
   wait_data=false;
+  wait_nested=false;
 //data=-1;
   ::data=-1; // knut: add namespace to avoid ambiguous symbol
@@ -831,5 +906,21 @@
       fprintf(stderr,"(DATAOUTPUTS - %d) COPY current_element\n",__LINE__);
 #endif
-      addToElements(&my_service->outputs,current_element);
+      if(wait_nested){
+	elements* cursor=my_service->outputs;
+	while(cursor->next!=NULL)
+	  cursor=cursor->next;
+	if(nested_level>1){
+	  for(int j=0;j<nested_level-1;j++){
+	    cursor=cursor->child;
+	    while(cursor->next!=NULL)
+	      cursor=cursor->next;
+	  }
+	}
+	if(cursor->child==NULL){
+	  cursor->child=dupElements(current_element);
+	}else
+	  addToElements(&cursor->child,current_element);
+      }else
+	addToElements(&my_service->outputs,current_element);
     }
 #ifdef DEBUG_SERVICE_CONF
Index: /trunk/zoo-project/zoo-kernel/service_internal_java.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_java.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_internal_java.c	(revision 790)
@@ -251,9 +251,10 @@
       if (pValue != (jint)NULL){
 	res=pValue;
-	m=mapsFromHashMap(env,arg1,scHashMapClass);
-	*main_conf=m;
-	outputs=mapsFromHashMap(env,arg3,scHashMapClass);
-	*real_outputs=outputs;
-
+	freeMaps(real_outputs);
+	free(*real_outputs);
+	freeMaps(main_conf);
+	free(*main_conf);
+	*main_conf=mapsFromHashMap(env,arg1,scHashMapClass);
+	*real_outputs=mapsFromHashMap(env,arg3,scHashMapClass);
 #ifdef DEBUG
 	fprintf(stderr,"Result of call: %i\n", pValue);
@@ -757,15 +758,15 @@
     jobject jk=(*env)->CallObjectMethod(env,tmp,getKey_mid);
 #endif
-    maps* cmap=(maps*)malloc(sizeof(maps));
-#ifdef JAVA7
-    cmap->name=(char*)(*env).GetStringUTFChars((jstring)jk, NULL);
-#else
-    cmap->name=(*env)->GetStringUTFChars(env, jk, NULL);
-#endif
+    maps* cmap=createMaps(
+#ifdef JAVA7
+      (char*)(*env).GetStringUTFChars((jstring)jk, NULL)
+#else
+      (*env)->GetStringUTFChars(env, jk, NULL)
+#endif
+			  );
 #ifdef DEBUG
     fprintf(stderr," / %s \n",cmap->name);
 #endif
     cmap->content=res;
-    cmap->next=NULL;
     if(final_res==NULL)
       final_res=dupMaps(&cmap);
@@ -780,5 +781,4 @@
   fprintf(stderr,"mapsFromHashMap end\n");
 #endif
-
   return final_res;
 }
Index: /trunk/zoo-project/zoo-kernel/service_internal_js.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_js.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_internal_js.c	(revision 790)
@@ -425,4 +425,9 @@
   while(tmp!=NULL){
     JSObject *pval=JSObject_FromMap(cx,tmp->content);
+    if(tmp->child!=NULL){
+      JSObject *pvalc=JSObject_FromMaps(cx,tmp->child);
+      jsval pvaljc=OBJECT_TO_JSVAL(pvalc);
+      JS_SetProperty(cx, pval, "child", &pvaljc);
+    }
     jsval pvalj=OBJECT_TO_JSVAL(pval);
     JS_SetProperty(cx, res, tmp->name, &pvalj);
@@ -548,8 +553,5 @@
 	
 	tmp=JS_EncodeString(cx,jsmsg);
-	tres=(maps*)malloc(MAPS_SIZE);
-	tres->name=zStrdup(tmp);
-	tres->content=NULL;
-	tres->next=NULL;
+	tres=createMaps(tmp);
 
 	jsval nvp=JSVAL_NULL;
@@ -567,4 +569,17 @@
 	}
 
+	jsval nvp0=JSVAL_NULL;
+	JSObject *nvp01=JSVAL_TO_OBJECT(JSVAL_NULL);
+	if((JS_GetProperty(cx, nvp1, "child", &nvp0)==JS_FALSE)){
+#ifdef JS_DEBUG
+	  fprintf(stderr,"Enumerate id : %d => %s => No more value\n",oi,tmp);
+#endif
+	}
+	JS_ValueToObject(cx,nvp0,&nvp01);
+	jsval nvp01j=OBJECT_TO_JSVAL(nvp01);
+	if(!JSVAL_IS_NULL(nvp01j)){
+	  tres->child=mapsFromJSObject(cx,nvp01j);
+	}
+
 	if(res==NULL)
 	  res=dupMaps(&tres);
@@ -574,5 +589,4 @@
 	free(tres);
 	tres=NULL;
-		
       }
       JS_DestroyIdArray(cx,idp);
@@ -725,13 +739,15 @@
       fprintf(stderr,"Enumerate id : %d [ %s => %s ]\n",index,tmp,tmp1);
 #endif
-      if(res!=NULL){
-#ifdef JS_DEBUG
-	fprintf(stderr,"%s - %s\n",tmp,tmp1);
-#endif
-	addToMap(res,tmp,tmp1);
-      }
-      else{
-	res=createMap(tmp,tmp1);
-	res->next=NULL;
+      if(strcasecmp(tmp,"child")!=0){
+	if(res!=NULL){
+#ifdef JS_DEBUG
+	  fprintf(stderr,"%s - %s\n",tmp,tmp1);
+#endif
+	  addToMap(res,tmp,tmp1);
+	}
+	else{
+	  res=createMap(tmp,tmp1);
+	  res->next=NULL;
+	}
       }
       free(tmp);
Index: /trunk/zoo-project/zoo-kernel/service_internal_perl.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_perl.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_internal_perl.c	(revision 790)
@@ -105,5 +105,4 @@
 int hash_to_maps(HV * hh,maps** m){
 	hv_iterinit(hh);
-	*m = (maps *)malloc(MAPS_SIZE);
 	maps * tmp = *m;
 	HE * he = hv_iternext(hh);
@@ -111,10 +110,11 @@
 	while (he != NULL) {
 		//fprintf(stderr,"key ===> %s \n",HeKEY(he));
-		tmp->name = HeKEY(he);
+		tmp=createMaps(HeKEY(he));
 		hash_to_map((HV *) SvRV(HeVAL(he)),&mm);
 		tmp->content = mm;
+		if(*m==NULL)
+		  *m=tmp;
 		he = hv_iternext(hh);
 		if (he != NULL){
-			tmp->next = (maps *)malloc(MAPS_SIZE);
 			tmp= tmp->next;
 		}
Index: /trunk/zoo-project/zoo-kernel/service_internal_php.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_php.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_internal_php.c	(revision 790)
@@ -306,10 +306,10 @@
   while(tmp!=NULL){
     map* sMap=getMapArray(tmp,"size",0);    
-	if(strncmp(tmp->name,"value",5)==0 && sMap!=NULL && tmp->value != NULL){
+    if(strncmp(tmp->name,"value",5)==0 && sMap!=NULL && tmp->value != NULL){
       tres=add_assoc_stringl(mapArray,tmp->name,tmp->value,atoi(sMap->value),1);
-	} 
-	else if (tmp->value != NULL) {
+    } 
+    else if (tmp->value != NULL) {
       tres=add_assoc_string(mapArray,tmp->name,tmp->value,1);
-	}
+    }
     tmp=tmp->next;
   }
@@ -362,20 +362,19 @@
        * String Key / Associative
        */
-      cursor=(maps*)malloc(MAPS_SIZE);
-      cursor->name=strdup(key);
-    }
+      cursor=createMaps(key);
 #ifdef DEBUG	
-    fprintf(stderr,"key : %s\n",key);
+      fprintf(stderr,"key : %s\n",key);
 #endif	
-    HashTable* t=HASH_OF(*ppzval);
-#ifdef DEBUG
-    fprintf(stderr,"key : %s\n",key);
-#endif
-    cursor->content=php_map_from_HasTable(t);
-    cursor->next=NULL;
-    if(final_res==NULL)
-      final_res=cursor;
-    else{
-      addMapsToMaps(&final_res,cursor);
+      HashTable* t=HASH_OF(*ppzval);
+#ifdef DEBUG
+      fprintf(stderr,"key : %s\n",key);
+#endif
+      cursor->content=php_map_from_HasTable(t);
+      cursor->next=NULL;
+      if(final_res==NULL)
+	final_res=dupMaps(&cursor);
+      else{
+	addMapsToMaps(&final_res,cursor);
+      }
       freeMaps(&cursor);
       free(cursor);
Index: /trunk/zoo-project/zoo-kernel/service_internal_php7.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_php7.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_internal_php7.c	(revision 790)
@@ -355,8 +355,6 @@
     HashTable* tab = HASH_OF(&copy);
 		
-    maps* node = (maps*) malloc(MAPS_SIZE);
-    node->name = strdup(ZSTR_VAL(key));					
+    maps* node = createMaps(ZSTR_VAL(key));					
     node->content = php_hashtable_to_map(tab);
-    node->next = NULL;
 		
     if(res == NULL) {
Index: /trunk/zoo-project/zoo-kernel/service_internal_python.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 790)
@@ -356,12 +356,14 @@
       if(pbt!=NULL)
 	free(pbt);
-      pbt=(char*)malloc((90+strlen(tpbt)+strlen(PyString_AsString(trace))+1)*sizeof(char));
-      sprintf(pbt,_("%s\nUnable to run your python process properly. Please check the following messages : %s"),tpbt,PyString_AsString(trace));
+      char* format=_("%s\nUnable to run your python process properly. Please check the following messages : %s");
+      pbt=(char*)malloc((strlen(format)+strlen(tpbt)+strlen(PyString_AsString(trace))+1)*sizeof(char));
+      sprintf(pbt,format,tpbt,PyString_AsString(trace));
     }
     else{
       if(pbt!=NULL)
 	free(pbt);
-      pbt=(char*)malloc((90+strlen(tpbt)+strlen(PyString_AsString(trace))+1)*sizeof(char));      
-      sprintf(pbt,_("%s \n Unable to run your python process properly. Unable to provide any further information."),tpbt);
+      char* format=_("%s \n Unable to run your python process properly. Unable to provide any further information.");
+      pbt=(char*)malloc((strlen(format)+strlen(tpbt)+strlen(PyString_AsString(trace))+1)*sizeof(char));
+      sprintf(pbt,format,tpbt);
     }
     free(tpbt);
@@ -390,4 +392,13 @@
   while(tmp!=NULL){
     PyObject* value=(PyObject*)PyDict_FromMap(tmp->content);
+    if(tmp->child!=NULL){
+      PyObject* cname=PyString_FromString("child");
+      PyObject* childs=(PyObject*)PyDict_FromMaps(tmp->child);
+      if(PyDict_SetItem(value,cname,childs)<0){
+	fprintf(stderr,"Unable to set map value ...");
+	return NULL;
+      } 
+      Py_DECREF(cname);
+    }
     PyObject* name=PyString_FromString(tmp->name);
     if(PyDict_SetItem(res,name,value)<0){
@@ -543,7 +554,11 @@
 	    PyString_AsString(key),PyString_AsString(value));
 #endif
-    cursor=(maps*)malloc(MAPS_SIZE);
-    cursor->name=zStrdup(PyString_AsString(key));
+    cursor=createMaps(PyString_AsString(key));
     cursor->content=mapFromPyDict((PyDictObject*)value);
+    PyObject* cname=PyString_FromString("child");
+    PyObject* childs=PyDict_GetItem((PyObject*)value,cname);
+    if(childs!=NULL)
+      cursor->child=mapsFromPyDict((PyDictObject*)childs);
+    Py_DECREF(cname);
 #ifdef DEBUG
     dumpMap(cursor->content);
@@ -626,37 +641,38 @@
 	    PyString_AsString(key),PyString_AsString(value));
 #endif
-    
-    if(strncmp(PyString_AsString(key),"value",5)==0){
-      char *buffer=NULL;
-      Py_ssize_t size;
+    if(strncmp(PyString_AsString(key),"child",5)!=0){
+      if(strncmp(PyString_AsString(key),"value",5)==0){
+	char *buffer=NULL;
+	Py_ssize_t size;
 #if PY_MAJOR_VERSION >= 3
-      if(PyBytes_Check(value)){
-	size=PyBytes_Size(value);
-	buffer=PyBytes_AsString(value);
-      }
-      else
-	if(PyUnicode_Check(value) && PyUnicode_READY(value) == 0){
-	  buffer=PyUnicode_AsUTF8AndSize(value,&size);
+	if(PyBytes_Check(value)){
+	  size=PyBytes_Size(value);
+	  buffer=PyBytes_AsString(value);
+	}
+	else
+	  if(PyUnicode_Check(value) && PyUnicode_READY(value) == 0){
+	    buffer=PyUnicode_AsUTF8AndSize(value,&size);
+	  }
+	  else{
+#ifdef DEBUG
+	    fprintf(stderr,"Unsupported return value.");
+#endif
+	    return NULL;
+	  }
+#else
+	PyString_AsStringAndSize(value,&buffer,&size);
+#endif      
+	res = addToMapWithSize(res,PyString_AsString(key),buffer,size);
+      }else{
+	char* lkey=PyString_AsString(key);
+	char* lvalue=PyString_AsString(value);
+	if(res!=NULL){
+	  if(PyString_Size(value)>0)
+	    addToMap(res,lkey,lvalue);
 	}
 	else{
-#ifdef DEBUG
-	  fprintf(stderr,"Unsupported return value.");
-#endif
-	  return NULL;
-	}
-#else
-      PyString_AsStringAndSize(value,&buffer,&size);
-#endif      
-	  res = addToMapWithSize(res,PyString_AsString(key),buffer,size);
-    }else{
-      char* lkey=PyString_AsString(key);
-      char* lvalue=PyString_AsString(value);
-      if(res!=NULL){
-	if(PyString_Size(value)>0)
-	  addToMap(res,lkey,lvalue);
-      }
-      else{
-	if(PyString_Size(value)>0)
-	  res=createMap(lkey,lvalue);
+	  if(PyString_Size(value)>0)
+	    res=createMap(lkey,lvalue);
+	}
       }
     }
Index: /trunk/zoo-project/zoo-kernel/service_internal_ruby.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_ruby.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_internal_ruby.c	(revision 790)
@@ -354,14 +354,11 @@
 	    StringValueCStr(key),StringValueCStr(value));
 #endif
-    cursor=(maps*)malloc(MAPS_SIZE);
-    cursor->name=StringValueCStr(key);
+    cursor=createMaps(StringValueCStr(key));
     cursor->content=mapFromRubyHash(value);
-    cursor->next=NULL;
     if(res==NULL)
       res=dupMaps(&cursor);
     else
       addMapsToMaps(&res,cursor);
-    freeMap(&cursor->content);
-    free(cursor->content);
+    freeMaps(&cursor);
     free(cursor);
   }
Index: /trunk/zoo-project/zoo-kernel/service_internal_saga.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_internal_saga.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_internal_saga.c	(revision 790)
@@ -690,8 +690,6 @@
     tmpName[strlen(fext)+(strlen(gfile->value)+strlen(tmpSubName)-4)]=0;
 
-    maps* louts=(maps*)malloc(MAPS_SIZE);
-    louts->name=zStrdup(tinOut[i]);
+    maps* louts=createMaps(tinOut[i]);
     louts->content=createMap("mimeType","UNKOWN");
-    louts->next=NULL;
     
     addToMap(arg,tinOut[i],tmpName);
@@ -741,8 +739,6 @@
     addToMap(arg,"GRIDS","");
 
-    maps* louts=(maps*)malloc(MAPS_SIZE);
-    louts->name=zStrdup("GRIDS");
+    maps* louts=createMaps("GRIDS");
     louts->content=createMap("mimeType","UNKOWN");
-    louts->next=NULL;
 
     sagaExecuteCmd(conf,"io_gdal","0",arg,&louts);
@@ -786,8 +782,6 @@
       addToMap(arg,"FILES",v->value);
 
-    maps* louts=(maps*)malloc(MAPS_SIZE);
-    louts->name=zStrdup("SHAPES");
+    maps* louts=createMaps("SHAPES");
     louts->content=createMap("mimeType","UNKOWN");
-    louts->next=NULL;
 
     sagaExecuteCmd(conf,"io_gdal","3",arg,&louts);
@@ -832,8 +826,6 @@
     if(v!=NULL)
       addToMap(arg,"SHAPES",v->value);
-    maps* louts=(maps*)malloc(MAPS_SIZE);
-    louts->name=zStrdup("TIN");
+    maps* louts=createMaps("TIN");
     louts->content=createMap("mimeType","UNKOWN");
-    louts->next=NULL;
     sagaExecuteCmd(conf,"tin_tools","2",arg,&louts);
     map* tmp=getMapFromMaps(louts,"TIN","generated_file");
@@ -887,8 +879,6 @@
 
     // Create the output maps
-    maps* louts=(maps*)malloc(MAPS_SIZE);
-    louts->name=zStrdup("TABLE");
+    maps* louts=createMaps("TABLE");
     louts->content=createMap("mimeType","UNKOWN");
-    louts->next=NULL;
 
     // Execute the saga command
@@ -940,8 +930,6 @@
 
     // Create the output maps
-    maps* louts=(maps*)malloc(MAPS_SIZE);
-    louts->name=zStrdup("POINTS");
+    maps* louts=createMaps("POINTS");
     louts->content=createMap("mimeType","UNKOWN");
-    louts->next=NULL;
 
     // Execute the saga command
Index: /trunk/zoo-project/zoo-kernel/service_yaml.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/service_yaml.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/service_yaml.c	(revision 790)
@@ -84,9 +84,14 @@
   yaml_parser_set_input_file(&parser, fh);
   /* BEGIN new code */
+  int nleveld=-1;
   int level=0;
   int plevel=level;
+  int nlevel=0;
+  int pnlevel=0;
   int ilevel=-1;
   int blevel=-1;
   int ttype=0;
+  int outputs=-1;
+  int noutputs=-1;
   int wait_metadata=-1;
   char *cur_key;
@@ -145,5 +150,11 @@
       blevel++;
       break;
-    case YAML_SCALAR_TOKEN:  
+    case YAML_SCALAR_TOKEN:
+      if((blevel-1)/2<nlevel){
+	pnlevel=nlevel;
+	nlevel=(blevel-1)/2;
+	nleveld=1;
+      }else
+	nleveld=-1;
       if(ttype==0){
 	cur_key=zStrdup((char *)token.data.scalar.value);
@@ -180,4 +191,46 @@
 	current_content=NULL;
 	wait_metadata=1;
+      }
+      if(strcasecmp((char *)token.data.scalar.value,"Child")==0){
+	elements* cursor=my_service->inputs;
+	if(outputs==1)
+	  cursor=my_service->outputs;
+	for(int i=0;(blevel/2)>1 && i<(blevel/2)-1 && cursor!=NULL;i++){
+	  while(cursor->next!=NULL)
+	    cursor=cursor->next;
+	  if(cursor->child!=NULL){
+	    cursor=cursor->child;
+	  }
+	}
+	if(current_content!=NULL){
+	  addMapToMap(&current_element->content,current_content);
+	  freeMap(&current_content);
+	  free(current_content);
+	  current_content=NULL;
+	}
+	if(current_element!=NULL){
+	  if(blevel/2>1 && cursor!=NULL){
+	    if(cursor->child==NULL)
+	      cursor->child=dupElements(current_element);
+	    else
+	      addToElements(&cursor->child,current_element);
+	  }
+	  else{
+	    if(outputs<0)
+	      if(my_service->inputs==NULL)
+		my_service->inputs=dupElements(current_element);
+	      else
+		addToElements(&my_service->inputs,current_element);
+	    else
+	      if(my_service->inputs==NULL)
+		my_service->outputs=dupElements(current_element);
+	      else
+		addToElements(&my_service->outputs,current_element);
+	  }
+	  freeElements(&current_element);
+	  free(current_element);
+	  current_element=NULL;
+	}
+	nlevel+=1;
       }
       if(ttype==0 && strcasecmp((char *)token.data.scalar.value,"inputs")==0 && blevel==0){
@@ -200,4 +253,5 @@
       }
       if(ttype==0 && strcasecmp((char *)token.data.scalar.value,"outputs")==0 && blevel==1){
+	outputs=1;
 	level++;
 #ifdef DEBUG_YAML
@@ -303,4 +357,57 @@
       }
 
+      if(strcasecmp(token.data.scalar.value,"default")!=0 && strcasecmp(token.data.scalar.value,"supported")!=0 && level==1 && (blevel-1)%2==0 && blevel!=1 && (blevel-1)/2==nlevel){
+	if(current_element==NULL)
+	  current_element=createElements((char *)token.data.scalar.value);
+	else{
+	  if(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);
+	    }
+	    freeMap(&current_content);
+	    free(current_content);
+	    current_content=NULL;
+	  }
+	  
+	  elements* cursor=my_service->inputs;
+	  if(outputs==1)
+	    cursor=my_service->outputs;
+	  int llevel=((blevel-1)/2);
+	  if(nleveld>0)
+	    llevel=((blevel-1)/2)+1;
+	  for(int i=0;llevel>1 && i<llevel-1 && cursor!=NULL;i++){
+	    while(cursor->next!=NULL)
+	      cursor=cursor->next;
+	    if(cursor->child!=NULL){
+	      cursor=cursor->child;
+	    }
+	  }
+	  if(llevel>1)
+	    if(cursor->child==NULL)
+	      cursor->child=dupElements(current_element);
+	    else
+	      addToElements(&cursor->child,current_element);
+	  else
+	    if(cursor==NULL)
+	      cursor=dupElements(current_element);
+	    else
+	      addToElements(&cursor,current_element);
+	  freeElements(&current_element);
+	  free(current_element);
+	  current_element=NULL;
+	  current_element=createElements((char *)token.data.scalar.value);
+	}
+      }
       if(blevel==1 && level==1){
 	if(current_element!=NULL && current_content!=NULL){
@@ -319,23 +426,48 @@
 	      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);
-	}
+	  freeMap(&current_content);
+	  free(current_content);
+	  current_content=NULL;
+	}
+	if(nleveld<0){
+	  if(current_element!=NULL){
+	    if(outputs<0)
+	      if(my_service->inputs==NULL)
+		my_service->inputs=dupElements(current_element);
+	      else
+		addToElements(&my_service->inputs,current_element);
+	    else
+	      if(my_service->outputs==NULL)
+		my_service->outputs=dupElements(current_element);
+	      else
+		addToElements(&my_service->outputs,current_element);
+	    freeElements(&current_element);
+	    free(current_element);
+	  }
+	}
+	else{
+	  if(current_element!=NULL){
+	    elements* cursor=my_service->inputs;
+	    if(outputs==1)
+	      cursor=my_service->outputs;
+	    while(cursor->next!=NULL)
+	      cursor=cursor->next;
+	    for(int i=0;pnlevel>1 && i<pnlevel-1 && cursor!=NULL;i++){
+	      while(cursor->next!=NULL)
+		cursor=cursor->next;
+	      if(cursor->child!=NULL){
+		cursor=cursor->child;
+	      }
+	    }
+	    if(cursor->child==NULL)
+	      cursor->child=dupElements(current_element);
+	    else
+	      addToElements(&cursor->child,current_element);
+	    freeElements(&current_element);
+	    free(current_element);
+	  }
+	}   
 	plevel=level;
-	current_element=(elements*)malloc(ELEMENTS_SIZE);
-	current_element->name=zStrdup((char *)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;
-	
+	current_element=createElements((char *)token.data.scalar.value);	
       }
       if(blevel==1 && level==2){
@@ -355,4 +487,7 @@
 	      addMapToIoType(&current_element->supported,current_content);
 	  }
+	  freeMaps(&current_content);
+	  free(current_content);
+	  current_content=NULL;
 	}
 	if(current_element!=NULL){
@@ -372,14 +507,14 @@
 	}
 	plevel=level;
-	current_element=(elements*)malloc(ELEMENTS_SIZE);
-	current_element->name=zStrdup((char *)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;
+	current_element=createElements((char *)token.data.scalar.value);	
 	
       }
+
+      if(noutputs>0)
+	outputs=1;
+      if(strcasecmp((char *)token.data.scalar.value,"outputs")==0 && ttype==0 && blevel==0){
+	noutputs=1;
+      }
+      
 
 
@@ -433,9 +568,27 @@
     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);
+    if(nlevel>0){
+      elements* cursor=my_service->inputs;
+      if(outputs==1)
+	cursor=my_service->outputs;
+      for(int i=0;nlevel>1 && i<nlevel-1 && cursor!=NULL;i++){
+	while(cursor->next!=NULL)
+	  cursor=cursor->next;
+	if(cursor->child!=NULL){
+	  cursor=cursor->child;
+	}
+      }
+      if(cursor->child==NULL)
+	cursor->child=dupElements(current_element);
+      else
+	addToElements(&cursor->child,current_element);
+    }else{
+      if(my_service->outputs==NULL)
+	my_service->outputs=dupElements(current_element);
+      else
+	addToElements(&my_service->outputs,current_element);
+    }
     freeElements(&current_element);
     free(current_element);
Index: /trunk/zoo-project/zoo-kernel/zoo_loader.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/zoo_loader.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/zoo_loader.c	(revision 790)
@@ -95,4 +95,5 @@
      strncasecmp(cgiRequestMethod,"post",4)==0){
     if(cgiContentLength==0){
+
        char *buffer=new char[2];
        char *res=NULL;
@@ -387,5 +388,4 @@
       token=strtok_r(NULL,"&",&saveptr);
     }
-    
   }
 
@@ -393,5 +393,8 @@
     map* tmp=getMap(tmpMap,"dataInputs");
     if(tmp!=NULL){
-      addToMap(tmpMap,"dataInputs",strstr(strQuery,"dataInputs=")+11);
+      if(strcasestr(strQuery,"dataInputs=")!=NULL)
+	addToMap(tmpMap,"dataInputs",strcasestr(strQuery,"dataInputs=")+11);
+      else
+	addToMap(tmpMap,"dataInputs","None");
     }
   }
Index: /trunk/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- /trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 789)
+++ /trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 790)
@@ -770,5 +770,5 @@
 
   map *tmpReq = getMap (request_inputs, "xrequest");
-  
+
   if(r_inputs2 != NULL && tmpReq != NULL) {
     const char key[] = "rfile=";
@@ -922,7 +922,8 @@
   if (m == NULL)
     {
-      return errorException (m, _("Unable to allocate memory"),
+      return errorException (NULL, _("Unable to allocate memory"),
                              "InternalError", NULL);
     }
+  m->child=NULL;
   char ntmp[1024];
 #ifndef ETC_DIR
@@ -1537,7 +1538,7 @@
 							   NULL);
 				  }
-#ifdef DEBUG
-				printf
-				  ("#################\n(%s) %s\n#################\n",
+#ifdef DEBUG_SERVICE_CONF
+				fprintf
+				  (stderr,"#################\n(%s) %s\n#################\n",
 				   r_inputs->value, buff1);
 #endif
@@ -1703,5 +1704,5 @@
   map *postRequest = NULL;
   postRequest = getMap (request_inputs, "xrequest");
-
+  
   if(vid==1 && postRequest==NULL){
     errorException (m,_("Unable to run Execute request using the GET HTTP method"),"InvalidParameterValue", "request");  
@@ -1817,5 +1818,4 @@
   maps *tmpmaps = request_input_real_format;
 
-
   if(parseRequest(&m,&request_inputs,s1,&request_input_real_format,&request_output_real_format,&hInternet)<0){
     freeMaps (&m);
@@ -1828,5 +1828,4 @@
     return 0;
   }
-
 
   // Define each env variable in runing environment
@@ -1989,6 +1988,5 @@
    *
    */
-  maps *_tmpMaps = (maps *) malloc (MAPS_SIZE);
-  _tmpMaps->name = zStrdup ("lenv");
+  maps *_tmpMaps = createMaps("lenv");
   char tmpBuff[100];
   struct ztimeval tp;
@@ -1998,5 +1996,4 @@
     sprintf (tmpBuff, "%i", (cpid + (int) time (NULL)));
   _tmpMaps->content = createMap ("osid", tmpBuff);
-  _tmpMaps->next = NULL;
   sprintf (tmpBuff, "%i", cpid);
   addToMap (_tmpMaps->content, "sid", tmpBuff);
@@ -2081,4 +2078,5 @@
           free (tcook);
           maps *tmpSess = (maps *) malloc (MAPS_SIZE);
+	  tmpSess->child=NULL;
           struct stat file_status;
           int istat = stat (session_file_path, &file_status);
@@ -2106,8 +2104,5 @@
     *environ;
 #endif
-  _tmpMaps = (maps *) malloc (MAPS_SIZE);
-  _tmpMaps->name = zStrdup ("renv");
-  _tmpMaps->content = NULL;
-  _tmpMaps->next = NULL;
+  _tmpMaps = createMaps("renv");
   for (; s; ei++) {
     char* tmpName=zStrdup(s);
@@ -2229,8 +2224,6 @@
                      strlen (usid->value) + 7) * sizeof (char));                    
           sprintf (fbkpres, "%s/%s.res", r_inputs->value, usid->value);
-	  bmap = (maps *) malloc (MAPS_SIZE);
-	  bmap->name=zStrdup("status");
+	  bmap = createMaps("status");
 	  bmap->content=createMap("usid",usid->value);
-	  bmap->next=NULL;
 	  addToMap(bmap->content,"sid",tmpm->value);
 	  addIntToMap(bmap->content,"pid",getpid());
Index: /trunk/zoo-project/zoo-services/gdal/grid/service.c
===================================================================
--- /trunk/zoo-project/zoo-services/gdal/grid/service.c	(revision 789)
+++ /trunk/zoo-project/zoo-services/gdal/grid/service.c	(revision 790)
@@ -1068,5 +1068,11 @@
         Usage();
         GDALDestroyDriverManager();
+#ifndef ZOO_SERVICE
         exit( 2 );
+#else
+	fprintf(stderr,"pszSource %s\n",pszSource);
+	fprintf(stderr,"pszDest %s\n",pszDest);
+	return SERVICE_FAILED;
+#endif
     }
 
Index: /trunk/zoo-project/zoo-services/hello-js/cgi-env/hello.js
===================================================================
--- /trunk/zoo-project/zoo-services/hello-js/cgi-env/hello.js	(revision 789)
+++ /trunk/zoo-project/zoo-services/hello-js/cgi-env/hello.js	(revision 790)
@@ -29,4 +29,11 @@
 }
 
+function hellojs2(conf,inputs,outputs){
+    outputs["result"]["value"]="Hello "+inputs["S"]["child"]["nom"]["value"]+" "+inputs["S"]["child"]["prenom"]["value"]+" from the JS World !";
+    outputs["result1"]["child"]["tata"]["value"]="a"
+    //SERVICE_SUCEEDED
+    return {"result": 3,"outputs":outputs};
+}
+
 function hellojs1(conf,inputs,outputs){
 	outputs["result"]["value"]="Hello "+inputs["S"]["value"]+" from the JS World !";
Index: /trunk/zoo-project/zoo-services/ogr/ogr2ogr/service.c
===================================================================
--- /trunk/zoo-project/zoo-services/ogr/ogr2ogr/service.c	(revision 789)
+++ /trunk/zoo-project/zoo-services/ogr/ogr2ogr/service.c	(revision 790)
@@ -591,10 +591,14 @@
 /* -------------------------------------------------------------------- */
 #if GDAL_VERSION_MAJOR >= 2
-      GDALDataset *poDS;
+      GDALDataset *poDS
+	= (GDALDataset*) GDALOpenEx( pszDataSource,
+				     GDAL_OF_READONLY | GDAL_OF_VECTOR,
+				     NULL, NULL, NULL );
       GDALDataset *poODS;
       GDALDriverManager* poR=GetGDALDriverManager();
       GDALDriver          *poDriver = NULL;
 #else
-      OGRDataSource* poDS;
+      OGRDataSource* poDS
+	= OGRSFDriverRegistrar::Open( pszDataSource, FALSE );
       OGRDataSource *poODS;
       OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
@@ -737,14 +741,30 @@
         if( poODS == NULL )
         {
+	  poODS = 
+#if GDAL_VERSION_MAJOR >= 2
+	    (GDALDataset*) GDALOpenEx( pszDestDataSource,
+				       GDAL_OF_UPDATE | GDAL_OF_VECTOR,
+				       NULL, NULL, NULL )
+#else
+	    OGRSFDriverRegistrar::Open( pszDestDataSource, TRUE )
+#endif
+	    ;
+	  if( poODS == NULL )
+	    {
+	      fprintf( stderr, "FAILURE:\n"
+		       "Unable to open existing output datasource `%s'.\n",
+		       pszDestDataSource );
+#ifdef ZOO_SERVICE
+	      char tmp[1024];
+	      sprintf(tmp,"Unable to open existing output datasource `%s'.",pszDestDataSource);
+	      setMapInMaps(conf,"lenv","message",tmp);
+	      return SERVICE_FAILED;
+#else
+	      exit( 1 );
+#endif
+
             fprintf( stderr,  "%s driver failed to create %s\n", 
                     pszFormat, pszDestDataSource );
-#ifdef ZOO_SERVICE
-	    char tmp[1024];
-	    sprintf(tmp,"%s driver failed to create %s",pszFormat, pszDestDataSource);
-	    setMapInMaps(conf,"lenv","message",tmp);
-	    return SERVICE_FAILED;
-#else
-            exit( 1 );
-#endif
+	    }
         }
     }
