Index: branches/prototype-v0/zoo-project/zoo-kernel/makefile.vc
===================================================================
--- branches/prototype-v0/zoo-project/zoo-kernel/makefile.vc	(revision 896)
+++ branches/prototype-v0/zoo-project/zoo-kernel/makefile.vc	(revision 897)
@@ -74,4 +74,7 @@
 	$(CPP) /c $(CFLAGS) service_internal_ruby.c
 
+service_internal_mono.obj: service_internal_mono.c service_internal_mono.h service.h
+        $(CPP) /c $(MONO_CLAGS) $(CFLAGS) service_internal_mono.c
+
 service_internal_python.obj: service_internal_python.c service.h
 	$(CPP) /c $(CFLAGS) service_internal_python.c
@@ -101,9 +104,9 @@
 	link /dll /out:$(LIBZOO_SERVICE) ./service.obj ./service_internal.obj ./sqlapi.obj $(LDFLAGS) /FORCE:MULTIPLE
 
-$(PROGRAMNAME): version.h $(LIBZOO_SERVICE) zoo_loader.obj zoo_service_loader.obj service_internal.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(RUBY_FILE) $(PHP_FILE) ulinet.obj lex.cr.obj lex.sr.obj service_conf.tab.obj main_conf_read.tab.obj request_parser.obj response_print.obj server_internal.obj caching.obj service_json.obj service_callback.obj
-	link zoo_loader.obj request_parser.obj response_print.obj server_internal.obj caching.obj service_json.obj service_callback.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(RUBY_FILE) $(PHP_FILE) ulinet.obj main_conf_read.tab.obj lex.cr.obj service_conf.tab.obj lex.sr.obj  zoo_service_loader.obj ./libzoo_service.lib /out:$(PROGRAMNAME) $(LDFLAGS) $(LDFLAGSCGI) ..\..\thirds\sdk\release-1800-x64/lib/json-c.lib ..\..\thirds\sdk\release-1800-x64/lib/pthread_dll.lib ..\..\thirds\sdk\release-1800-x64/lib/libxslt.lib
+$(PROGRAMNAME): version.h $(LIBZOO_SERVICE) zoo_loader.obj zoo_service_loader.obj service_internal.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(MONO_FILE) $(RUBY_FILE) $(PHP_FILE) ulinet.obj lex.cr.obj lex.sr.obj service_conf.tab.obj main_conf_read.tab.obj request_parser.obj response_print.obj server_internal.obj caching.obj service_json.obj service_callback.obj
+	link zoo_loader.obj request_parser.obj response_print.obj server_internal.obj caching.obj service_json.obj service_callback.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(MONO_FILE) $(RUBY_FILE) $(PHP_FILE) ulinet.obj main_conf_read.tab.obj lex.cr.obj service_conf.tab.obj lex.sr.obj  zoo_service_loader.obj ./libzoo_service.lib /out:$(PROGRAMNAME) $(LDFLAGS) $(LDFLAGSCGI) ..\..\thirds\sdk\release-1800-x64/lib/json-c.lib ..\..\thirds\sdk\release-1800-x64/lib/pthread_dll.lib ..\..\thirds\sdk\release-1800-x64/lib/libxslt.lib
 
-zcfg2yaml: version.h zcfg2yaml.obj zoo_service_loader.obj service_internal.obj caching.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(RUBY_FILE) ulinet.obj lex.cr.obj lex.sr.obj service_conf.tab.obj main_conf_read.tab.obj
-	link zcfg2yaml.obj server_internal.obj caching.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(RUBY_FILE) $(PHP_FILE) ulinet.obj response_print.obj main_conf_read.tab.obj lex.cr.obj service_conf.tab.obj lex.sr.obj ./libzoo_service.lib /out:zcfg2yaml.exe $(LDFLAGS) $(LDFLAGSCGI)
+zcfg2yaml: version.h zcfg2yaml.obj zoo_service_loader.obj service_internal.obj caching.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(MONO_FILE) $(RUBY_FILE) ulinet.obj lex.cr.obj lex.sr.obj service_conf.tab.obj main_conf_read.tab.obj
+	link zcfg2yaml.obj server_internal.obj caching.obj $(PY_FILE) $(JAVA_FILE) $(MS_FILE) $(JS_FILE) $(MONO_FILE) $(RUBY_FILE) $(PHP_FILE) ulinet.obj response_print.obj main_conf_read.tab.obj lex.cr.obj service_conf.tab.obj lex.sr.obj ./libzoo_service.lib /out:zcfg2yaml.exe $(LDFLAGS) $(LDFLAGSCGI)
 
 clean:
