Index: trunk/zoo-project/zoo-kernel/main.cfg
===================================================================
--- trunk/zoo-project/zoo-kernel/main.cfg	(revision 675)
+++ trunk/zoo-project/zoo-kernel/main.cfg	(revision 676)
@@ -8,5 +8,4 @@
 dataPath = /tmp/
 cacheDir = /tmp/
-
 
 [identification]
Index: trunk/zoo-project/zoo-kernel/main_conf_read.l
===================================================================
--- trunk/zoo-project/zoo-kernel/main_conf_read.l	(revision 675)
+++ trunk/zoo-project/zoo-kernel/main_conf_read.l	(revision 676)
@@ -36,5 +36,5 @@
 attname	[a-zA-Z0-9_\-:]+
 
-attvalue1	[%\*,;@a-zA-Z0-9_\-.:" "\"\'/\\\(\)\+\x41-\xff]+
+attvalue1	[%\*,;@a-zA-Z0-9_\-.:" "\"\'/\\\(\)\+\x41-\xff?&=]+
 
 whitesp                      [ ]
Index: trunk/zoo-project/zoo-kernel/response_print.c
===================================================================
--- trunk/zoo-project/zoo-kernel/response_print.c	(revision 675)
+++ trunk/zoo-project/zoo-kernel/response_print.c	(revision 676)
@@ -639,4 +639,5 @@
  * Generate a wps:Process node for a servie and add it to a given node.
  * 
+ * @param reg the profiles registry
  * @param m the conf maps containing the main.cfg settings
  * @param registry the profile registry if any
@@ -645,5 +646,5 @@
  * @return the generated wps:ProcessOfferings xmlNodePtr 
  */
-void printGetCapabilitiesForProcess(maps* m,xmlNodePtr nc,service* serv){
+void printGetCapabilitiesForProcess(registry *reg, maps* m,xmlNodePtr nc,service* serv){
   xmlNsPtr ns,ns_ows,ns_xml,ns_xlink;
   xmlNodePtr n=NULL,nc1,nc2;
@@ -702,6 +703,13 @@
 }
 
+/**
+ * Attach attributes to a ProcessDescription or a ProcessOffering node.
+ * 
+ * @param n the XML node to attach the attributes to
+ * @param ns the XML namespace to create the attributes
+ * @param content the servive main content created from the zcfg file
+ * @param vid the version identifier (0 for 1.0.0 and 1 for 2.0.0)
+ */
 void attachAttributes(xmlNodePtr n,xmlNsPtr ns,map* content,int vid){
-  xmlNodePtr nc1;
   int limit=(vid==1?7:3);
   for(int i=1;i<limit;i+=2){
@@ -711,12 +719,59 @@
 	char *val=(char*)malloc((strlen(tmp1->value)+5)*sizeof(char));
 	sprintf(val,"%s.0.0",tmp1->value);
-	xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST val);
+	xmlNewNsProp(n,ns,BAD_CAST capabilities[vid][i],BAD_CAST val);
 	free(val);
       }
       else
-	xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST tmp1->value);
+	xmlNewNsProp(n,ns,BAD_CAST capabilities[vid][i],BAD_CAST tmp1->value);
     }
     else
-      xmlNewNsProp(nc1,ns,BAD_CAST capabilities[vid][i],BAD_CAST capabilities[vid][i+1]);
+      xmlNewNsProp(n,ns,BAD_CAST capabilities[vid][i],BAD_CAST capabilities[vid][i+1]);
+  }
+}
+
+/**
+ * Add the ows:Metadata nodes relative to the profile registry
+ *
+ * @param n the XML node to add the ows:Metadata
+ * @param ns_ows the ows XML namespace
+ * @param ns_xlink the ows xlink namespace
+ * @param reg the profile registry
+ * @param main_conf the map containing the main configuration content
+ * @param serv the service 
+ */
+void addInheritedMetadata(xmlNodePtr n,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,registry* reg,maps* main_conf,service* serv){
+  int vid=1;
+  map* tmp1=getMap(serv->content,"extend");
+  if(tmp1==NULL)
+    tmp1=getMap(serv->content,"concept");
+  if(tmp1!=NULL){
+    map* level=getMap(serv->content,"level");
+    if(level!=NULL){
+      xmlNodePtr nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
+      char* ckey=level->value;
+      if(strncasecmp(level->value,"profile",7)==0)
+	ckey="generic";
+      if(strncasecmp(level->value,"generic",7)==0)
+	ckey="concept";
+      service* inherited=getServiceFromRegistry(reg,ckey,tmp1->value);
+      if(inherited!=NULL){
+	addInheritedMetadata(n,ns_ows,ns_xlink,reg,main_conf,inherited);
+      }
+      char cschema[71];
+      sprintf(cschema,"%s%s",schemas[vid][7],ckey);
+      map* regUrl=getMapFromMaps(main_conf,"main","registryUrl");
+      map* regExt=getMapFromMaps(main_conf,"main","registryExt");
+      char* registryUrl=(char*)malloc((strlen(regUrl->value)+strlen(ckey)+
+				       (regExt!=NULL?strlen(regExt->value)+1:0)+
+				       strlen(tmp1->value)+2)*sizeof(char));
+      if(regExt!=NULL)
+	sprintf(registryUrl,"%s%s/%s.%s",regUrl->value,ckey,tmp1->value,regExt->value);
+      else
+	sprintf(registryUrl,"%s%s/%s",regUrl->value,ckey,tmp1->value);
+      xmlNewNsProp(nc1,ns_xlink,BAD_CAST "role",BAD_CAST cschema);
+      xmlNewNsProp(nc1,ns_xlink,BAD_CAST "href",BAD_CAST registryUrl);
+      free(registryUrl);
+      xmlAddChild(n,nc1);
+    }
   }
 }
@@ -725,4 +780,5 @@
  * Generate a ProcessDescription node for a servie and add it to a given node.
  * 
+ * @param reg the profile registry
  * @param m the conf maps containing the main.cfg settings
  * @param nc the XML node to add the Process node
@@ -730,5 +786,5 @@
  * @return the generated wps:ProcessOfferings xmlNodePtr 
  */
