Index: trunk/zoo-project/HISTORY.txt
===================================================================
--- trunk/zoo-project/HISTORY.txt	(revision 359)
+++ trunk/zoo-project/HISTORY.txt	(revision 360)
@@ -8,4 +8,5 @@
   * Add the Normalized Difference Vegetation Index service
   * Add importScripts function to JavaScript support (ticket #66)
+  * Add multiple inputs values for the same identifier (ticket #72)
 
 Version 1.2.0-rc3
Index: trunk/zoo-project/zoo-kernel/service.h
===================================================================
--- trunk/zoo-project/zoo-kernel/service.h	(revision 359)
+++ trunk/zoo-project/zoo-kernel/service.h	(revision 360)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- * Copyright (c) 2009-2010 GeoLabs SARL
+ * Copyright (c) 2009-2012 GeoLabs SARL
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -596,4 +596,97 @@
   }
 
+  static map* getMapArray(map* m,char* key,int index){
+    char tmp[1024];
+    if(index>0)
+      sprintf(tmp,"%s_%d",key,index);
+    else
+      sprintf(tmp,key);
+#ifdef DEBUG
+    fprintf(stderr,"** KEY %s\n",tmp);
+#endif
+    map* tmpMap=getMap(m,tmp);
+#ifdef DEBUG
+    if(tmpMap!=NULL)
+      dumpMap(tmpMap);
+#endif
+    return tmpMap;
+  }
+
+
+  static void setMapArray(map* m,char* key,int index,char* value){
+    char tmp[1024];
+    if(index>0)
+      sprintf(tmp,"%s_%d",key,index);
+    else
+      sprintf(tmp,key);
+    map* tmpSize=getMapArray(m,"size",index);
+    if(tmpSize!=NULL && strncasecmp(key,"value",5)==0){
+      fprintf(stderr,"%s\n",tmpSize->value);
+      map* ptr=getMapOrFill(m,tmp,"");
+      free(ptr->value);
+      ptr->value=(char*)malloc((atoi(tmpSize->value)+1)*sizeof(char));
+      memcpy(ptr->value,value,atoi(tmpSize->value)); 
+    }
+    else
+      addToMap(m,tmp,value);
+  }
+
+  static map* getMapType(map* mt){
+    map* tmap=getMap(mt,"mimeType");
+    if(tmap==NULL){
+      tmap=getMap(mt,"dataType");
+      if(tmap==NULL){
+	tmap=getMap(mt,"CRS");
+      }
+    }
+    dumpMap(tmap);
+    return tmap;
+  }
+
+  static int addMapsArrayToMaps(maps** mo,maps* mi,char* typ){
+    maps* tmp=mi;
+    maps* _cursor=*mo;
+    maps* tmpMaps=getMaps(_cursor,tmp->name);
+
+    if(tmpMaps==NULL)
+      return -1;
+
+    map* tmpLength=getMap(tmpMaps->content,"length");
+    char tmpLen[10];
+    int len=1;
+    if(tmpLength!=NULL){
+      len=atoi(tmpLength->value);
+    }
+
+    map* tmpValI=getMap(tmp->content,"value");
+    char *tmpV[8]={
+      "size",
+      "value",
+      "uom",
+      "Reference",
+      "xlink:href",
+      typ,
+      "schema",
+      "encoding"
+    };
+    sprintf(tmpLen,"%d",len+1);
+    addToMap(_cursor->content,"length",tmpLen);
+    int i=0;
+    map* tmpSizeI=getMap(tmp->content,tmpV[i]);
+    for(0;i<8;i++){
+      map* tmpVI=getMap(tmp->content,tmpV[i]);
+      if(tmpVI!=NULL){
+	fprintf(stderr,"%s = %s\n",tmpV[i],tmpVI->value);
+	if(i<5)
+	  setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
+	else
+	  if(strncasecmp(tmpV[5],"mimeType",8)==0)
+	    setMapArray(_cursor->content,tmpV[i],len,tmpVI->value);
+      }
+    }
+    
+    addToMap(_cursor->content,"isArray","true");
+    return 0;
+  }
 
   static void setMapInMaps(maps* m,const char* key,const char* subkey,const char *value){
Index: trunk/zoo-project/zoo-kernel/service_internal.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal.c	(revision 359)
+++ trunk/zoo-project/zoo-kernel/service_internal.c	(revision 360)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- * Copyright (c) 2009-2011 GeoLabs SARL
+ * Copyright (c) 2009-2012 GeoLabs SARL
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -2188,5 +2188,5 @@
 	map* tmpContent=tmpIoType->content;
 	map* cval=NULL;
-
+	int hasPassed=-1;
 	while(tmpContent!=NULL){
 	  if((cval=getMap(tmpMaps->content,tmpContent->name))==NULL){
@@ -2198,4 +2198,22 @@
 	    else
 	      addToMap(tmpMaps->content,tmpContent->name,tmpContent->value);
+	    
+	    if(hasPassed<0 && type==0 && getMap(tmpMaps->content,"isArray")!=NULL){
+	      map* length=getMap(tmpMaps->content,"length");
+	      int i;
+	      char *tcn=strdup(tmpContent->name);
+	      for(i=1;i<atoi(length->value);i++){
+		dumpMap(tmpMaps->content);
+		fprintf(stderr,"addDefaultValues %s_%d => %s\n",tcn,i,tmpContent->value);
+		int len=strlen(tcn);
+		char *tmp1=malloc((len+10)*sizeof(char));
+		sprintf(tmp1,"%s_%d",tcn,i);
+		fprintf(stderr,"addDefaultValues %s => %s\n",tmp1,tmpContent->value);
+		addToMap(tmpMaps->content,tmp1,tmpContent->value);
+		free(tmp1);
+		hasPassed=1;
+	      }
+	      free(tcn);
+	    }
 	  }
 	  tmpContent=tmpContent->next;
@@ -2484,8 +2502,11 @@
     return errorException(m, _("Unable to download the file."), "InternalError");
   }
+
   map* tmpMap=getMapOrFill(content,"value","");
+    
   free(tmpMap->value);
   tmpMap->value=(char*)malloc((fsize+1)*sizeof(char));
-  memcpy(tmpMap->value,fcontent,(fsize)*sizeof(char)); 
+  memcpy(tmpMap->value,fcontent,(fsize)*sizeof(char));
+
   char ltmp1[256];
   sprintf(ltmp1,"%d",fsize);
Index: trunk/zoo-project/zoo-kernel/service_internal_java.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal_java.c	(revision 359)
+++ trunk/zoo-project/zoo-kernel/service_internal_java.c	(revision 360)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- * Copyright (c) 2009-2011 GeoLabs SARL
+ * Copyright (c) 2009-2012 GeoLabs SARL
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -201,13 +201,61 @@
     maps* tmp=t;
     while(tmp!=NULL){
+      map* tmap=getMapType(tmp->content);
       map* tmp1=tmp->content;
       scObject1 = (*env)->NewObject(env, scHashMap_class, scHashMap_constructor);
       map* sizeV=getMap(tmp1,"size");
+      map* isArray=getMap(tmp1,"isArray");
+      map* alen=getMap(tmp1,"length");
       while(tmp1!=NULL){
-	if(sizeV!=NULL && strcmp(tmp1->name,"value")==0){
-	  jbyteArray tmpData=(*env)->NewByteArray(env,atoi(sizeV->value));
-	  (*env)->SetByteArrayRegion(env,tmpData,0,atoi(sizeV->value),tmp1->value);
-	  (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), tmpData);
-	}else
+	if(strcmp(tmp1->name,"value")==0){
+	  if(isArray==NULL){
+	    if(sizeV!=NULL && strcmp(tmp1->name,"value")==0){
+	      jbyteArray tmpData=(*env)->NewByteArray(env,atoi(sizeV->value));
+	      (*env)->SetByteArrayRegion(env,tmpData,0,atoi(sizeV->value),tmp1->value);
+	      (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), tmpData);
+	    }else
+	      (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), (*env)->NewStringUTF(env,tmp1->value));
+	  }
+	  else{
+	    int alen1=atoi(alen->value);
+	    fprintf(stderr,"LENGTH %d \n",alen1);
+	    
+	    jclass scArrayListClass,scArrayList_class;
+	    jmethodID scArrayList_constructor;
+	    jobject scObject2,scObject3,scObject4;
+	    scArrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
+	    scArrayList_class = (*env)->NewGlobalRef(env, scArrayListClass);
+	    scArrayList_constructor = (*env)->GetMethodID(env, scArrayList_class, "<init>", "()V");
+	    jmethodID add_mid = 0;
+	    scObject2 = (*env)->NewObject(env, scArrayList_class, scArrayList_constructor);
+	    scObject3 = (*env)->NewObject(env, scArrayList_class, scArrayList_constructor);
+	    scObject4 = (*env)->NewObject(env, scArrayList_class, scArrayList_constructor);
+
+	    add_mid = (*env)->GetMethodID(env,scArrayListClass,
+					  "add","(Ljava/lang/Object;)Z");
+	    
+	    int i;
+	    
+	    for(i=0;i<alen1;i++){
+	      map* vMap=getMapArray(tmp->content,"value",i);	    
+	      map* sMap=getMapArray(tmp->content,"size",i);
+	      map* mMap=getMapArray(tmp->content,tmap->value,i);
+	      
+	      if(sMap!=NULL && vMap!=NULL && strncmp(vMap->name,"value",5)==0){
+		jbyteArray tmpData=(*env)->NewByteArray(env,atoi(sMap->value));
+		(*env)->SetByteArrayRegion(env,tmpData,0,atoi(sMap->value),vMap->value);
+		(*env)->CallObjectMethod(env,scObject2, add_mid, tmpData);
+	      }else{
+		jobject tmpData=(*env)->NewStringUTF(env,vMap->value);
+		(*env)->CallObjectMethod(env,scObject2, add_mid, tmpData);
+	      }
+	      
+	    }
+	    
+	    (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), scObject2);
+	    
+	  }
+	}
+	else
 	  (*env)->CallObjectMethod(env,scObject1, put_mid, (*env)->NewStringUTF(env,tmp1->name), (*env)->NewStringUTF(env,tmp1->value));
 	tmp1=tmp1->next;
