Index: trunk/zoo-project/HISTORY.txt
===================================================================
--- trunk/zoo-project/HISTORY.txt	(revision 675)
+++ trunk/zoo-project/HISTORY.txt	(revision 676)
@@ -1,3 +1,4 @@
 Version 1.5.0-dev
+  * Add utils/registry service
   * Initial support for WPS 2.0.0 including the Dismiss extension
   * Fix concurrency access to status informations
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);
Index: trunk/zoo-project/zoo-services/utils/registry/Makefile
===================================================================
--- trunk/zoo-project/zoo-services/utils/registry/Makefile	(revision 676)
+++ trunk/zoo-project/zoo-services/utils/registry/Makefile	(revision 676)
@@ -0,0 +1,24 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+
+YAML_FILES=""
+ifeq ("${YAML_FILE}","")
+else
+	YAML_FILES="${ZRPATH}/zoo-kernel/${YAML_FILE}"
+endif
+
+MS_FILES=""
+ifeq ("${MS_FILE}","")
+else
+	MS_FILES="${ZRPATH}/zoo-kernel/${MS_FILE}"
+endif
+
+cgi-env/wps_registry.zo: service.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/wps_registry.zo ./service.c ${GDAL_LIBS} ${XML2LDFLAGS} ${MACOS_LD_FLAGS} ${ZOO_LDFLAGS} ${MACOS_LD_NET_FLAGS} ${XSLT_LDFLAGS} -lfcgi -lzoo_service ${ZRPATH}/zoo-kernel/server_internal.o ${ZRPATH}/zoo-kernel/lex.cr.o ${ZRPATH}/zoo-kernel/lex.sr.o ${ZRPATH}/zoo-kernel/service_conf.tab.o ${ZRPATH}/zoo-kernel/main_conf_read.tab.o ${ZRPATH}/zoo-kernel/response_print.o ${YAML_FILES} ${MS_FILES} ${MS_LDFLAGS} ${YAML_LDFLAGS}
+
+install:
+	install -d ${CGI_DIR}
+	install cgi-env/* ${CGI_DIR}/
+clean:
+	rm -f cgi-env/wps_registry.zo
Index: trunk/zoo-project/zoo-services/utils/registry/cgi-env/GetFromRegistry.zcfg
===================================================================
--- trunk/zoo-project/zoo-services/utils/registry/cgi-env/GetFromRegistry.zcfg	(revision 676)
+++ trunk/zoo-project/zoo-services/utils/registry/cgi-env/GetFromRegistry.zcfg	(revision 676)
@@ -0,0 +1,36 @@
+[GetFromRegistry]
+ Title = Provide access to the Profile Registry
+ Abstract = Return a GenericProcess, Process or simple Concept based on the profiles registry
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = wps_registry.zo
+ serviceType = C
+ <DataInputs>
+  [id]
+   Title = The registry path
+   Abstract = The profiles registry path
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    DataType = integer
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = the GenericProcess, Process or Concept
+   Abstract = The resulting GenericProcess, Process or Concept
+   <ComplexData>
+    <Default>
+     mimeType = text/xml
+     encoding = UTF-8
+     schema = http://schemas.opengis.net/wps/2.0/wps.xsd
+    </Default>
+    <Supported>
+     mimeType = text/plain
+     encoding = UTF-8
+    </Supported>
+   </ComplexData>
+ </DataOutputs>  
Index: trunk/zoo-project/zoo-services/utils/registry/makefile.vc
===================================================================
--- trunk/zoo-project/zoo-services/utils/registry/makefile.vc	(revision 676)
+++ trunk/zoo-project/zoo-services/utils/registry/makefile.vc	(revision 676)
@@ -0,0 +1,24 @@
+TROOT= $(ZOOK_DIR)
+!INCLUDE $(ZOOK_DIR)/nmake.opt
+
+FILES=$(ZOOK_DIR)/service_internal.obj $(ZOOK_DIR)/ulinet.obj
+!IFDEF JS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JS_FILE)
+!ENDIF
+!IFDEF JDK_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(JAVA_FILE)
+!ENDIF
+!IFDEF PY_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(PY_FILE)
+!ENDIF
+!IFDEF MS_DIR
+FILES=$(FILES) $(ZOOK_DIR)$(MS_FILE)
+!ENDIF
+
+cgi-env/wps_registry.zo: service.c
+	$(CPP) /D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -DZOO_SERVICE $(CFLAGS) /c service.c
+	link /dll /out:cgi-env/wps_registry.zo $(FILES) ./service.obj $(LDFLAGS) /FORCE:MULTIPLE
+
+clean:
+	erase cgi-env\*_registry.*
+	erase *.obj
Index: trunk/zoo-project/zoo-services/utils/registry/service.c
===================================================================
--- trunk/zoo-project/zoo-services/utils/registry/service.c	(revision 676)
+++ trunk/zoo-project/zoo-services/utils/registry/service.c	(revision 676)
@@ -0,0 +1,138 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2015 GeoLabs SARL. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "service.h"
+#include "service_internal.h"
+#include "server_internal.h"
+#include "response_print.h"
+
+extern "C" {
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+
+#include <dirent.h>
+
+  /**
+   * GetFromRegistry ZOO Service :
+   * This service is used in the ZOO-Project to browse the profiles registry.
+   */
+#ifdef WIN32
+  __declspec(dllexport)
+#endif
+  int GetFromRegistry(maps*& conf,maps*& inputs,maps*& outputs){
+    const char *params[4 + 1];
+    int xmlLoadExtDtdDefaultValue;
+    map* tmpMap=NULL,*tmpMmap=NULL, *tmpTmap=NULL;
+
+    map* reg = getMapFromMaps (conf, "main", "registry");
+    registry* zooRegistry=NULL;
+    if(reg!=NULL){
+      int saved_stdout = dup (fileno (stdout));
+      dup2 (fileno (stderr), fileno (stdout));
+      createRegistry (conf,&zooRegistry,reg->value);
+      dup2 (saved_stdout, fileno (stdout));
+      close(saved_stdout);
+    }else{
+      setMapInMaps(conf,"lenv","message",_ss("No registry defined"));
+      return SERVICE_FAILED;
+    }
+    tmpMap=getMapFromMaps(inputs,"id","value");
+    if(strstr(tmpMap->value,"/")==NULL){
+      setMapInMaps(conf,"lenv","message",_ss("Unable to parse your registry identifier"));
+      return SERVICE_FAILED;
+    }
+    char* tmp=zStrdup(tmpMap->value);
+    char* tmp1=zStrdup(strstr(tmpMap->value,"/")+1);
+    tmp[strlen(tmp)-strlen(tmp1)-1]=0;
+    service* inherited=getServiceFromRegistry(zooRegistry,tmp,tmp1);
+    if(inherited!=NULL){
+      dumpService(inherited);
+      xmlDocPtr doc = xmlNewDoc (BAD_CAST "1.0");
+      xmlNodePtr n = printWPSHeader(doc,conf,"DescribeProcess",
+				    root_nodes[1][1],"2.0.0",1);
+      setMapInMaps(conf,"main","rversion","2.0.0");
+      printDescribeProcessForProcess(zooRegistry,conf,n,inherited);
+      setMapInMaps(conf,"main","rversion","1.0.0");
+
+
+      xmlNodePtr n1 = xmlFirstElementChild(xmlFirstElementChild(n));
+
+
+      xmlDocPtr doc1 = xmlNewDoc (BAD_CAST "1.0");
+      int vid=1;
+      char *tmp=(char*) malloc((86+strlen("DescribeProcess")+1)*sizeof(char));
+      sprintf(tmp,schemas[vid][4],schemas[vid][2],schemas[vid][3],"DescribeProcess");
+      xmlNewProp(n1,BAD_CAST "xsi:schemaLocation",BAD_CAST tmp);
+      free(tmp);
+
+      n1->ns=xmlCopyNamespaceList(n->ns);
+      n1->nsDef=xmlCopyNamespaceList(n->nsDef);
+      
+      xmlDocSetRootElement(doc1, n1);
+      
+      xmlChar *xmlbuff;
+      int buffersize;
+      xmlDocDumpFormatMemoryEnc(doc1, &xmlbuff, &buffersize, "utf-8", 1);
+      setMapInMaps(outputs,"Result","value",(char*)xmlbuff);
+      xmlFree(xmlbuff);
+      xmlFreeDoc(doc);
+      xmlFreeDoc(doc1);
+      return SERVICE_SUCCEEDED;
+    }else{
+      if(strcasecmp(tmp,"concept")==0){
+	char *file_path=(char*)malloc((strlen(reg->value)+strlen(tmpMap->value)+5)*sizeof(char));
+	sprintf(file_path,"%s/%s.txt",reg->value,tmpMap->value);
+	FILE* f=fopen(file_path,"r");
+	if(f!=NULL){
+	  fseek(f, 0, SEEK_END);
+	  long count = ftell(f);
+	  fseek(f, 0, SEEK_SET);
+	  setMapInMaps(outputs,"Result","value","");
+	  map* tmpMap=getMapFromMaps(outputs,"Result","value");
+	  free(tmpMap->value);
+	  tmpMap->value=(char*) malloc((count+1)*sizeof(char));  
+	  fread(tmpMap->value,1,count,f);
+	  tmpMap->value[count]=0;
+	  fclose(f);
+	  setMapInMaps(outputs,"Result","mimeType","text/plain");
+	  return SERVICE_SUCCEEDED;
+	}else{
+	  setMapInMaps(conf,"lenv","message",_ss("Unable to access this item in the registry."));
+	  return SERVICE_FAILED;
+	}
+      }
+      setMapInMaps(conf,"lenv","message",_ss("Unable to access this item in the registry."));
+      return SERVICE_FAILED;
+    }
+    return SERVICE_SUCCEEDED;
+  }
+
+}