-void printDescribeProcessForProcess(maps* m,xmlNodePtr nc,service* serv){
+void printDescribeProcessForProcess(registry *reg, maps* m,xmlNodePtr nc,service* serv){
   xmlNsPtr ns,ns_ows,ns_xlink;
   xmlNodePtr n,nc1,nc2;
@@ -752,29 +808,24 @@
   else{
     nc2 = xmlNewNode(ns, BAD_CAST "ProcessOffering");
+    // In case mode was defined in the ZCFG file then restrict the 
+    // jobControlOptions value to this value. The dismiss is always 
+    // supported whatever you can set in the ZCFG file.
+    // cf. http://docs.opengeospatial.org/is/14-065/14-065.html#47 (Table 30)
+    map* mode=getMap(serv->content,"mode");
+    if(mode!=NULL){
+      if( strncasecmp(mode->value,"sync",strlen(mode->value))==0 ||
+	  strncasecmp(mode->value,"async",strlen(mode->value))==0 ){
+	char toReplace[22];
+	sprintf(toReplace,"%s-execute dismiss",mode->value);
+	addToMap(serv->content,capabilities[vid][3],toReplace);
+      }
+    }
     attachAttributes(nc2,NULL,serv->content,vid);
-    nc = xmlNewNode(ns, BAD_CAST "Process");
-  }
-  /*
-  const char *tmp4[3];
-  tmp4[0]="processVersion";
-  tmp4[1]="storeSupported";
-  tmp4[2]="statusSupported";
-  int j=0;
-  for(j=0;j<3;j++){
-    tmp1=getMap(serv->content,tmp4[j]);
-    if(tmp1!=NULL){
-      if(j==0)
-	xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST tmp1->value);      
-      else
-	xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST tmp1->value);      
-    }
-    else{
-      if(j>0)
-	xmlNewProp(nc,BAD_CAST tmp4[j],BAD_CAST "true");
-      else
-	xmlNewNsProp(nc,ns,BAD_CAST "processVersion",BAD_CAST "1");
-    }
-  }
-  */
+    map* level=getMap(serv->content,"level");
+    if(level!=NULL && strcasecmp(level->value,"generic")==0)
+      nc = xmlNewNode(ns, BAD_CAST "GenericProcess");
+    else
+      nc = xmlNewNode(ns, BAD_CAST "Process");
+  }
   
   tmp1=getMapFromMaps(m,"lenv","level");
@@ -782,17 +833,20 @@
   printDescription(nc,ns_ows,serv->name,serv->content,vid);
 
-  tmp1=serv->metadata;
-  while(tmp1!=NULL){
-    nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
-    xmlNewNsProp(nc1,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
-    xmlAddChild(nc,nc1);
-    tmp1=tmp1->next;
-  }
-
-  tmp1=getMap(serv->content,"Profile");
-  if(tmp1!=NULL && vid==0){
-    nc1 = xmlNewNode(ns, BAD_CAST "Profile");
-    xmlAddChild(nc1,xmlNewText(BAD_CAST tmp1->value));
-    xmlAddChild(nc,nc1);
+  if(vid==0){
+    tmp1=serv->metadata;
+    while(tmp1!=NULL){
+      nc1 = xmlNewNode(ns_ows, BAD_CAST "Metadata");
+      xmlNewNsProp(nc1,ns_xlink,BAD_CAST tmp1->name,BAD_CAST tmp1->value);
+      xmlAddChild(nc,nc1);
+      tmp1=tmp1->next;
+    }
+    tmp1=getMap(serv->content,"Profile");
+    if(tmp1!=NULL && vid==0){
+      nc1 = xmlNewNode(ns, BAD_CAST "Profile");
+      xmlAddChild(nc1,xmlNewText(BAD_CAST tmp1->value));
+      xmlAddChild(nc,nc1);
+    }
+  }else{
+    addInheritedMetadata(nc,ns_ows,ns_xlink,reg,m,serv);
   }
 
@@ -835,5 +889,7 @@
  * @param type the name ("Input" or "Output") of the XML node to create
  * @param ns_ows the ows XML namespace
+ * @param ns_ows the ows XML namespace
  * @param nc1 the XML node to use to add the created tree
+ * @param vid the WPS version id (0 for 1.0.0, 1 for 2.0.0)
  */
 void printFullDescription(int in,elements *elem,const char* type,xmlNsPtr ns,xmlNsPtr ns_ows,xmlNodePtr nc1,int vid){
@@ -841,18 +897,4 @@
   if(vid==1)
     ns1=ns;
-  const char *orderedFields[13];
-  orderedFields[0]="mimeType";
-  orderedFields[1]="encoding";
-  orderedFields[2]="schema";
-  orderedFields[3]="dataType";
-  orderedFields[4]="uom";
-  orderedFields[5]="CRS";
-  orderedFields[6]="value";
-  orderedFields[7]="AllowedValues";
-  orderedFields[8]="range";
-  orderedFields[9]="rangeMin";
-  orderedFields[10]="rangeMax";
-  orderedFields[11]="rangeClosure";
-  orderedFields[12]="rangeSpace";
 
   xmlNodePtr nc2,nc3,nc4,nc5,nc6,nc7,nc8,nc9;
@@ -864,5 +906,5 @@
     int isAnyValue=1;
     nc2 = xmlNewNode(NULL, BAD_CAST type);
-    if(strncmp(type,"Input",5)==0){
+    if(strstr(type,"Input")!=NULL){
       tmp1=getMap(e->content,"minOccurs");
       if(tmp1!=NULL){
@@ -885,418 +927,76 @@
     printDescription(nc2,ns_ows,e->name,e->content,vid);
 
-    /**
-     * Build the (Literal/Complex/BoundingBox)Data node
-     */
-    if(strncmp(type,"Output",6)==0){
-      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0)
-	nc3 = xmlNewNode(ns1, BAD_CAST "LiteralOutput");
-      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
-	nc3 = xmlNewNode(ns1, BAD_CAST "ComplexOutput");
-      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
-	nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxOutput");
-      else
-	nc3 = xmlNewNode(ns1, BAD_CAST e->format);
-    }else{
-      if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0 ||
-	 strncasecmp(e->format,"LITERALOUTPUT",strlen(e->format))==0){
-	nc3 = xmlNewNode(ns1, BAD_CAST "LiteralData");
-      }
-      else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
-	nc3 = xmlNewNode(ns1, BAD_CAST "ComplexData");
-      else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
-	nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxData");
-      else
-	nc3 = xmlNewNode(ns1, BAD_CAST e->format);
-    }
-
-    iotype* _tmp0=NULL;
-    iotype* _tmp=e->defaults;
-    int datatype=0;
-    bool hasUOM=false;
-    bool hasUOM1=false;
-    if(_tmp!=NULL){
-      if(strcmp(e->format,"LiteralOutput")==0 ||
-	 strcmp(e->format,"LiteralData")==0){
-     	datatype=1;
-	if(vid==1){
-	  nc4 = xmlNewNode(ns1, BAD_CAST "Format");
-	  xmlNewProp(nc4,BAD_CAST "mimeType",BAD_CAST "text/plain");
-	  xmlNewProp(nc4,BAD_CAST "default",BAD_CAST "true");
-	  xmlAddChild(nc3,nc4);
-	  nc5 = xmlNewNode(NULL, BAD_CAST "LiteralDataDomain");
-	  xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true");
-	}
-	else{
-	  nc4 = xmlNewNode(NULL, BAD_CAST "UOMs");
-	  nc5 = xmlNewNode(NULL, BAD_CAST "Default");
-	}
-      }
-      else if(strcmp(e->format,"BoundingBoxOutput")==0 ||
-	      strcmp(e->format,"BoundingBoxData")==0){
-	datatype=2;
-	nc5 = xmlNewNode(NULL, BAD_CAST "Default");
-      }
-      else{
-	if(vid==0)
-	  nc4 = xmlNewNode(NULL, BAD_CAST "Default");
-	nc5 = xmlNewNode(ns1, BAD_CAST "Format");
-	if(vid==1){
-	  xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true");
-	  int oI=0;
-	  for(oI=0;oI<3;oI++)
-	    if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
-	      xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value);
-	    }
-	}
-      }
-      
-      tmp1=_tmp->content;
-
-      if(vid==0)
-	if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){
-	  nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType");
-	  xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value));
-	  char tmp[1024];
-	  sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
-	  xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
-	  if(vid==0)
-	    xmlAddChild(nc3,nc8);
-	  else
-	    xmlAddChild(nc5,nc8);
+    if(e->format!=NULL){
+      const char orderedFields[13][14]={
+	"mimeType",
+	"encoding",
+	"schema",
+	"dataType",
+	"uom",
+	"CRS",
+	"AllowedValues",
+	"range",
+	"rangeMin",
+	"rangeMax",
+	"rangeClosure",
+	"rangeSpace"
+      };
+
+      //Build the (Literal/Complex/BoundingBox)Data node
+      if(strncmp(type,"Output",6)==0){
+	if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0)
+	  nc3 = xmlNewNode(ns1, BAD_CAST "LiteralOutput");
+	else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
+	  nc3 = xmlNewNode(ns1, BAD_CAST "ComplexOutput");
+	else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
+	  nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxOutput");
+	else
+	  nc3 = xmlNewNode(ns1, BAD_CAST e->format);
+      }else{
+	if(strncasecmp(e->format,"LITERALDATA",strlen(e->format))==0 ||
+	   strncasecmp(e->format,"LITERALOUTPUT",strlen(e->format))==0){
+	  nc3 = xmlNewNode(ns1, BAD_CAST "LiteralData");
+	}
+	else if(strncasecmp(e->format,"COMPLEXDATA",strlen(e->format))==0)
+	  nc3 = xmlNewNode(ns1, BAD_CAST "ComplexData");
+	else if(strncasecmp(e->format,"BOUNDINGBOXDATA",strlen(e->format))==0)
+	  nc3 = xmlNewNode(ns1, BAD_CAST "BoundingBoxData");
+	else
+	  nc3 = xmlNewNode(ns1, BAD_CAST e->format);
+      }
+
+      iotype* _tmp0=NULL;
+      iotype* _tmp=e->defaults;
+      int datatype=0;
+      bool hasUOM=false;
+      bool hasUOM1=false;
+      if(_tmp!=NULL){
+	if(strcmp(e->format,"LiteralOutput")==0 ||
+	   strcmp(e->format,"LiteralData")==0){
 	  datatype=1;
-	}
-
-      bool isInput=false;
-      if(strncmp(type,"Input",5)==0 || strncmp(type,"wps:Input",9)==0){
-	isInput=true;
-	if((tmp1=getMap(_tmp->content,"AllowedValues"))!=NULL){
-	  nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
-	  char *token,*saveptr1;
-	  token=strtok_r(tmp1->value,",",&saveptr1);
-	  while(token!=NULL){
-	    nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
-	    char *tmps=strdup(token);
-	    tmps[strlen(tmps)]=0;
-	    xmlAddChild(nc7,xmlNewText(BAD_CAST tmps));
-	    free(tmps);
-	    xmlAddChild(nc6,nc7);
-	    token=strtok_r(NULL,",",&saveptr1);
-	  }
-	  if(getMap(_tmp->content,"range")!=NULL ||
-	     getMap(_tmp->content,"rangeMin")!=NULL ||
-	     getMap(_tmp->content,"rangeMax")!=NULL ||
-	     getMap(_tmp->content,"rangeClosure")!=NULL )
-	    goto doRange;
-	  if(vid==0)
-	    xmlAddChild(nc3,nc6);
-	  else
-	    xmlAddChild(nc5,nc6);
-	  isAnyValue=-1;
-	}
-
-        tmp1=getMap(_tmp->content,"range");
-	if(tmp1==NULL)
-	  tmp1=getMap(_tmp->content,"rangeMin");
-	if(tmp1==NULL)
-	  tmp1=getMap(_tmp->content,"rangeMax");
-	
-	if(tmp1!=NULL && isAnyValue==1){
-	  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,"range");
-	  if(tmp0!=NULL){
-	    char* pToken;
-	    char* orig=zStrdup(tmp0->value);
-	    /**
-	     * RangeClosure: Table 47 OGC Web Services Common Standard
-	     */
-	    const 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");
-		strncpy( tmpStr, pToken+1, strlen(pToken)-1 );
-		tmpStr[strlen(pToken)-1] = '\0';
-	      }else{
-		nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
-		const char* bkt;
-		if ( ( bkt = strchr(pToken, '[') ) != NULL || ( bkt = strchr(pToken, ']') ) != NULL ){
-		  strncpy( tmpStr, pToken, bkt - pToken );
-		  tmpStr[bkt - pToken] = '\0';
-		}
-	      }
-	      xmlAddChild(nc7,xmlNewText(BAD_CAST tmpStr));
-	      free(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);
-	    }
-	    free(orig);
-	  }else{
-	    
-	    tmp0=getMap(tmp1,"rangeMin");
-	    if(tmp0!=NULL){
-	      nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
-	      xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
-	      xmlAddChild(nc8,nc7);
-	    }else{
-	      nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
-	      xmlAddChild(nc8,nc7);
-	    }
-	    tmp0=getMap(tmp1,"rangeMax");
-	    if(tmp0!=NULL){
-	      nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
-	      xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
-	      xmlAddChild(nc8,nc7);
-	    }else{
-	      nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
-	      xmlAddChild(nc8,nc7);
-	    }
-	    tmp0=getMap(tmp1,"rangeSpacing");
-	    if(tmp0!=NULL){
-	      nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
-	      xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
-	      xmlAddChild(nc8,nc7);
-	    }
-	    tmp0=getMap(tmp1,"rangeClosure");
-	    if(tmp0!=NULL){
-	      const char *tmp="closed";
-	      if(strcasecmp(tmp0->value,"co")==0)
-		tmp="closed-open";
-	      else
-		if(strcasecmp(tmp0->value,"oc")==0)
-		  tmp="open-closed";
-		else
-		  if(strcasecmp(tmp0->value,"o")==0)
-		    tmp="open";
-	      xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
-	    }else
-	      xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST "closed");
-	  }
-	  if(_tmp0==NULL){
-	    xmlAddChild(nc6,nc8);
-	    _tmp0=e->supported;
-	    if(_tmp0!=NULL &&
-	       (getMap(_tmp0->content,"range")!=NULL ||
-		getMap(_tmp0->content,"rangeMin")!=NULL ||
-		getMap(_tmp0->content,"rangeMax")!=NULL ||
-		getMap(_tmp0->content,"rangeClosure")!=NULL )){
-	      tmp1=_tmp0->content;
-	      goto doRange;
-	    }
-	  }else{
-	    _tmp0=_tmp0->next;
-	    if(_tmp0!=NULL){
-	      xmlAddChild(nc6,nc8);
-	      if(getMap(_tmp0->content,"range")!=NULL ||
-		 getMap(_tmp0->content,"rangeMin")!=NULL ||
-		 getMap(_tmp0->content,"rangeMax")!=NULL ||
-		 getMap(_tmp0->content,"rangeClosure")!=NULL ){
-		tmp1=_tmp0->content;
-		goto doRange;
-	      }
-	    }
-	  }
-	  xmlAddChild(nc6,nc8);
-	  if(vid==0)
-	    xmlAddChild(nc3,nc6);
-	  else
-	    xmlAddChild(nc5,nc6);
-	  isAnyValue=-1;
-	}
-	
-      }
-      
-      int oI=0;
-      /*if(vid==0)*/ {
-	for(oI=0;oI<13;oI++)
-	  if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
-#ifdef DEBUG
-	    printf("DATATYPE DEFAULT ? %s\n",tmp1->name);
-#endif
-	    if(strcmp(tmp1->name,"asReference")!=0 &&
-	       strncasecmp(tmp1->name,"DataType",8)!=0 &&
-	       strcasecmp(tmp1->name,"extension")!=0 &&
-	       strcasecmp(tmp1->name,"value")!=0 &&
-	       strcasecmp(tmp1->name,"AllowedValues")!=0 &&
-	       strncasecmp(tmp1->name,"range",5)!=0){
-	      if(datatype!=1){
-		char *tmp2=zCapitalize1(tmp1->name);
-		nc9 = xmlNewNode(NULL, BAD_CAST tmp2);
-		free(tmp2);
-	      }
-	      else{
-		char *tmp2=zCapitalize(tmp1->name);
-		nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
-		free(tmp2);
-	      }
-	      xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
-	      if(vid==0 || oI>=3){
-		if(vid==0 || oI!=4)
-		  xmlAddChild(nc5,nc9);
-		if(oI==4 && vid==1){
-		  xmlNewProp(nc9,BAD_CAST "default",BAD_CAST "true");
-		}
-	      }
-	      else
-		xmlFree(nc9);
-	      if(strcasecmp(tmp1->name,"uom")==0)
-		hasUOM1=true;
-	      hasUOM=true;
-	    }else 	  
-	      tmp1=tmp1->next;
-	  }
-      }
-    
-      if(datatype!=2){
-	if(hasUOM==true){
-	  if(vid==0){
-	    xmlAddChild(nc4,nc5);
+	  if(vid==1){
+	    nc4 = xmlNewNode(ns1, BAD_CAST "Format");
+	    xmlNewProp(nc4,BAD_CAST "mimeType",BAD_CAST "text/plain");
+	    xmlNewProp(nc4,BAD_CAST "default",BAD_CAST "true");
 	    xmlAddChild(nc3,nc4);
+	    nc5 = xmlNewNode(NULL, BAD_CAST "LiteralDataDomain");
+	    xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true");
 	  }
 	  else{
-	    xmlAddChild(nc3,nc5);
+	    nc4 = xmlNewNode(NULL, BAD_CAST "UOMs");
+	    nc5 = xmlNewNode(NULL, BAD_CAST "Default");
 	  }
-	}else{
-	  if(hasUOM1==false && vid==0){
-	    xmlFreeNode(nc5);
-	    if(datatype==1)
-	      xmlFreeNode(nc4);
-	  }
-	  else
-	    xmlAddChild(nc3,nc5);
-	}
-      }else{
-	xmlAddChild(nc3,nc5);
-      }
-      
-      if(datatype!=1 && default1<0){
-	xmlFreeNode(nc5);
-	if(datatype!=2)
-	  xmlFreeNode(nc4);
-      }
-
-
-      if((isInput || vid==1) && datatype==1 &&
-	 getMap(_tmp->content,"AllowedValues")==NULL &&
-	 getMap(_tmp->content,"range")==NULL &&
-	 getMap(_tmp->content,"rangeMin")==NULL &&
-	 getMap(_tmp->content,"rangeMax")==NULL &&
-	 getMap(_tmp->content,"rangeClosure")==NULL ){
-	tmp1=getMap(_tmp->content,"dataType");
-	// We were tempted to define default value for boolean as {true,false}
-	if(tmp1!=NULL && strcasecmp(tmp1->value,"boolean")==0){
-	  nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
-	  nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
-	  xmlAddChild(nc7,xmlNewText(BAD_CAST "true"));
-	  xmlAddChild(nc6,nc7);
-	  nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
-	  xmlAddChild(nc7,xmlNewText(BAD_CAST "false"));
-	  xmlAddChild(nc6,nc7);
+	}
+	else if(strcmp(e->format,"BoundingBoxOutput")==0 ||
+		strcmp(e->format,"BoundingBoxData")==0){
+	  datatype=2;
+	  nc5 = xmlNewNode(NULL, BAD_CAST "Default");
+	}
+	else{
 	  if(vid==0)
-	    xmlAddChild(nc3,nc6);
-	  else
-	    xmlAddChild(nc5,nc6);
-	}
-	else
-	if(vid==0)
-	  xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
-	else
-	  xmlAddChild(nc5,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
-      }
-
-      if(vid==1){
-	if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){
-	  nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType");
-	  xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value));
-	  char tmp[1024];
-	  sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
-	  xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
-	  if(vid==0)
-	    xmlAddChild(nc3,nc8);
-	  else
-	    xmlAddChild(nc5,nc8);
-	  datatype=1;
-	}
-	if(hasUOM==true){
-	  tmp1=getMap(_tmp->content,"uom");
-	  if(tmp1!=NULL){
-	    char *tmp2=zCapitalize(tmp1->name);
-	    nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
-	    free(tmp2);
-	    //xmlNewProp(nc9, BAD_CAST "default", BAD_CAST "true");
-	    xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
-	    xmlAddChild(nc5,nc9);
-	    /*struct iotype * _ltmp=e->supported;
-	    while(_ltmp!=NULL){
-	      tmp1=getMap(_ltmp->content,"uom");
-	      if(tmp1!=NULL){
-		char *tmp2=zCapitalize(tmp1->name);
-		nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
-		free(tmp2);
-		xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
-		xmlAddChild(nc5,nc9);
-	      }
-	      _ltmp=_ltmp->next;
-	      }*/
-	    
-	  }
-	}
-	if(e->defaults!=NULL && (tmp1=getMap(e->defaults->content,"value"))!=NULL){
-	  nc7 = xmlNewNode(ns_ows, BAD_CAST "DefaultValue");
-	  xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
-	  xmlAddChild(nc5,nc7);
-	}
-      }
-
-      map* metadata=e->metadata;
-      xmlNodePtr n=NULL;
-      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;
-      }
-
-    }
-
-    _tmp=e->supported;
-    if(_tmp==NULL && datatype!=1)
-      _tmp=e->defaults;
-
-    int hasSupported=-1;
-
-    while(_tmp!=NULL){
-      if(hasSupported<0){
-	if(datatype==0){
-	  if(vid==0)
-	    nc4 = xmlNewNode(NULL, BAD_CAST "Supported");
+	    nc4 = xmlNewNode(NULL, BAD_CAST "Default");
 	  nc5 = xmlNewNode(ns1, BAD_CAST "Format");
 	  if(vid==1){
+	    xmlNewProp(nc5,BAD_CAST "default",BAD_CAST "true");
 	    int oI=0;
 	    for(oI=0;oI<3;oI++)
@@ -1306,124 +1006,481 @@
 	  }
 	}
-	else
-	  if(vid==0)
-	    nc5 = xmlNewNode(NULL, BAD_CAST "Supported");
-	hasSupported=0;
-      }else
-	if(datatype==0){
-	  nc5 = xmlNewNode(ns1, BAD_CAST "Format");
-	  if(vid==1){
-	    int oI=0;
-	    for(oI=0;oI<3;oI++)
-	      if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
-		xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value);
+      
+	tmp1=_tmp->content;
+
+	if(vid==0)
+	  if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){
+	    nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType");
+	    xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value));
+	    char tmp[1024];
+	    sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
+	    xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
+	    if(vid==0)
+	      xmlAddChild(nc3,nc8);
+	    else
+	      xmlAddChild(nc5,nc8);
+	    datatype=1;
+	  }
+
+	bool isInput=false;
+	if(strncmp(type,"Input",5)==0 || strncmp(type,"wps:Input",9)==0){
+	  isInput=true;
+	  if((tmp1=getMap(_tmp->content,"AllowedValues"))!=NULL){
+	    nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
+	    char *token,*saveptr1;
+	    token=strtok_r(tmp1->value,",",&saveptr1);
+	    while(token!=NULL){
+	      nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
+	      char *tmps=strdup(token);
+	      tmps[strlen(tmps)]=0;
+	      xmlAddChild(nc7,xmlNewText(BAD_CAST tmps));
+	      free(tmps);
+	      xmlAddChild(nc6,nc7);
+	      token=strtok_r(NULL,",",&saveptr1);
+	    }
+	    if(getMap(_tmp->content,"range")!=NULL ||
+	       getMap(_tmp->content,"rangeMin")!=NULL ||
+	       getMap(_tmp->content,"rangeMax")!=NULL ||
+	       getMap(_tmp->content,"rangeClosure")!=NULL )
+	      goto doRange;
+	    if(vid==0)
+	      xmlAddChild(nc3,nc6);
+	    else
+	      xmlAddChild(nc5,nc6);
+	    isAnyValue=-1;
+	  }
+
+	  tmp1=getMap(_tmp->content,"range");
+	  if(tmp1==NULL)
+	    tmp1=getMap(_tmp->content,"rangeMin");
+	  if(tmp1==NULL)
+	    tmp1=getMap(_tmp->content,"rangeMax");
+	
+	  if(tmp1!=NULL && isAnyValue==1){
+	    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,"range");
+	    if(tmp0!=NULL){
+	      char* pToken;
+	      char* orig=zStrdup(tmp0->value);
+	      /**
+	       * RangeClosure: Table 47 OGC Web Services Common Standard
+	       */
+	      const 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");
+		  strncpy( tmpStr, pToken+1, strlen(pToken)-1 );
+		  tmpStr[strlen(pToken)-1] = '\0';
+		}else{
+		  nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
+		  const char* bkt;
+		  if ( ( bkt = strchr(pToken, '[') ) != NULL || ( bkt = strchr(pToken, ']') ) != NULL ){
+		    strncpy( tmpStr, pToken, bkt - pToken );
+		    tmpStr[bkt - pToken] = '\0';
+		  }
+		}
+		xmlAddChild(nc7,xmlNewText(BAD_CAST tmpStr));
+		free(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);
 	      }