Index: branches/prototype-v0/zoo-project/zoo-kernel/nmake.opt
===================================================================
--- branches/prototype-v0/zoo-project/zoo-kernel/nmake.opt	(revision 896)
+++ branches/prototype-v0/zoo-project/zoo-kernel/nmake.opt	(revision 897)
@@ -87,4 +87,10 @@
 !ENDIF
 
+!IFDEF MONO_DIR
+MONO_CFLAGS=-DUSE_MONO -I"$(MONO_DIR)"\msvc -I"$(MONO_DIR)"\msvc\include -I"$(MONO_DIR)"
+MONO_LDFLAGS=/LIBPATH:"$(MONO_DIR)/msvc/build/sgen/x64/lib/Release" mono-2.0-sgen.lib
+MONO_FILE=service_internal_mono.obj
+!ENDIF
+
 !IFNDEF ZOOK_DIR
 ZOOK_DIR=.
Index: branches/prototype-v0/zoo-project/zoo-kernel/response_print.c
===================================================================
--- branches/prototype-v0/zoo-project/zoo-kernel/response_print.c	(revision 896)
+++ branches/prototype-v0/zoo-project/zoo-kernel/response_print.c	(revision 897)
@@ -2871,7 +2871,8 @@
 	    geodatatype=getMap(tmpI->content,"geodatatype");
 	    if((nbFeatures!=NULL && atoi(nbFeatures->value)==0) ||
-	       (geodatatype!=NULL && strcasecmp(geodatatype->value,"other")==0))
+	       (geodatatype!=NULL && strcasecmp(geodatatype->value,"other")==0)){
 	      error=1;
 	      res=SERVICE_FAILED;
+	    }
 	  }
 	}
Index: branches/prototype-v0/zoo-project/zoo-kernel/service_internal.c
===================================================================
--- branches/prototype-v0/zoo-project/zoo-kernel/service_internal.c	(revision 896)
+++ branches/prototype-v0/zoo-project/zoo-kernel/service_internal.c	(revision 897)
@@ -688,4 +688,5 @@
             }
         }
+	setMapInMaps(conf,"lenv","semaphore","Created");
     } else if (errno == EEXIST) { /* someone else got it first */
         int ready = 0;
@@ -718,4 +719,5 @@
 	  return -1;
         }
+	setMapInMaps(conf,"lenv","semaphore","Acquired");
     } else {
         return sem_id; /* error, check errno */
Index: branches/prototype-v0/zoo-project/zoo-kernel/service_internal_ms.c
===================================================================
--- branches/prototype-v0/zoo-project/zoo-kernel/service_internal_ms.c	(revision 896)
+++ branches/prototype-v0/zoo-project/zoo-kernel/service_internal_ms.c	(revision 897)
@@ -403,5 +403,5 @@
     extent=getMapArray(tmpI->content,options[proto][4],imyIndex);
     memset(webService_url,0,strlen(webService_url));
-    freeMap(&rformat);
+     freeMap(&rformat);
     free(rformat);
     rformat=createMap("value","image/tiff");
@@ -578,5 +578,5 @@
   
     if(test!=NULL){
-      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.y,min.x,max.y,max.x);
+      sprintf(tmpExtent,"%.15f,%.15f,%.15f,%.15f",min.y,min.x,max.y,max.x);
       map* isGeo=getMapArray(output->content,"crs_isGeographic",imyIndex);
 #ifdef DEBUGMS
@@ -584,18 +584,18 @@
 #endif
       if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0){
-	sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.y,min.x,max.y,max.x);
+	sprintf(tmpExtent,"%.15f,%.15f,%.15f,%.15f",min.y,min.x,max.y,max.x);
 	setMapArray(output->content,"wgs84_extent",imyIndex,tmpExtent);
-        sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
+        sprintf(tmpExtent,"%.15f,%.15f,%.15f,%.15f", minY,minX, maxY, maxX);
       }else{
-	sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
+	sprintf(tmpExtent,"%.15f,%.15f,%.15f,%.15f",min.x,min.y,max.x,max.y);
 	setMapArray(output->content,"wgs84_extent",imyIndex,tmpExtent);
       }
       setMapArray(output->content,"wms_extent",imyIndex,tmpExtent);