Index: trunk/zoo-project/zoo-kernel/service_internal_js.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal_js.c	(revision 359)
+++ trunk/zoo-project/zoo-kernel/service_internal_js.c	(revision 360)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- * Copyright (c) 2009-2010 GeoLabs SARL
+ * Copyright (c) 2009-2012 GeoLabs SARL
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -352,11 +352,50 @@
   jsval resf =  OBJECT_TO_JSVAL(res);
   map* tmpm=t;
+  map* isArray=getMap(t,"isArray");
+  map* isBinary=getMap(t,"size");
+  map* tmap=getMapType(t);
+  if(tmap==NULL)
+    fprintf(stderr,"tmap is null !\n");
+  else
+    fprintf(stderr,"tmap is not null ! (%s = %s)\n",tmap->name,tmap->value);
+
+  /* Avoid gesture of binary content which failed due to strlen function use */
+  if(isBinary!=NULL){
+    return res;
+  }
   while(tmpm!=NULL){
-    jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
-    JS_SetProperty(cx, res, tmpm->name,&jsstr);
-#ifdef JS_DEBUG
-    fprintf(stderr,"%s => %s\n",tmpm->name,tmpm->value);
-#endif
+    if(isArray==NULL || strncasecmp(tmpm->name,"value",5)!=0 || 
+       (tmap!=NULL && strncasecmp(tmpm->name,tmap->name,strlen(tmap->name))!=0)){
+      jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm->value,strlen(tmpm->value)));
+      JS_SetProperty(cx, res, tmpm->name,&jsstr);
+#ifdef JS_DEBUG
+      fprintf(stderr,"%s => %s\n",tmpm->name,tmpm->value);
+#endif
+    }
     tmpm=tmpm->next;