-	  }
-	}
-      tmp1=_tmp->content;
-      int oI=0;
-      for(oI=0;oI<6;oI++)
-	if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
-#ifdef DEBUG
-	  printf("DATATYPE SUPPORTED ? %s\n",tmp1->name);
-#endif
-	  if(strcmp(tmp1->name,"asReference")!=0 && 
-	     strcmp(tmp1->name,"value")!=0 && 
-	     strcmp(tmp1->name,"DataType")!=0 &&
-	     strcasecmp(tmp1->name,"extension")!=0){
-	    if(datatype!=1){
-	      char *tmp2=zCapitalize1(tmp1->name);
-	      nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
-	      free(tmp2);
+	      free(orig);
+	    }else{
+	    
+	      tmp0=getMap(tmp1,"rangeMin");
+	      if(tmp0!=NULL){
+		nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
+		xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
+		xmlAddChild(nc8,nc7);
+	      }else{
+		nc7 = xmlNewNode(ns_ows, BAD_CAST "MinimumValue");
+		xmlAddChild(nc8,nc7);
+	      }
+	      tmp0=getMap(tmp1,"rangeMax");
+	      if(tmp0!=NULL){
+		nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
+		xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
+		xmlAddChild(nc8,nc7);
+	      }else{
+		nc7 = xmlNewNode(ns_ows, BAD_CAST "MaximumValue");
+		xmlAddChild(nc8,nc7);
+	      }
+	      tmp0=getMap(tmp1,"rangeSpacing");
+	      if(tmp0!=NULL){
+		nc7 = xmlNewNode(ns_ows, BAD_CAST "Spacing");
+		xmlAddChild(nc7,xmlNewText(BAD_CAST tmp0->value));
+		xmlAddChild(nc8,nc7);
+	      }
+	      tmp0=getMap(tmp1,"rangeClosure");
+	      if(tmp0!=NULL){
+		const char *tmp="closed";
+		if(strcasecmp(tmp0->value,"co")==0)
+		  tmp="closed-open";
+		else
+		  if(strcasecmp(tmp0->value,"oc")==0)
+		    tmp="open-closed";
+		  else
+		    if(strcasecmp(tmp0->value,"o")==0)
+		      tmp="open";
+		xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST tmp);
+	      }else
+		xmlNewNsProp(nc8,ns_ows,BAD_CAST "rangeClosure",BAD_CAST "closed");
 	    }