-      sprintf(tmpSrsStr,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
+      sprintf(tmpSrsStr,"%.15f,%.15f,%.15f,%.15f",min.x,min.y,max.x,max.y);
       setMapArray(output->content,"wcs_extent",imyIndex,tmpExtent);
     }else{
-      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",min.x,min.y,max.x,max.y);
+      sprintf(tmpExtent,"%.15f,%.15f,%.15f,%.15f",min.x,min.y,max.x,max.y);
       setMapArray(output->content,"wgs84_extent",imyIndex,tmpExtent);
-      sprintf(tmpExtent,"%f,%f,%f,%f",minX, minY, maxX, maxY);
+      sprintf(tmpExtent,"%.15f,%.15f,%.15f,%.15f",minX, minY, maxX, maxY);
       map* isGeo=getMapArray(output->content,"crs_isGeographic",imyIndex);
       if(isGeo!=NULL){
@@ -604,8 +604,8 @@
 #endif
 	if(isGeo!=NULL && strcasecmp("true",isGeo->value)==0)
-	  sprintf(tmpExtent,"%f,%f,%f,%f", minY,minX, maxY, maxX);
+	  sprintf(tmpExtent,"%.15f,%.15f,%.15f,%.15f", minY,minX, maxY, maxX);
       }
       setMapArray(output->content,"wms_extent",imyIndex,tmpExtent); 
-      sprintf(tmpExtent,"%.3f,%.3f,%.3f,%.3f",minX,minY,maxX,maxY);
+      sprintf(tmpExtent,"%.15f,%.15f,%.15f,%.15f",minX,minY,maxX,maxY);
       setMapArray(output->content,"wcs_extent",imyIndex,tmpExtent);
     }
@@ -754,4 +754,5 @@
   }
 
+  setMapArray(output->content,"gdalType",imyIndex,OGR_Dr_GetName(OGR_DS_GetDriver(poDS)));  
   setMapArray(output->content,"geodatatype",imyIndex,"vector");
   int iLayer = 0;
@@ -963,4 +964,5 @@
   int imyIndex=getPublishedId(output);
   map* tmpMap=getMapArray(output->content,"storage",imyIndex);
+  map* styleMap=getMap(output->content,"msStyle");
   char *pszFilename=tmpMap->value;
   GDALDatasetH hDataset;
@@ -1112,14 +1114,15 @@
     msInsertHashTable(&(myLayer->metadata), "ows_bandcount", nBands);
   }
-  if(nBandsI>=3)
-    if(nBandsI==4)
-      msLayerAddProcessing(myLayer,"BANDS=1,2,3,4");
+  if(styleMap==NULL || strstr(styleMap->value,"BANDS=")==NULL){
+    if(nBandsI>=3)
+      if(nBandsI==4)
+	msLayerAddProcessing(myLayer,"BANDS=1,2,3,4");
+      else
+	msLayerAddProcessing(myLayer,"BANDS=1,2,3");
+    else if(nBandsI>=2)
+      msLayerAddProcessing(myLayer,"BANDS=1,2");
     else
-      msLayerAddProcessing(myLayer,"BANDS=1,2,3");
-  else if(nBandsI>=2)
-    msLayerAddProcessing(myLayer,"BANDS=1,2");
-  else
-    msLayerAddProcessing(myLayer,"BANDS=1");
-  
+      msLayerAddProcessing(myLayer,"BANDS=1");
+  }
 
   /**
@@ -1162,13 +1165,17 @@
       char tmpMm[100],tmpMp[100];
       sprintf(tmpMm,"%.3f %.3f",pdfMin,pdfMax);
-      if(pdfMin!=pdfMax)
-	sprintf(tmpMp,"SCALE_%d=%.3f,%.3f",iBand+1,pdfMean-(2*pdfStdDev),pdfMean+(2*pdfStdDev));
-      /*else
-	sprintf(tmpMp,"SCALE_%d=%.3f,%.3f",iBand+1,pdfMin,pdfMax);*/
+      if(pdfMin!=pdfMax && (styleMap==NULL || strstr(styleMap->value,"SCALE_")==NULL)){
+        sprintf(tmpNb,"%d",iBand+1);
+        if(styleMap==NULL || strstr(styleMap->value,"BANDS=")==NULL || strstr(strstr(styleMap->value,"BANDS="),tmpNb)!=NULL){ 
+	  if(pdfMean-(2*pdfStdDev)<0)
+	    sprintf(tmpMp,"SCALE_%d=%.3f,%.3f",iBand+1,0.0,pdfMean+(2*pdfStdDev));
+	  else
+	    sprintf(tmpMp,"SCALE_%d=%.3f,%.3f",iBand+1,pdfMean-(2*pdfStdDev),pdfMean+(2*pdfStdDev));
+	  msLayerAddProcessing(myLayer,tmpMp);
+        }
+      }
       char tmpI[31];      
       sprintf(tmpI,"%s_interval",tmpN);
       msInsertHashTable(&(myLayer->metadata), tmpI, tmpMm);