+  }
+  if(isArray!=NULL){
+    map* len=getMap(t,"length");
+    int cnt=atoi(len->value);
+    JSObject* values=JS_NewArrayObject( cx, cnt, NULL );
+    JSObject* mvalues=JS_NewArrayObject( cx, cnt, NULL );
+    map *tmpm1,*tmpm2;
+    int i=0;
+    for(i=0;i<cnt;i++){
+      tmpm1=getMapArray(t,"value",i);
+      tmpm2=getMapArray(t,tmap->name,i);
+      if(tmpm1!=NULL){
+	jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm1->value,strlen(tmpm1->value)));
+	JS_SetElement( cx, values, i, &jsstr );
+      }
+      if(tmpm2!=NULL){
+	jsval jsstr = STRING_TO_JSVAL(JS_NewStringCopyN(cx,tmpm2->value,strlen(tmpm2->value)));
+	JS_SetElement( cx, mvalues, i, &jsstr );
+      }
+    }
+    jsval jvalues=OBJECT_TO_JSVAL(values);
+    jsval jmvalues=OBJECT_TO_JSVAL(mvalues);
+    JS_SetProperty(cx, res,"value",&jvalues);
+    JS_SetProperty(cx, res,tmap->name,&jmvalues);
   }
   return res;
Index: trunk/zoo-project/zoo-kernel/service_internal_ms.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal_ms.c	(revision 359)
+++ trunk/zoo-project/zoo-kernel/service_internal_ms.c	(revision 360)
@@ -126,7 +126,4 @@
 
   if(proto>0){
-    map* test=getMap(tmpI->content,"real_extent");
-    if(test!=NULL)
-	extent=test;
     sprintf(webService_url,
 	    "%s?map=%s/%s_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
@@ -145,7 +142,4 @@
   }
   else{
-    map* test=getMap(tmpI->content,"real_extent_reverse");
-    if(test!=NULL)
-	extent=test;
     sprintf(webService_url,
 	    "%s?map=%s/%s_%s.map&request=%s&service=%s&version=%s&%s&width=%s&height=%s&format=%s&bbox=%s&crs=%s",
@@ -281,9 +275,10 @@
   
   if(output!=NULL){
+
     map* test=getMap(output->content,"real_extent");
     if(test!=NULL){
       pointObj min, max;
       projectionObj tempSrs;
-      
+
       min.x = m->extent.minx;
       min.y = m->extent.miny;
@@ -291,16 +286,22 @@
       max.y = m->extent.maxy;
       char tmpSrsStr[1024];
-      
+
+
       msInitProjection(&tempSrs);
       msLoadProjectionStringEPSG(&tempSrs,"EPSG:4326");
-      
+
       msProjectPoint(&(m->projection),&tempSrs,&min);
       msProjectPoint(&m->projection,&tempSrs,&max);
       
       sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.y,min.x,max.y,max.x);
+      map* isGeo=getMap(output->content,"crs_isGeographic");
+      fprintf(stderr,"isGeo = %s\n",isGeo->value);
+      if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0)
+        sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
       addToMap(output->content,"wms_extent",tmpExtent);
-      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
+      sprintf(tmpSrsStr,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
       addToMap(output->content,"wcs_extent",tmpExtent);
-      
+      dumpMap(output->content);
+
     }else{
       sprintf(tmpExtent,"%f,%f,%f,%f",minX, minY, maxX, maxY);
@@ -308,9 +309,11 @@
       fprintf(stderr,"isGeo = %s\n",isGeo->value);
       if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0)
-	sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
+        sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
       addToMap(output->content,"wms_extent",tmpExtent); 
       sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",minX,minY,maxX,maxY);
-      addToMap(output->content,"wcs_extent",tmpExtent); 
-    }
+      addToMap(output->content,"wcs_extent",tmpExtent);
+      
+    }
+
   }
 