-	    else{
-	      char *tmp2=zCapitalize(tmp1->name);
-	      nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
-	      free(tmp2);
-	    }
-	    if(datatype==2){
-	      char *tmpv,*tmps;
-	      tmps=strtok_r(tmp1->value,",",&tmpv);
-	      while(tmps){
-		xmlAddChild(nc6,xmlNewText(BAD_CAST tmps));
-		tmps=strtok_r(NULL,",",&tmpv);
-		if(tmps){
-		  char *tmp2=zCapitalize1(tmp1->name);
-		  nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
-		  free(tmp2);
+	    if(_tmp0==NULL){
+	      xmlAddChild(nc6,nc8);
+	      _tmp0=e->supported;
+	      if(_tmp0!=NULL &&
+		 (getMap(_tmp0->content,"range")!=NULL ||
+		  getMap(_tmp0->content,"rangeMin")!=NULL ||
+		  getMap(_tmp0->content,"rangeMax")!=NULL ||
+		  getMap(_tmp0->content,"rangeClosure")!=NULL )){
+		tmp1=_tmp0->content;
+		goto doRange;
+	      }
+	    }else{
+	      _tmp0=_tmp0->next;
+	      if(_tmp0!=NULL){
+		xmlAddChild(nc6,nc8);
+		if(getMap(_tmp0->content,"range")!=NULL ||
+		   getMap(_tmp0->content,"rangeMin")!=NULL ||
+		   getMap(_tmp0->content,"rangeMax")!=NULL ||
+		   getMap(_tmp0->content,"rangeClosure")!=NULL ){
+		  tmp1=_tmp0->content;
+		  goto doRange;
 		}
 	      }
 	    }
+	    xmlAddChild(nc6,nc8);
+	    if(vid==0)
+	      xmlAddChild(nc3,nc6);
+	    else
+	      xmlAddChild(nc5,nc6);
+	    isAnyValue=-1;
+	  }
+	
+	}
+      
+	int oI=0;
+	/*if(vid==0)*/ {
+	  for(oI=0;oI<13;oI++)
+	    if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
+#ifdef DEBUG
+	      printf("DATATYPE DEFAULT ? %s\n",tmp1->name);
+#endif
+	      if(strcmp(tmp1->name,"asReference")!=0 &&
+		 strncasecmp(tmp1->name,"DataType",8)!=0 &&
+		 strcasecmp(tmp1->name,"extension")!=0 &&
+		 strcasecmp(tmp1->name,"value")!=0 &&
+		 strcasecmp(tmp1->name,"AllowedValues")!=0 &&
+		 strncasecmp(tmp1->name,"range",5)!=0){
+		if(datatype!=1){
+		  char *tmp2=zCapitalize1(tmp1->name);
+		  nc9 = xmlNewNode(NULL, BAD_CAST tmp2);
+		  free(tmp2);
+		}
+		else{
+		  char *tmp2=zCapitalize(tmp1->name);
+		  nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
+		  free(tmp2);
+		}
+		xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
+		if(vid==0 || oI>=3){
+		  if(vid==0 || oI!=4)
+		    xmlAddChild(nc5,nc9);
+		  if(oI==4 && vid==1){
+		    xmlNewProp(nc9,BAD_CAST "default",BAD_CAST "true");
+		  }
+		}
+		else
+		  xmlFree(nc9);
+		if(strcasecmp(tmp1->name,"uom")==0)
+		  hasUOM1=true;
+		hasUOM=true;
+	      }else 	  
+		tmp1=tmp1->next;
+	    }
+	}
+    
+	if(datatype!=2){
+	  if(hasUOM==true){
+	    if(vid==0){
+	      xmlAddChild(nc4,nc5);
+	      xmlAddChild(nc3,nc4);
+	    }
 	    else{
-	      xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
+	      xmlAddChild(nc3,nc5);
 	    }
-	    if(vid==0 || oI>=3){
-	      if(vid==0 || oI!=4)
-		xmlAddChild(nc5,nc6);
+	  }else{
+	    if(hasUOM1==false && vid==0){
+	      xmlFreeNode(nc5);
+	      if(datatype==1)
+		xmlFreeNode(nc4);
+	    }
+	    else
+	      xmlAddChild(nc3,nc5);
+	  }
+	}else{
+	  xmlAddChild(nc3,nc5);
+	}
+      
+	if(datatype!=1 && default1<0){
+	  xmlFreeNode(nc5);
+	  if(datatype!=2)
+	    xmlFreeNode(nc4);
+	}
+
+
+	if((isInput || vid==1) && datatype==1 &&
+	   getMap(_tmp->content,"AllowedValues")==NULL &&
+	   getMap(_tmp->content,"range")==NULL &&
+	   getMap(_tmp->content,"rangeMin")==NULL &&
+	   getMap(_tmp->content,"rangeMax")==NULL &&
+	   getMap(_tmp->content,"rangeClosure")==NULL ){
+	  tmp1=getMap(_tmp->content,"dataType");
+	  // We were tempted to define default value for boolean as {true,false}
+	  if(tmp1!=NULL && strcasecmp(tmp1->value,"boolean")==0){
+	    nc6 = xmlNewNode(ns_ows, BAD_CAST "AllowedValues");
+	    nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
+	    xmlAddChild(nc7,xmlNewText(BAD_CAST "true"));
+	    xmlAddChild(nc6,nc7);
+	    nc7 = xmlNewNode(ns_ows, BAD_CAST "Value");
+	    xmlAddChild(nc7,xmlNewText(BAD_CAST "false"));
+	    xmlAddChild(nc6,nc7);
+	    if(vid==0)
+	      xmlAddChild(nc3,nc6);
+	    else
+	      xmlAddChild(nc5,nc6);
+	  }
+	  else
+	    if(vid==0)
+	      xmlAddChild(nc3,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
+	    else
+	      xmlAddChild(nc5,xmlNewNode(ns_ows, BAD_CAST "AnyValue"));
+	}
+
+	if(vid==1){
+	  if((tmp1=getMap(_tmp->content,"DataType"))!=NULL){
+	    nc8 = xmlNewNode(ns_ows, BAD_CAST "DataType");
+	    xmlAddChild(nc8,xmlNewText(BAD_CAST tmp1->value));
+	    char tmp[1024];
+	    sprintf(tmp,"http://www.w3.org/TR/xmlschema-2/#%s",tmp1->value);
+	    xmlNewNsProp(nc8,ns_ows,BAD_CAST "reference",BAD_CAST tmp);
+	    if(vid==0)
+	      xmlAddChild(nc3,nc8);
+	    else
+	      xmlAddChild(nc5,nc8);
+	    datatype=1;
+	  }
+	  if(hasUOM==true){
+	    tmp1=getMap(_tmp->content,"uom");
+	    if(tmp1!=NULL){
+	      char *tmp2=zCapitalize(tmp1->name);
+	      nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
+	      free(tmp2);
+	      //xmlNewProp(nc9, BAD_CAST "default", BAD_CAST "true");
+	      xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
+	      xmlAddChild(nc5,nc9);
+	      /*struct iotype * _ltmp=e->supported;
+		while(_ltmp!=NULL){
+		tmp1=getMap(_ltmp->content,"uom");
+		if(tmp1!=NULL){
+		char *tmp2=zCapitalize(tmp1->name);
+		nc9 = xmlNewNode(ns_ows, BAD_CAST tmp2);
+		free(tmp2);
+		xmlAddChild(nc9,xmlNewText(BAD_CAST tmp1->value));
+		xmlAddChild(nc5,nc9);
+		}
+		_ltmp=_ltmp->next;
+		}*/
+	    
+	    }
+	  }
+	  if(e->defaults!=NULL && (tmp1=getMap(e->defaults->content,"value"))!=NULL){
+	    nc7 = xmlNewNode(ns_ows, BAD_CAST "DefaultValue");
+	    xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
+	    xmlAddChild(nc5,nc7);
+	  }
+	}
+
+	map* metadata=e->metadata;
+	xmlNodePtr n=NULL;
+	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;
+	}
+
+      }
+
+      _tmp=e->supported;
+      if(_tmp==NULL && datatype!=1)
+	_tmp=e->defaults;
+
+      int hasSupported=-1;
+
+      while(_tmp!=NULL){
+	if(hasSupported<0){
+	  if(datatype==0){
+	    if(vid==0)
+	      nc4 = xmlNewNode(NULL, BAD_CAST "Supported");
+	    nc5 = xmlNewNode(ns1, BAD_CAST "Format");
+	    if(vid==1){
+	      int oI=0;
+	      for(oI=0;oI<3;oI++)
+		if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
+		  xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value);
+		}
+	    }
+	  }
+	  else
+	    if(vid==0)
+	      nc5 = xmlNewNode(NULL, BAD_CAST "Supported");
+	  hasSupported=0;
+	}else
+	  if(datatype==0){
+	    nc5 = xmlNewNode(ns1, BAD_CAST "Format");
+	    if(vid==1){
+	      int oI=0;
+	      for(oI=0;oI<3;oI++)
+		if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
+		  xmlNewProp(nc5,BAD_CAST orderedFields[oI],BAD_CAST tmp1->value);
+		}
+	    }
+	  }
+	tmp1=_tmp->content;
+	int oI=0;
+	for(oI=0;oI<6;oI++)
+	  if((tmp1=getMap(_tmp->content,orderedFields[oI]))!=NULL){
+#ifdef DEBUG
+	    printf("DATATYPE SUPPORTED ? %s\n",tmp1->name);
+#endif
+	    if(strcmp(tmp1->name,"asReference")!=0 && 
+	       strcmp(tmp1->name,"value")!=0 && 
+	       strcmp(tmp1->name,"DataType")!=0 &&
+	       strcasecmp(tmp1->name,"extension")!=0){
+	      if(datatype!=1){
+		char *tmp2=zCapitalize1(tmp1->name);
+		nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
+		free(tmp2);
+	      }
+	      else{
+		char *tmp2=zCapitalize(tmp1->name);
+		nc6 = xmlNewNode(ns_ows, BAD_CAST tmp2);
+		free(tmp2);
+	      }
+	      if(datatype==2){
+		char *tmpv,*tmps;
+		tmps=strtok_r(tmp1->value,",",&tmpv);
+		while(tmps){
+		  xmlAddChild(nc6,xmlNewText(BAD_CAST tmps));
+		  tmps=strtok_r(NULL,",",&tmpv);
+		  if(tmps){
+		    char *tmp2=zCapitalize1(tmp1->name);
+		    nc6 = xmlNewNode(NULL, BAD_CAST tmp2);
+		    free(tmp2);
+		  }
+		}
+	      }
+	      else{
+		xmlAddChild(nc6,xmlNewText(BAD_CAST tmp1->value));
+	      }
+	      if(vid==0 || oI>=3){
+		if(vid==0 || oI!=4)
+		  xmlAddChild(nc5,nc6);
+		else
+		  xmlFree(nc6);
+	      }
 	      else
 		xmlFree(nc6);
 	    }
-	    else
-	      xmlFree(nc6);
+	    tmp1=tmp1->next;
 	  }