-      //if(pdfMax>255)
-      msLayerAddProcessing(myLayer,tmpMp);
       map* test=getMap(output->content,"msClassify");
       if(test!=NULL && strncasecmp(test->value,"true",4)==0){
@@ -1255,6 +1262,11 @@
 
   }
-  msLayerAddProcessing(myLayer,"RESAMPLE=BILINEAR");
-
+  if(styleMap==NULL || strstr(styleMap->value,"RESAMPLE")==NULL)
+    msLayerAddProcessing(myLayer,"RESAMPLE=BILINEAR");
+  
+  if(styleMap!=NULL && strlen(styleMap->value)>9){
+    msUpdateLayerFromString(myLayer,styleMap->value,MS_FALSE);
+  }
+  
   m->layerorder[m->numlayers] = m->numlayers;
   m->numlayers++;
@@ -1278,4 +1290,6 @@
   int imyIndex=getPublishedId(outputs);
   map* mime=getMapArray(outputs->content,"mimeType",imyIndex);
+  map* msUrl=getMapFromMaps(conf,"main","mapserverAddress");
+  map* dataPath=getMapFromMaps(conf,"main","dataPath");
   char *ext="data";
   if(mime!=NULL)
@@ -1482,4 +1496,18 @@
   free(correspondance);
 
+  map* sid=getMapFromMaps(conf,"lenv","usid");
+  char *mapPath=
+    (char*)malloc((14+strlen(sid->value)+strlen(outputs->name)+strlen(dataPath->value))*sizeof(char));
+  sprintf(mapPath,"%s/%s_%d_%s.map",dataPath->value,outputs->name,imyIndex,sid->value);
+  char *mapUrl=
+    (char*)malloc((6+strlen(mapPath)+strlen(msUrl->value))*sizeof(char));
+  sprintf(mapUrl,"%s?map=%s",msUrl->value,mapPath);
+
+  if (msInsertHashTable(&(myMap->web.metadata), "ows_onlineresource", mapUrl) == NULL){
+#ifdef DEBUGMS
+    fprintf(stderr,"Unable to add metadata");
+#endif
+    return;
+  }
 
   if(tryOgr(conf,outputs,myMap)<0)
@@ -1487,15 +1515,10 @@
       return ;
 
-  tmp1=getMapFromMaps(conf,"main","dataPath");
-  char *tmpPath=(char*)malloc((13+strlen(tmp1->value))*sizeof(char));
-  sprintf(tmpPath,"%s/symbols.sym",tmp1->value);
+  char *tmpPath=(char*)malloc((13+strlen(dataPath->value))*sizeof(char));
+  sprintf(tmpPath,"%s/symbols.sym",dataPath->value);
   msInitSymbolSet(&myMap->symbolset);
   myMap->symbolset.filename=zStrdup(tmpPath);
   free(tmpPath);
 
-  map* sid=getMapFromMaps(conf,"lenv","usid");
-  char *mapPath=
-    (char*)malloc((14+strlen(sid->value)+strlen(outputs->name)+strlen(tmp1->value))*sizeof(char));
-  sprintf(mapPath,"%s/%s_%d_%s.map",tmp1->value,outputs->name,imyIndex,sid->value);
   msSaveMap(myMap,mapPath);
   saveMapNames(conf,outputs,mapPath);
Index: branches/prototype-v0/zoo-project/zoo-kernel/sshapi.c
===================================================================
--- branches/prototype-v0/zoo-project/zoo-kernel/sshapi.c	(revision 896)
+++ branches/prototype-v0/zoo-project/zoo-kernel/sshapi.c	(revision 897)
@@ -3,5 +3,5 @@
  * Author : Gérald FENOY
  *