@@ -858,8 +861,14 @@
    * Firs store the value on disk
    */
+  map* mime=getMap(outputs->content,"mimeType");
+  char *ext="data";
+  if(mime!=NULL)
+    if(strncasecmp(mime->value,"application/json",16)==0)
+      ext="json";
+  
   map* tmpMap=getMapFromMaps(conf,"main","dataPath");
   map* sidMap=getMapFromMaps(conf,"lenv","sid");
   char *pszDataSource=(char*)malloc((strlen(tmpMap->value)+strlen(sidMap->value)+strlen(outputs->name)+17)*sizeof(char));
-  sprintf(pszDataSource,"%s/ZOO_DATA_%s_%s.data",tmpMap->value,outputs->name,sidMap->value);
+  sprintf(pszDataSource,"%s/ZOO_DATA_%s_%s.%s",tmpMap->value,outputs->name,sidMap->value,ext);
   int f=open(pszDataSource,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
   map* sizeMap=getMap(outputs->content,"size");
Index: trunk/zoo-project/zoo-kernel/service_internal_python.c
===================================================================
--- trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 359)
+++ trunk/zoo-project/zoo-kernel/service_internal_python.c	(revision 360)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- * Copyright (c) 2009-2011 GeoLabs SARL
+ * Copyright (c) 2009-2012 GeoLabs SARL
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -208,9 +208,76 @@
   PyObject* res=PyDict_New( );
   map* tmp=t;
+  int hasSize=0;
+  map* isArray=getMap(tmp,"isArray");
   map* size=getMap(tmp,"size");