-	  tmp1=tmp1->next;
-	}
-      if(hasSupported<=0){
-	if(datatype==0){
-	  if(vid==0){
-	    xmlAddChild(nc4,nc5);
-	    xmlAddChild(nc3,nc4);
+	if(hasSupported<=0){
+	  if(datatype==0){
+	    if(vid==0){
+	      xmlAddChild(nc4,nc5);
+	      xmlAddChild(nc3,nc4);
+	    }
+	    else{
+	      xmlAddChild(nc3,nc5);
+	    }
+
+	  }else{
+	    if(datatype!=1)
+	      xmlAddChild(nc3,nc5);
 	  }
-	  else{
-	    xmlAddChild(nc3,nc5);
+	  hasSupported=1;
+	}
+	else
+	  if(datatype==0){
+	    if(vid==0){
+	      xmlAddChild(nc4,nc5);
+	      xmlAddChild(nc3,nc4);
+	    }
+	    else{
+	      xmlAddChild(nc3,nc5);
+	    }
 	  }
-
-	}else{
-	  if(datatype!=1)
-	    xmlAddChild(nc3,nc5);
-	}
-	hasSupported=1;
-      }
-      else
-	if(datatype==0){
-	  if(vid==0){
-	    xmlAddChild(nc4,nc5);
-	    xmlAddChild(nc3,nc4);
-	  }
-	  else{
-	    xmlAddChild(nc3,nc5);
-	  }
-	}
-	else
-	  if(datatype!=1)
-	    xmlAddChild(nc3,nc5);
-
-      _tmp=_tmp->next;
-    }
-
-    if(hasSupported==0){
-      if(datatype==0 && vid!=0)
-	xmlFreeNode(nc4);
-      xmlFreeNode(nc5);
-    }
-
-    _tmp=e->defaults;
-    if(datatype==1 && hasUOM1==true){
-      if(vid==0){
-	xmlAddChild(nc4,nc5);
-	xmlAddChild(nc3,nc4);
-      }
-      else{
-	xmlAddChild(nc3,nc5);
-      }
-    }
-
-    if(vid==0 && _tmp!=NULL && (tmp1=getMap(_tmp->content,"value"))!=NULL){
-      nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue");
-      xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
-      xmlAddChild(nc3,nc7);
-    }
+	  else
+	    if(datatype!=1)
+	      xmlAddChild(nc3,nc5);
+
+	_tmp=_tmp->next;
+      }
+
+      if(hasSupported==0){
+	if(datatype==0 && vid!=0)
+	  xmlFreeNode(nc4);
+	xmlFreeNode(nc5);
+      }
+
+      _tmp=e->defaults;
+      if(datatype==1 && hasUOM1==true){
+	if(vid==0){
+	  xmlAddChild(nc4,nc5);
+	  xmlAddChild(nc3,nc4);
+	}
+	else{
+	  xmlAddChild(nc3,nc5);
+	}
+      }
+
+      if(vid==0 && _tmp!=NULL && (tmp1=getMap(_tmp->content,"value"))!=NULL){
+	nc7 = xmlNewNode(NULL, BAD_CAST "DefaultValue");
+	xmlAddChild(nc7,xmlNewText(BAD_CAST tmp1->value));
+	xmlAddChild(nc3,nc7);
+      }
     