- * Copyright 2017 GeoLabs SARL. All rights reserved.
+ * Copyright 2017-2019 GeoLabs SARL. All rights reserved.
  *
  * This work was supported by public funds received in the framework of GEOSUD,
@@ -322,9 +322,10 @@
  */
 bool ssh_copy(maps* conf,const char* localPath,const char* targetPath,int cnt){
-  char mem[1024 * 1000];
+  char mem[1024 * 16];
   size_t nread;
   size_t memuse=0;
   time_t start;
   long total = 0;
+  int counter=0;
   int duration;
   int rc;
@@ -391,10 +392,5 @@
       break;
     
-    if(memuse - rc) {
-      memmove(&mem[0], &mem[rc], memuse - rc);
-      memuse -= rc;
-    }
-    else
-      memuse = 0;
+    memuse = 0;
     
   } while (rc > 0);
@@ -438,5 +434,5 @@
     }
     if(!sessions[cnt]->sftp_session)
-      zSleep(1);
+      zSleep(10);
   } while (!sessions[cnt]->sftp_session);
   do {
@@ -453,32 +449,35 @@
     }
     if(!sftp_handle)
-      zSleep(1);
+      zSleep(10);
   } while (!sftp_handle);
- 
+
   int result=0;
+  int counter=0;
   do {
     do {
-      char* mem=(char*)malloc(16*1024*1024);
-      rc = libssh2_sftp_read(sftp_handle, mem,16*1024*1024);
+      char* mem=(char*)malloc(16*1024);
+      rc = libssh2_sftp_read(sftp_handle, mem,16*1024);
       if(rc > 0) {
 	fwrite(mem, rc, 1, local);
       }
       free(mem);
+      if(counter%25==0)
+	zSleep(10);
     } while (rc > 0);
-    
+
     if(rc != LIBSSH2_ERROR_EAGAIN) {
       result=-1;
       break;
     }
-    
+
     struct timeval timeout;
     fd_set fd;
     timeout.tv_sec = 10;
     timeout.tv_usec = 0;
- 
+
     FD_ZERO(&fd);
- 
+
     FD_SET(sessions[cnt]->sock_id, &fd);
- 
+
     rc = select(sessions[cnt]->sock_id+1, &fd, &fd, NULL, &timeout);
     if(rc <= 0) {
@@ -489,5 +488,9 @@
       return -1;
     }
-    
+
+    if(counter%50==0)
+       zSleep(10);
+    counter++;
+
   } while (1);
   duration = (int)(time(NULL)-start);
Index: branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c
===================================================================
--- branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c	(revision 896)
+++ branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c	(revision 897)
@@ -504,5 +504,5 @@
 #endif
 
-  if(memUse==NULL || strcasecmp(memUse->value,"load")==0)
+  if(memUse!=NULL && strcasecmp(memUse->value,"load")==0)
     ldwFlags=INTERNET_FLAG_NO_CACHE_WRITE;
   
Index: branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 896)
+++ branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 897)
@@ -1307,6 +1307,8 @@
   registry* zooRegistry=NULL;
   if(reg!=NULL){
+#ifndef WIN32
     int saved_stdout = zDup (fileno (stdout));
     zDup2 (fileno (stderr), fileno (stdout));
+#endif
     if(createRegistry (m,&zooRegistry,reg->value)<0){
       map *message=getMapFromMaps(m,"lenv","message");
@@ -1317,6 +1319,8 @@
       return 0;
     }
+#ifndef WIN32
     zDup2 (saved_stdout, fileno (stdout));
     zClose(saved_stdout);
+#endif
   }
 
@@ -1770,5 +1774,7 @@
 			free (REQUEST);
 			closedir (dirp);
-			//xmlFreeDoc (doc);
+			if (corig != NULL)
+			  free (corig);
+			xmlFreeDoc (doc);
 			xmlCleanupParser ();
 			zooXmlCleanupNs ();
@@ -1779,5 +1785,5 @@
 		    if (corig != NULL)
 		      free (corig);
-		  }
+		  }		  
 	      }
 	    closedir (dirp);
@@ -2062,4 +2068,5 @@
 #endif
 #endif
+
 #ifdef DEBUG
           fprintf (stderr, "[ZOO: setenv (%s=%s)]\n", mapcs->name,