+  map* tmap=getMapType(tmp);
   while(tmp!=NULL){
     PyObject* name=PyString_FromString(tmp->name);
-    if(strcasecmp(tmp->name,"value")==0){
-      if(size!=NULL){
+    if(strcasecmp(tmp->name,"value")==0) {
+      if(isArray!=NULL){
+	map* len=getMap(tmp,"length");
+	int cnt=atoi(len->value);
+	PyObject* value=PyList_New(cnt);
+	PyObject* mvalue=PyList_New(cnt);
+	PyObject* svalue=PyList_New(cnt);
+
+	for(int i=0;i<cnt;i++){
+	  
+	  map* vMap=getMapArray(tmp,"value",i);	    
+	  map* sMap=getMapArray(tmp,"size",i);
+
+	  if(vMap!=NULL){
+	    
+	    PyObject* lvalue;
+	    PyObject* lsvalue;
+	    if(sMap==NULL){
+	      lvalue=PyString_FromString(vMap->value);
+	      lsvalue=Py_None;
+	    }
+	    else{
+	      lvalue=PyString_FromStringAndSize(vMap->value,atoi(sMap->value));
+	      lsvalue=PyString_FromString(sMap->value);
+	      hasSize=1;
+	    }
+
+	    if(PyList_SetItem(value,i,lvalue)<0){
+	      fprintf(stderr,"Unable to set key value pair...");
+	      return NULL;
+	    } 
+	    if(PyList_SetItem(svalue,i,lsvalue)<0){
+	      fprintf(stderr,"Unable to set key value pair...");
+	      return NULL;
+	    } 
+	  }
+	  
+	  map* mMap=getMapArray(tmp,tmap->name,i);
+	  PyObject* lmvalue;
+	  if(mMap!=NULL){
+	    lmvalue=PyString_FromString(mMap->value);
+	  }else
+	    lmvalue=Py_None;
+	  
+	  if(PyList_SetItem(mvalue,i,lmvalue)<0){
+	      fprintf(stderr,"Unable to set key value pair...");
+	      return NULL;
+	  } 
+	  
+	}
+
+	if(PyDict_SetItem(res,name,value)<0){
+	  fprintf(stderr,"Unable to set key value pair...");
+	  return NULL;
+	}
+	if(PyDict_SetItem(res,PyString_FromString(tmap->name),mvalue)<0){
+	  fprintf(stderr,"Unable to set key value pair...");
+	  return NULL;
+	}
+	if(hasSize>0)
+	  if(PyDict_SetItem(res,PyString_FromString("size"),svalue)<0){
+	    fprintf(stderr,"Unable to set key value pair...");
+	    return NULL;
+	  }
+      }
+      else if(size!=NULL){
 	PyObject* value=PyString_FromStringAndSize(tmp->value,atoi(size->value));
 	if(PyDict_SetItem(res,name,value)<0){
@@ -228,8 +295,10 @@
     }
     else{
-      PyObject* value=PyString_FromString(tmp->value);
-      if(PyDict_SetItem(res,name,value)<0){
-	fprintf(stderr,"Unable to set key value pair...");
-	return NULL;
+      if(PyDict_GetItem(res,name)==NULL){
+	PyObject* value=PyString_FromString(tmp->value);
+	if(PyDict_SetItem(res,name,value)<0){
+	  fprintf(stderr,"Unable to set key value pair...");
+	  return NULL;
+	}
       }
     }
Index: trunk/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 359)
+++ trunk/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 360)
@@ -2,5 +2,5 @@
  * Author : Gérald FENOY
  *
- *  Copyright 2008-2011 GeoLabs SARL. All rights reserved.
+ *  Copyright 2008-2012 GeoLabs SARL. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -92,4 +92,45 @@
       str[i]=toReplaceBy;
   }
+}
+
+/**
+ * Create (or append to) an array valued maps
+ * value = "["",""]"
+ */
+int appendMapsToMaps(maps* m,maps* mo,maps* mi,elements* elem){
+
+  map* tmap=getMapType(mo->content);
+  if(tmap==NULL){
+    tmap=getMapType(elem->defaults->content);
+  }
+
+  map* testMap=getMap(elem->content,"maxOccurs");
+  if(testMap!=NULL){
+    if(strncasecmp(testMap->value,"unbounded",9)!=0 && atoi(testMap->value)>1){
+      if(addMapsArrayToMaps(&mo,mi,tmap->name)<0){
+	char emsg[1024];
+	sprintf(emsg,_("You set maximum occurences for <%s> as %i but you tried to use it more than the limit you set. Please correct your ZCFG file or your request."),mi->name,atoi(testMap->value));
+	errorException(m,emsg,"InternalError");
+	return -1;
+      }
+    }else{
+      if(strncasecmp(testMap->value,"unbounded",9)==0){
+	if(addMapsArrayToMaps(&mo,mi,tmap->name)<0){
+	  char emsg[1024];
+	  map* tmpMap=getMap(mi->content,"length");
+	  sprintf(emsg,_("ZOO-Kernel was unable to load your data for %s position %s."),mi->name,tmpMap->value);
+	  errorException(m,emsg,"InternalError");
+	  return -1;
+	}
+      }
+      else{
+	char emsg[1024];
+	sprintf(emsg,_("You set maximum occurences for <%s> to one but you tried to use it more than once. Please correct your ZCFG file or your request."),mi->name);
+	errorException(m,emsg,"InternalError");
+	return -1;
+      }
+    }
+  }
+  return 0;
 }
 
@@ -1068,6 +1109,24 @@
 	if(request_input_real_format==NULL)
 	  request_input_real_format=dupMaps(&tmpmaps);
-	else
-	  addMapsToMaps(&request_input_real_format,tmpmaps);
+	else{
+	  maps* testPresence=getMaps(request_input_real_format,tmpmaps->name);
+	  if(testPresence!=NULL){
+	    elements* elem=getElements(s1->inputs,tmpmaps->name);
+	    if(elem!=NULL){
+	      if(appendMapsToMaps(m,request_input_real_format,tmpmaps,elem)<0){
+		freeMaps(&m);
+		free(m);
+		free(REQUEST);
+		free(SERVICE_URL);
+		InternetCloseHandle(hInternet);
+		freeService(&s1);
+		free(s1);
+		return 0;
+	      }
+	    }
+	  }
+	  else
+	    addMapsToMaps(&request_input_real_format,tmpmaps);
+	}
 	freeMaps(&tmpmaps);
 	free(tmpmaps);
@@ -1479,5 +1538,25 @@
 	fflush(stderr);
 #endif
-	addMapsToMaps(&request_input_real_format,tmpmaps);
+
+	{
+	  maps* testPresence=getMaps(request_input_real_format,tmpmaps->name);
+	  if(testPresence!=NULL){
+	    elements* elem=getElements(s1->inputs,tmpmaps->name);
+	    if(elem!=NULL){
+	      if(appendMapsToMaps(m,request_input_real_format,tmpmaps,elem)<0){
+		freeMaps(&m);
+		free(m);
+		free(REQUEST);
+		free(SERVICE_URL);
+		InternetCloseHandle(hInternet);
+		freeService(&s1);
+		free(s1);
+		return 0;
+	      }
+	    }
+	  }
+	  else
+	    addMapsToMaps(&request_input_real_format,tmpmaps);
+	}
 	
 #ifdef DEBUG
Index: trunk/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ogr_sp.py
===================================================================
--- trunk/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ogr_sp.py	(revision 359)
+++ trunk/zoo-project/zoo-services/ogr/base-vect-ops-py/cgi-env/ogr_sp.py	(revision 360)
@@ -6,40 +6,57 @@
 import sys
 
+def readFileFromBuffer(data,ext):
+    geometry=[]
+    osgeo.gdal.FileFromMemBuffer('/vsimem//temp1'+ext,data)
+    ds = osgeo.ogr.Open('/vsimem//temp1'+ext)
+    lyr = ds.GetLayer(0)
+    feat = lyr.GetNextFeature()
+    while feat is not None:
+        geometry+=[feat.Clone()]
+        feat.Destroy()
+        feat = lyr.GetNextFeature()
+    ds.Destroy()
+    osgeo.gdal.Unlink('/vsimem//temp1'+ext)
+    return geometry
+
+def buildFeatureFromGeomtry(conf,geom,driverName,ext):
+    drv = osgeo.ogr.GetDriverByName( driverName )
+    ds = drv.CreateDataSource( "/vsimem//store"+conf["lenv"]["sid"]+"0."+ext )
+    lyr = ds.CreateLayer( "Result", None, osgeo.ogr.wkbUnknown )
+    field_defn = osgeo.ogr.FieldDefn( "Name", osgeo.ogr.OFTString )
+    field_defn.SetWidth( len("Result10000") )
+    lyr.CreateField ( field_defn )
+    feat = osgeo.ogr.Feature(lyr.GetLayerDefn())
+    feat.SetField( "Name", "Input0" )
+    feat.SetGeometry(geom)
+    lyr.CreateFeature(feat)
+    ds.Destroy()
+    return [feat]
+
 def createGeometryFromWFS(conf,my_wfs_response):
-    geometry=[]
-    try:
-        # Create virtual file or parse XML file depending on the GDAL Version
-        gV=int(osgeo.gdal.VersionInfo())
-        if gV >= 1800:
-            osgeo.gdal.FileFromMemBuffer('/vsimem//temp', my_wfs_response)
-            ds = osgeo.ogr.Open('/vsimem//temp')
-            lyr = ds.GetLayer(0)
-            feat = lyr.GetNextFeature()
-            while feat is not None:
-                geometry+=[feat.GetGeometryRef().Clone()]
-                feat.Destroy()
-                feat = lyr.GetNextFeature()
-            ds.Destroy()
-            osgeo.gdal.Unlink('/vsimem//temp')
+    try:
+        geom=osgeo.ogr.CreateGeometryFromGML(my_wfs_response.replace('<?xml version="1.0" encoding="utf-8"?>\n',''))
+    except:
+        geom=None
+    try:
+        if geom is None:
+            return readFileFromBuffer(my_wfs_response,"")
         else:
-            doc=libxml2.parseMemory(my_wfs_response,len(my_wfs_response))
-            ctxt = doc.xpathNewContext()
-            res=ctxt.xpathEval("/*/*/*/*/*[local-name()='Polygon' or local-name()='MultiPolygon' or local-name()='Point' or local-name()='MultiPoint' or local-name()='MultiLineString' or local-name()='LineString' ]")
-            for node in res:
-                geometry_as_string=node.serialize()
-                geometry+=[osgeo.ogr.CreateGeometryFromGML(geometry_as_string)]
-    except:
-        print >> sys.stderr,"Unable to load file from mem buffer\n\n\n"
-    return geometry
+            return buildFeatureFromGeomtry(conf,geom,"GML","xml")
+    except:
+        print >> sys.stderr,"Unable to load file input data !!!\n\n\n"
+
+def createLayerFromJson(conf,obj):
+    geom=osgeo.ogr.CreateGeometryFromJson(obj)
+    if geom is None:
+        return readFileFromBuffer(obj,".json")
+    else:
+        return buildFeatureFromGeomtry(conf,geom,"GeoJSON","json")
 
 def extractInputs(conf,obj):
     if obj["mimeType"]=="application/json":
-	return [osgeo.ogr.CreateGeometryFromJson(obj["value"])]
+        return createLayerFromJson(conf,obj["value"])
     else:
-	try:
-        	return createGeometryFromWFS(conf,obj["value"])
-	except:
-		return [osgeo.ogr.CreateGeometryFromJson(obj["value"])]
-    return null
+        return createGeometryFromWFS(conf,obj["value"])
     
 def outputResult(conf,obj,geom):
@@ -49,40 +66,51 @@
         driverName = "GeoJSON"
         extension = [ ".js" ]
+    if obj.keys().count("schema")>0 and \
+            obj["schema"]=="http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd":
+        driverName = "KML"
+        extension = [ ".kml" ]
     drv = osgeo.ogr.GetDriverByName( driverName )
-    # Create virtual file or real one depending on the GDAL Version
-    gV=int(osgeo.gdal.VersionInfo())
-    if gV >= 1800:
-        ds = drv.CreateDataSource( "/vsimem/store"+conf["lenv"]["sid"]+extension[0] )
-    else:
-        ds = drv.CreateDataSource( conf["main"]["tmpPath"]+"/store"+conf["lenv"]["sid"]+extension[0] )
+    # Create virtual file 
+    ds = drv.CreateDataSource( "/vsimem/store"+conf["lenv"]["sid"]+extension[0] )
     lyr = ds.CreateLayer( "Result", None, osgeo.ogr.wkbUnknown )
-    field_defn = osgeo.ogr.FieldDefn( "Name", osgeo.ogr.OFTString )
-    field_defn.SetWidth( len("Result10000") )
-    lyr.CreateField ( field_defn )
     i=0
     while i < len(geom):
-        feat = osgeo.ogr.Feature( lyr.GetLayerDefn())
-        feat.SetField( "Name", "Result"+str(i) )
-        feat.SetGeometry(geom[i])
-        lyr.CreateFeature(feat)
-        feat.Destroy()
+        lyr.CreateFeature(geom[i])
         geom[i].Destroy()
         i+=1
     ds.Destroy()
-    if gV >= 1800:
-        vsiFile=osgeo.gdal.VSIFOpenL("/vsimem/store"+conf["lenv"]["sid"]+extension[0],"r")
-        i=0
-        while osgeo.gdal.VSIFSeekL(vsiFile,0,os.SEEK_END)>0:
-            i+=1
-        fileSize=osgeo.gdal.VSIFTellL(vsiFile)
-        osgeo.gdal.VSIFSeekL(vsiFile,0,os.SEEK_SET)
-        obj["value"]=osgeo.gdal.VSIFReadL(fileSize,1,vsiFile)
-        osgeo.gdal.Unlink("/vsimem/store"+conf["lenv"]["sid"]+extension[0])
-    else:
-        obj["value"]=open(conf["main"]["tmpPath"]+"/store"+conf["lenv"]["sid"]+extension[0],"r").read()
-        os.unlink(conf["main"]["tmpPath"]+"/store"+conf["lenv"]["sid"]+extension[0])
-        if len(extension)>1:
-            os.unlink(conf["main"]["tmpPath"]+"/store"+conf["lenv"]["sid"]+extension[1])
+    vsiFile=osgeo.gdal.VSIFOpenL("/vsimem/store"+conf["lenv"]["sid"]+extension[0],"r")
+    i=0
+    while osgeo.gdal.VSIFSeekL(vsiFile,0,os.SEEK_END)>0:
+        i+=1
+    fileSize=osgeo.gdal.VSIFTellL(vsiFile)
+    osgeo.gdal.VSIFSeekL(vsiFile,0,os.SEEK_SET)
+    obj["value"]=osgeo.gdal.VSIFReadL(fileSize,1,vsiFile)
+    osgeo.gdal.Unlink("/vsimem/store"+conf["lenv"]["sid"]+extension[0])
+
+def BufferPy(conf,inputs,outputs):
+    print >> sys.stderr, inputs
+    print >> sys.stderr, outputs
+    try:
+        bdist=float(inputs["BufferDistance"]["value"])
+    except:
+        bdist=1
+    print >> sys.stderr, bdist
     
+    geometry=extractInputs(conf,inputs["InputPolygon"])
+    i=0
+    rgeometries=[]
+    while i < len(geometry):
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef().Buffer(bdist)
+        tmp.SetGeometryDirectly(resg)
+        rgeometries+=[tmp]
+        geometry[i].Destroy()
+        resg.thisown=False 
+        tmp.thisown=False
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    i=0
+    return 3
 
 def BoundaryPy(conf,inputs,outputs):
@@ -91,5 +119,9 @@
     rgeometries=[]
     while i < len(geometry):
-        rgeometries+=[geometry[i].GetBoundary()]
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef()
+        resg=resg.GetBoundary()
+        tmp.SetGeometryDirectly(resg)
+        rgeometries+=[tmp]
         geometry[i].Destroy()
         i+=1
@@ -102,7 +134,11 @@
     rgeometries=[]
     while i < len(geometry):
-        if geometry[i].GetGeometryType()!=3:
-            geometry[i]=geometry[i].ConvexHull()
-        rgeometries+=[geometry[i].Centroid()]
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef()
+        if resg.GetGeometryType()!=3:
+            resg=resg.ConvexHull()
+        resg=resg.Centroid()
+        tmp.SetGeometryDirectly(resg)
+        rgeometries+=[tmp]
         geometry[i].Destroy()
         i+=1
@@ -115,11 +151,17 @@
     rgeometries=[]
     while i < len(geometry):
-        rgeometries+=[geometry[i].ConvexHull()]
-        geometry[i].Destroy()
-        i+=1
-    outputResult(conf,outputs["Result"],rgeometries)
-    return 3
-
-def BufferPy(conf,inputs,outputs):
+        tmp=geometry[i].Clone()
+        resg=geometry[i].GetGeometryRef().ConvexHull()
+        tmp.SetGeometryDirectly(resg)
+        rgeometries+=[tmp]
+        geometry[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    return 3
+
+
+
+def EnvelopePy(conf,inputs,outputs):
+    print >> sys.stderr, inputs
     try:
         bdist=float(inputs["BufferDistance"]["value"])
@@ -127,12 +169,7 @@
         bdist=10
     geometry=extractInputs(conf,inputs["InputPolygon"])
-    i=0
-    rgeometries=[]
-    while i < len(geometry):
-        rgeometries+=[geometry[i].Buffer(bdist)]
-        geometry[i].Destroy()
-        i+=1
-    outputResult(conf,outputs["Result"],rgeometries)
-    i=0
+    tmp=geometry[0].GetGeometryRef().GetEnvelope()
+    outputs["Result"]["value"]=str(tmp[0])+','+str(tmp[2])+','+str(tmp[1])+','+str(tmp[3])+','+'urn:ogc:def:crs:OGC:1.3:CRS84'
+    print >> sys.stderr,outputs["Result"]
     return 3
 
@@ -159,22 +196,30 @@
 
 def IntersectionPy(conf,inputs,outputs):
-    geometry1=extractInputs(conf,inputs["InputEntity1"])
-    geometry2=extractInputs(conf,inputs["InputEntity2"])
-    rgeometries=[]
-    i=0
-    while i < len(geometry1):
-        j=0
-        while j < len(geometry2):
-            tres=geometry1[i].Intersection(geometry2[j])
-            if not(tres.IsEmpty()):
-                rgeometries+=[tres]
-            j+=1
-        geometry1[i].Destroy()
-        i+=1
-    i=0
-    while i < len(geometry2):
-        geometry2[i].Destroy()
-        i+=1
-    outputResult(conf,outputs["Result"],rgeometries)
+
+    geometry1=extractInputs(conf,inputs["InputEntity1"])
+    print >> sys.stderr,inputs["InputEntity2"]
+    geometry2=extractInputs(conf,inputs["InputEntity2"])
+
+    rgeometries=[]
+    i=0
+    while i < len(geometry1):
+        j=0
+        while j < len(geometry2):
+            tmp=geometry2[j].Clone()
+            resg=geometry2[j].GetGeometryRef()
+            #resg=resg.Intersection(geometry1[i].GetGeometryRef())
+            resg=geometry1[i].GetGeometryRef().Intersection(resg)
+            tmp.SetGeometryDirectly(resg)
+            if not(resg.IsEmpty()):
+                rgeometries+=[tmp]
+            j+=1
+        geometry1[i].Destroy()
+        i+=1
+    i=0
+    while i < len(geometry2):
+        geometry2[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    print >> sys.stderr,"/outputResult"
     return 3
 
@@ -187,7 +232,10 @@
         j=0
         while j < len(geometry2):
-            tres=geometry1[i].Difference(geometry2[j])
-            if not(tres.IsEmpty()):
-                rgeometries+=[tres]
+            tmp=geometry2[j].Clone()
+            resg=geometry1[i].GetGeometryRef()
+            resg=resg.Difference(geometry2[i].GetGeometryRef())
+            tmp.SetGeometryDirectly(resg)
+            if not(resg.IsEmpty()):
+                rgeometries+=[tmp]
             j+=1
         geometry1[i].Destroy()
@@ -208,12 +256,17 @@
         j=0
         while j < len(geometry2):
-            rgeometries+=[geometry1[i].SymmetricDifference(geometry2[j])]
-            j+=1
-        geometry1[i].Destroy()
-        i+=1
-    i=0
-    while i < len(geometry2):
-        geometry2[i].Destroy()
-        i+=1
-    outputResult(conf,outputs["Result"],rgeometries)
-    return 3
+            tmp=geometry2[j].Clone()
+            resg=geometry1[i].GetGeometryRef()
+            resg=resg.SymmetricDifference(geometry2[i].GetGeometryRef())
+            tmp.SetGeometryDirectly(resg)
+            rgeometries+=[tmp]
+            j+=1
+        geometry1[i].Destroy()
+        i+=1
+    i=0
+    while i < len(geometry2):
+        geometry2[i].Destroy()
+        i+=1
+    outputResult(conf,outputs["Result"],rgeometries)
+    return 3
+