-    xmlAddChild(nc2,nc3);
+      xmlAddChild(nc2,nc3);
+    }
     
     xmlAddChild(nc1,nc2);
Index: trunk/zoo-project/zoo-kernel/response_print.h
===================================================================
--- trunk/zoo-project/zoo-kernel/response_print.h	(revision 675)
+++ trunk/zoo-project/zoo-kernel/response_print.h	(revision 676)
@@ -143,7 +143,7 @@
    * Definitions of schemas depending on the WPS version
    */
-  static const char* schemas[2][7]={
+  static const char* schemas[2][8]={
     {"1.0.0","http://www.opengis.net/ows/1.1","http://www.opengis.net/wps/1.0.0","http://schemas.opengis.net/wps/1.0.0","%s %s/wps%s_response.xsd","http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd","1.1.0"},
-    {"2.0.0","http://www.opengis.net/ows/2.0","http://www.opengis.net/wps/2.0","http://schemas.opengis.net/wps/2.0","%s %s/wps%s.xsd","http://schemas.opengis.net/ows/2.0/owsExceptionReport.xsd","2.0.2"},
+    {"2.0.0","http://www.opengis.net/ows/2.0","http://www.opengis.net/wps/2.0","http://schemas.opengis.net/wps/2.0","http://www.opengis.net/wps/2.0 http://schemas.opengis.net/wps/2.0/wps.xsd","http://schemas.opengis.net/ows/2.0/owsExceptionReport.xsd","2.0.2","http://www.opengis.net/spec/wps/2.0/def/process-profile/"},
   };
   /**
@@ -208,6 +208,6 @@
   xmlNodePtr printWPSHeader(xmlDocPtr,maps*,const char*,const char*,const char*,int);
   xmlNodePtr printGetCapabilitiesHeader(xmlDocPtr,maps*,const char*);
-  void printGetCapabilitiesForProcess(maps*,xmlNodePtr,service*);
-  void printDescribeProcessForProcess(maps*,xmlNodePtr,service*);
+  void printGetCapabilitiesForProcess(registry*,maps*,xmlNodePtr,service*);
+  void printDescribeProcessForProcess(registry*,maps*,xmlNodePtr,service*);
   void printFullDescription(int,elements*,const char*,xmlNsPtr,xmlNsPtr,xmlNodePtr,int);
   void printDocument(maps*,xmlDocPtr,int);
Index: trunk/zoo-project/zoo-kernel/server_internal.c
===================================================================
--- trunk/zoo-project/zoo-kernel/server_internal.c	(revision 675)
+++ trunk/zoo-project/zoo-kernel/server_internal.c	(revision 676)
@@ -966,5 +966,6 @@
 	  sprintf(fileName,"%s/%s",r_inputs->value,dp->d_name);
 	  if(unlink(fileName)!=0){
-	    errorException (conf, _("The job cannot be removed, a file cannot be removed"),
+	    errorException (conf, 
+			    _("The job cannot be removed, a file cannot be removed"),
 			    "NoApplicableCode", NULL);
 	    return;
@@ -983,2 +984,107 @@
   return;
 }
+
+extern int getServiceFromFile (maps *, const char *, service **);
+
+/**
+ * Parse the service file using getServiceFromFile or use getServiceFromYAML
+ * if YAML support was activated.
+ *
+ * @param conf the conf maps containing the main.cfg settings
+ * @param file the file name to parse
+ * @param service the service to update witht the file content
+ * @param name the service name
+ * @return true if the file can be parsed or false
+ * @see getServiceFromFile, getServiceFromYAML
+ */
+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;
+}
+
+/**
+ * Create the profile registry.
+ *
+ * The profile registry is optional (created only if the registry key is
+ * available in the [main] section of the main.cfg file) and can be used to
+ * store the profiles hierarchy. The registry is a directory which should
+ * contain the following sub-directories: 
+ *  * concept: direcotry containing .html files describing concept
+ *  * generic: directory containing .zcfg files for wps:GenericProcess
+ *  * implementation: directory containing .zcfg files for wps:Process
+ *
+ * @param m the conf maps containing the main.cfg settings
+ * @param r the registry to update
+ * @param reg_dir the resgitry 
+ * @return 0 if the resgitry is null or was correctly updated, -1 on failure
+ */
+int createRegistry (maps* m,registry ** r, char *reg_dir)
+{
+  char registryKeys[3][15]={
+    "concept",
+    "generic",
+    "implementation"
+  };
+  int scount = 0,i=0;
+  if (reg_dir == NULL)
+    return 0;
+  for(i=0;i<3;i++){
+    char * tmpName =
+      (char *) malloc ((strlen (reg_dir) + strlen (registryKeys[i]) + 2) *
+		       sizeof (char));
+    sprintf (tmpName, "%s/%s", reg_dir, registryKeys[i]);
+    
+    DIR *dirp1 = opendir (tmpName);
+    struct dirent *dp1;
+    while ((dp1 = readdir (dirp1)) != NULL){
+      char* extn = strstr(dp1->d_name, ".zcfg");
+      if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
+	{
+	  int t;
+	  char *tmps1=
+	    (char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) *
+			     sizeof (char));
+	  sprintf (tmps1, "%s/%s", tmpName, dp1->d_name);
+	  char *tmpsn = zStrdup (dp1->d_name);
+	  tmpsn[strlen (tmpsn) - 5] = 0;
+	  service* s1 = (service *) malloc (SERVICE_SIZE);
+	  if (s1 == NULL)
+	    {
+	      setMapInMaps(m,"lenv","message",_("Unable to allocate memory."));
+	      setMapInMaps(m,"lenv","type","InternalError");
+	      return -2;
+	    }
+	  t = readServiceFile (m, tmps1, &s1, tmpsn);
+	  free (tmpsn);
+	  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)"),
+			 dp1->d_name, tmp00->value);
+	      else
+		sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
+			 dp1->d_name);
+	      setMapInMaps(m,"lenv","message",tmp01);
+	      setMapInMaps(m,"lenv","type","InternalError");
+	      return -1;
+	    }
+	  if(strncasecmp(registryKeys[i],"implementation",14)==0){
+	    inheritance(*r,&s1);
+	  }
+	  addServiceToRegistry(r,registryKeys[i],s1);
+	  freeService (&s1);
+	  free (s1);
+	  scount++;
+	}
+    }
+    (void) closedir (dirp1);
+  }
+  return 0;
+}
Index: trunk/zoo-project/zoo-kernel/server_internal.h
===================================================================
--- trunk/zoo-project/zoo-kernel/server_internal.h	(revision 675)
+++ trunk/zoo-project/zoo-kernel/server_internal.h	(revision 676)
@@ -58,5 +58,7 @@
   
   char* getLastErrorMessage();
-  
+  int readServiceFile (maps *, char *, service **, char *);
+  int createRegistry (maps*,registry **,char *);
+
 #ifdef __cplusplus
 }
Index: trunk/zoo-project/zoo-kernel/service.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service.c	(revision 675)
+++ trunk/zoo-project/zoo-kernel/service.c	(revision 676)
@@ -1262,5 +1262,9 @@
 void inheritMap(map** out,map* in){
   map* content=in;
-  while(content!=NULL && *out!=NULL){
+  if((*out)==NULL){
+    addMapToMap(out,in);
+    return;
+  }
+  while(content!=NULL){
     map* cmap=getMap(*out,content->name);
     if(cmap==NULL)
Index: trunk/zoo-project/zoo-kernel/service_conf.y
===================================================================
--- trunk/zoo-project/zoo-kernel/service_conf.y	(revision 675)
+++ trunk/zoo-project/zoo-kernel/service_conf.y	(revision 676)
@@ -814,4 +814,7 @@
 #endif
   if(wait_outputs && current_element!=NULL && current_element->name!=NULL){
+    if(current_content!=NULL){
+      addMapToMap(&current_element->content,current_content);
+    }
     if(my_service->outputs==NULL){  
 #ifdef DEBUG_SERVICE_CONF
Index: trunk/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 675)
+++ trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 676)
@@ -141,29 +141,4 @@
 #endif
 
-extern int getServiceFromFile (maps *, const char *, service **);
-
-/**
- * Parse the service file using getServiceFromFile or use getServiceFromYAML
- * if YAML support was activated.
- *
- * @param conf the conf maps containing the main.cfg settings
- * @param file the file name to parse
- * @param service the service to update witht the file content
- * @param name the service name
- * @return true if the file can be parsed or false
- * @see getServiceFromFile, getServiceFromYAML
- */
-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;
-}
 
 /**
@@ -185,95 +160,4 @@
 }
 
-
-/**
- * Create the profile registry.
- *
- * The profile registry is optional (created only if the registry key is
- * available in the [main] section of the main.cfg file) and can be used to
- * store the profiles hierarchy. The registry is a directory which should
- * contain the following sub-directories: 
- *  * concept: direcotry containing .html files describing concept
- *  * generic: directory containing .zcfg files for wps:GenericProcess
- *  * implementation: directory containing .zcfg files for wps:Process
- *
- * @param m the conf maps containing the main.cfg settings
- * @param r the registry to update
- * @param reg_dir the resgitry 
- * @param saved_stdout the saved stdout identifier
- * @return 0 if the resgitry is null or was correctly updated, -1 on failure
- */
-int
-createRegistry (maps* m,registry ** r, char *reg_dir, int saved_stdout)
-{
-  char registryKeys[3][15]={
-    "concept",
-    "generic",
-    "implementation"
-  };
-  int scount = 0,i=0;
-  if (reg_dir == NULL)
-    return 0;
-  for(i=0;i<3;i++){
-    char * tmpName =
-      (char *) malloc ((strlen (reg_dir) + strlen (registryKeys[i]) + 2) *
-		       sizeof (char));
-    sprintf (tmpName, "%s/%s", reg_dir, registryKeys[i]);
-    
-    DIR *dirp1 = opendir (tmpName);
-    struct dirent *dp1;
-    while ((dp1 = readdir (dirp1)) != NULL){
-      char* extn = strstr(dp1->d_name, ".zcfg");
-      if(dp1->d_name[0] != '.' && extn != NULL && strlen(extn) == 5)
-	{
-	  int t;
-	  char *tmps1=
-	    (char *) malloc ((strlen (tmpName) + strlen (dp1->d_name) + 2) *
-			     sizeof (char));
-	  sprintf (tmps1, "%s/%s", tmpName, dp1->d_name);
-	  char *tmpsn = zStrdup (dp1->d_name);
-	  tmpsn[strlen (tmpsn) - 5] = 0;
-	  service* s1 = (service *) malloc (SERVICE_SIZE);
-	  if (s1 == NULL)
-	    {
-	      dup2 (saved_stdout, fileno (stdout));
-	      errorException (m, _("Unable to allocate memory."),
-			      "InternalError", NULL);
-	      return -1;
-	    }
-	  t = readServiceFile (m, tmps1, &s1, tmpsn);
-	  free (tmpsn);
-	  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)"),
-			 dp1->d_name, tmp00->value);
-	      else
-		sprintf (tmp01, _("Unable to parse the ZCFG file: %s."),
-			 dp1->d_name);
-	      dup2 (saved_stdout, fileno (stdout));
-	      errorException (m, tmp01, "InternalError", NULL);
-	      return -1;
-	    }
-#ifdef DEBUG
-	  dumpService (s1);
-	  fflush (stdout);
-	  fflush (stderr);
-#endif
-	  if(strncasecmp(registryKeys[i],"implementation",14)==0){
-	    inheritance(*r,&s1);
-	  }
-	  addServiceToRegistry(r,registryKeys[i],s1);
-	  freeService (&s1);
-	  free (s1);
-	  scount++;
-	}
-    }
-    (void) closedir (dirp1);
-  }
-  return 0;
-}
-
 /**
  * Recursivelly parse zcfg starting from the ZOO-Kernel cwd.
@@ -288,10 +172,12 @@
  * @param level the current level (number of sub-directories to reach the
  * current path)
+ * @param func a pointer to a function having 4 parameters 
+ *  (registry*, maps*, xmlNodePtr and service*).
  * @see inheritance, readServiceFile
  */
 int
-recursReaddirF (maps * m, registry *r, xmlNodePtr n, char *conf_dir, char *prefix,
-                int saved_stdout, int level, void (func) (maps *, xmlNodePtr,
-                                                          service *))
+recursReaddirF ( maps * m, registry *r, xmlNodePtr n, char *conf_dir, 
+		 char *prefix, int saved_stdout, int level, 
+		 void (func) (registry *, maps *, xmlNodePtr, service *) )
 {
   struct dirent *dp;
@@ -400,5 +286,5 @@
 #endif
 	    inheritance(r,&s1);
-            func (m, n, s1);
+            func (r, m, n, s1);
             freeService (&s1);
             free (s1);
@@ -1251,6 +1137,14 @@
     int saved_stdout = dup (fileno (stdout));
     dup2 (fileno (stderr), fileno (stdout));
-    createRegistry (m,&zooRegistry,reg->value,saved_stdout);
+    if(createRegistry (m,&zooRegistry,reg->value)<0){
+      map *message=getMapFromMaps(m,"lenv","message");
+      map *type=getMapFromMaps(m,"lenv","type");
+      dup2 (saved_stdout, fileno (stdout));
+      errorException (m, message->value,
+		      type->value, NULL);
+      return 0;
+    }
     dup2 (saved_stdout, fileno (stdout));
+    close(saved_stdout);
   }
 
@@ -1433,5 +1327,5 @@
 #endif
 			inheritance(zooRegistry,&s1);
-			printDescribeProcessForProcess (m, n, s1);
+			printDescribeProcessForProcess (zooRegistry,m, n, s1);
 			freeService (&s1);
 			free (s1);
@@ -1511,5 +1405,5 @@
 #endif
 				inheritance(zooRegistry,&s1);
-				printDescribeProcessForProcess (m, n, s1);
+				printDescribeProcessForProcess (zooRegistry,m, n, s1);
 				freeService (&s1);
 				free (s1);
@@ -2177,5 +2071,5 @@
 	  fclose (stdin);
 #endif
-
+	  fprintf(stderr,"DEBUG START %s %d \n",__FILE__,__LINE__);
 #ifdef RELY_ON_DB
 	  init_sql(m);
