Index: /branches/prototype-v0/zoo-project/zoo-kernel/response_print.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/response_print.c	(revision 850)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/response_print.c	(revision 851)
@@ -2667,5 +2667,5 @@
 #endif
       map *gfile=getMap(tmpI->content,"generated_file");
-      char *file_name;
+      char *file_name=NULL;
       if(gfile!=NULL){
 	gfile=getMap(tmpI->content,"expected_generated_file");
@@ -2676,5 +2676,4 @@
 	file_name=zStrdup((gfile->value)+strlen(tmp1->value));
       }
-
       toto=getMap(tmpI->content,"asReference");
 #ifdef USE_MS
@@ -2714,5 +2713,6 @@
 	      getFileExtension(mtype != NULL ? mtype->value : NULL, file_ext, 32);
 	    }
-
+	    if(file_name!=NULL)
+	      free(file_name);
 	    file_name=(char*)malloc((strlen(s->name)+strlen(usid->value)+strlen(file_ext)+strlen(tmpI->name)+45)*sizeof(char));
 	    sprintf(file_name,"%s_%s_%s_%d.%s",s->name,tmpI->name,usid->value,itn,file_ext);
@@ -2761,5 +2761,5 @@
 	  free(file_name);
 	  free(file_url);
-	  
+	  file_name=NULL;
 	}
 #ifdef USE_MS
@@ -2770,4 +2770,8 @@
       }
 #endif
+      if(file_name!=NULL){
+	free(file_name);
+	file_name=NULL;
+      }
       tmpI=tmpI->next;
     }
@@ -2777,5 +2781,5 @@
       if(tmpI!=NULL)
 	goto NESTED0;
-    }
+    }    
 #ifdef DEBUG
     fprintf(stderr,"SERVICE : %s\n",s->name);
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_callback.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_callback.c	(revision 850)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_callback.c	(revision 851)
@@ -30,4 +30,5 @@
 #include "service_json.h"
 #include "service_internal_ms.h"
+#include <pthread.h>
 
 #ifdef __cplusplus
@@ -35,8 +36,24 @@
 #endif
 
+  int nbThreads=0;
+  int cStep=0;
+  pthread_t* myThreads=NULL;
+  bool steps[7][2]={
+    {false,false},
+    {false,false},
+    {false,false},
+    {false,false},
+    {false,false},
+    {false,false},
+    {false,false}
+  };
+  
   /**
-   * Check if a service name is prohibited, meaning that we don't have to invoke
-   * the callback for this specific service.
+   * Check if a service name is prohibited, meaning that the Kernel doesn't have
+   * to invoke the callback for this specific service.
    *
+   * @param conf the main configuration file maps
+   * @param serviceName the serviceName
+   * @return a bool true if the service is prohibited, false in other case
    */
   bool isProhibited(maps* conf,const char* serviceName){
@@ -52,4 +69,125 @@
     }
     return false;
+  }
+
+  /**
+   * Parameter definition to be used for sending parameters to a thread.
+   */
+  typedef struct {
+    maps *conf;      //!< the main configuration file
+    map *url;        //!< the callback url maps
+    json_object *res;//!< the JSON object to post 
+    int step;        //!< the current step [0,6]
+    int state;       //!< the current state [0,1]
+  } local_params;
+
+  /**
+   * Verify if the URL should use a shared cache or not.
+   *
+   * In case the security section contains a key named "shared", then if the
+   * domain listed in the shared key are contained in the url given as parameter
+   * then it return "SHARED" in other cases, it returns "OTHER".
+   *
+   * @param conf the main configuration file maps
+   * @param url the URL to evaluate
+   * @return a string "SHARED" in case the host is in a domain listed in the
+   * shared key, "OTHER" in other cases.
+   */
+  char* getProvenance(maps* conf,const char* url){
+    map* sharedCache=getMapFromMaps(conf,"security","shared");
+    if(sharedCache!=NULL){
+      char *res=NULL;
+      char *hosts=sharedCache->value;
+      char *curs=strtok(hosts,",");
+      while(curs!=NULL){
+	if(strstr(url,curs)==NULL)
+	  res="OTHER";
+	else{
+	  res="SHARED";
+	  return res;
+	}
+      }
+      return res;
+    }
+    return "OTHER";
+  }
+
+  /**
+   * Practically invoke the callback, meaning sending the HTTP POST request.
+   * 
+   * @param args local_params containing all the variables required
+   */
+  void* _invokeCallback(void* args){
+    local_params* arg=(local_params*)args;
+    HINTERNET hInternet,res1;
+    hInternet=InternetOpen("ZooWPSClient\0",
+			   INTERNET_OPEN_TYPE_PRECONFIG,
+			   NULL,NULL, 0);
+    if(!CHECK_INET_HANDLE(hInternet)){
+      InternetCloseHandle (&hInternet);
+      return false;
+    }
+    char *URL=(char*)malloc((strlen(arg->url->value)+5)*sizeof(char));
+    sprintf(URL,"%s%d_%d/",arg->url->value,arg->step,arg->state);
+    const char* jsonStr=json_object_to_json_string_ext(arg->res,JSON_C_TO_STRING_PLAIN);
+    hInternet.waitingRequests[0] = zStrdup(URL);
+    free(URL);
+    fprintf(stderr,"************************* From thread %d %s %d: REQUEST PARAMETERS\n",pthread_self(),__FILE__,__LINE__);
+    fprintf(stderr," * JSON: [%s] \n",jsonStr);
+    fprintf(stderr," * URL: %s/ \n\n",hInternet.waitingRequests[0]);
+    fprintf(stderr,"************************* From thread %d %s %d: REQUEST PARAMETERS\n",pthread_self(),__FILE__,__LINE__);
+    while( cStep!=7 &&
+	   ( cStep!=arg->step || (arg->state!=0 && steps[arg->step][0]==false) )
+	   ){
+      sleep(1);
+    }
+    fprintf(stderr,"************************* From thread %d %s %d: REQUEST START\n\n",pthread_self(),__FILE__,__LINE__);
+    int i=0;
+    for(i=0;i<7;i++){
+      fprintf(stderr,"%d) %d %d\n",i,steps[i][0],steps[i][1]);
+      fflush(stderr);
+    }
+    fprintf(stderr,"************************* From thread %d %s %d: REQUEST START\n",pthread_self(),__FILE__,__LINE__);
+    fflush(stderr);
+    res1 = InternetOpenUrl (&hInternet,
+			    hInternet.waitingRequests[0], 
+			    (char*)jsonStr, strlen(jsonStr),
+			    INTERNET_FLAG_NO_CACHE_WRITE,
+			    0);
+    AddHeaderEntries(&hInternet,arg->conf);
+    //curl_easy_setopt(hInternet.ihandle[hInternet.nb].handle, CURLOPT_VERBOSE, 1);x
+    processDownloads(&hInternet);
+    fprintf(stderr,"************************* From thread %d %s %d: REQUEST END\n\n",pthread_self(),__FILE__,__LINE__);
+    fflush(stderr);
+    char *tmp = (char *) malloc ((hInternet.ihandle[0].nDataLen + 1)
+				 * sizeof (char));
+    if (tmp == NULL)
+      {
+	setMapInMaps(arg->conf,"lenv","message",_("Unable to allocate memory"));
+	setMapInMaps(arg->conf,"lenv","code","InternalError");
+	return NULL;
+      }
+    size_t bRead;
+    InternetReadFile (hInternet.ihandle[0],
+		      (LPVOID) tmp,
+		      hInternet.
+		      ihandle[0].nDataLen,
+		      &bRead);
+    tmp[hInternet.ihandle[0].nDataLen] = 0;
+    json_object_put(arg->res);
+    InternetCloseHandle(&hInternet);
+    if(cStep==0 || cStep==6 || arg->state==1)
+      cStep=arg->step+1;
+    steps[arg->step][arg->state]=true;
+    fprintf(stderr,"************************* From thread %d %s %d: RESPONSE CONTENT\n",pthread_self(),__FILE__,__LINE__);
+    for(i=0;i<7;i++){
+      fprintf(stderr,"%d) %d %d\n",i,steps[i][0],steps[i][1]);
+    }
+    fprintf(stderr,"Result: \n%s\n\n",tmp);
+    fprintf(stderr,"************************* From thread %d %s %d\n\n",pthread_self(),__FILE__,__LINE__);
+    fflush(stderr);
+    free(tmp);
+    free(args);
+    pthread_exit(NULL);
   }
   
@@ -72,31 +210,46 @@
    * @return bool true in case of success, false in other cases
    */
-  bool invokeCallback(maps* m,maps* inputs,maps* outputs,int step,int state){
-    map* url=getMapFromMaps(m,"callback","url");
+  bool invokeCallback(maps* conf,maps* inputs,maps* outputs,int step,int state){
+    map* url=getMapFromMaps(conf,"callback","url");
     if(url==NULL)
       return false;
       
-    maps* lenv=getMaps(m,"lenv");
+    maps* lenv=getMaps(conf,"lenv");
     map* sname=getMap(lenv->content,"identifier");
-    if(sname!=NULL && isProhibited(m,sname->value))
+    if(sname!=NULL && isProhibited(conf,sname->value))
       return false;
       
     json_object *res=json_object_new_object();
 
-    map* sid=getMapFromMaps(m,"lenv","usid");
+    map* sid=getMapFromMaps(conf,"lenv","usid");
     if(sid!=NULL){
       json_object *jsStr=json_object_new_string(sid->value);
       json_object_object_add(res,"jobid",jsStr);
     }
+    const struct tm *tm;
+    size_t len;
+    time_t now;
+    char *tmp1;
+    map *tmpStatus;
+  
+    now = time ( NULL );
+    tm = localtime ( &now );
+
+    tmp1 = (char*)malloc((TIME_SIZE+1)*sizeof(char));
+
+    len = strftime ( tmp1, TIME_SIZE, "%Y-%m-%dT%I:%M:%SZ", tm );
+    json_object *jsStr0=json_object_new_string(tmp1);
+    json_object_object_add(res,"datetime",jsStr0);
+
     switch(step){
     case 0: {
       // Create a new analyze
-      maps* lenv=getMaps(m,"lenv");
-      sid=getMapFromMaps(m,"lenv","xrequest");
+      maps* lenv=getMaps(conf,"lenv");
+      sid=getMapFromMaps(conf,"lenv","xrequest");
       if(sid!=NULL){
 	json_object *jsStr=json_object_new_string(sid->value);
 	json_object_object_add(res,"request_execute_content",jsStr);
       }
-      sid=getMapFromMaps(m,"lenv","identifier");
+      sid=getMapFromMaps(conf,"lenv","identifier");
       if(sid!=NULL){
 	json_object *jsStr=json_object_new_string(sid->value);
@@ -108,5 +261,4 @@
       // Fetching data inputs
       maps* curs=inputs;
-      
       char *keys[8][2]={
 	{
@@ -139,5 +291,5 @@
 	},
 	{
-	  "datatype",
+	  "geodatatype",
 	  "datatype"
 	}	
@@ -147,15 +299,22 @@
 	map* tmpMap=getMap(curs->content,"cache_file");
 	sid=getMap(curs->content,"ref_wms_link");
+	json_object *res2=json_object_new_object();
 	if(tmpMap!=NULL && sid==NULL){
 	  addToMap(curs->content,"generated_file",tmpMap->value);
+	  struct stat buf;
+	  char timeStr[ 100 ] = "";
+	  if (stat(tmpMap->value, &buf)==0){
+	    strftime(timeStr, 100, "%d-%m-%Y %H:%M:%S", localtime( &buf.st_mtime));
+	    json_object *jsStr=json_object_new_string(timeStr);
+	    json_object_object_add(res2,"creation_date",jsStr);
+	  }
 	  tmpMap=getMap(curs->content,"fmimeType");
 	  if(tmpMap!=NULL){
 	    addToMap(curs->content,"mimeType",tmpMap->value);
 	  }
-	  setReferenceUrl(m,curs);
-	  //outputMapfile(m,curs);
+	  setReferenceUrl(conf,curs);
+	  //outputMapfile(conf,curs);
 	  dumpMaps(curs);
 	}
-	json_object *res2=json_object_new_object();
 	int i=0;
 	int hasRef=-1;
@@ -165,6 +324,9 @@
 	    json_object *jsStr=json_object_new_string(sid->value);
 	    json_object_object_add(res2,keys[i][1],jsStr);
-	    if(i==0)
+	    if(i==0){
 	      hasRef=1;
+	      json_object *jsStr1=json_object_new_string(getProvenance(conf,url->value));
+	      json_object_object_add(res2,"dataOrigin",jsStr1);
+	    }
 	  }
 	}
@@ -176,14 +338,9 @@
       }
       json_object_object_add(res,"inputs",res1);
-      json_object* in=mapsToJson(inputs);
-      if(in!=NULL){
-	//json_object_object_add(res,"inputs",in);
-	json_object_put(in);
-      }
       break;
     }
     case 2: {
       // Uploading data input to cluster
-      maps* in=getMaps(m,"uploadQueue");
+      maps* in=getMaps(conf,"uploadQueue");
       if(in!=NULL){
 	maps* curs=in;
@@ -216,5 +373,5 @@
     case 3: {
       // Generating job script
-      sid=getMapFromMaps(m,"lenv","local_script");
+      sid=getMapFromMaps(conf,"lenv","local_script");
       if(sid!=NULL){
 	json_object *jsStr=json_object_new_string(sid->value);
@@ -225,5 +382,5 @@
     case 4: {
       // Submitting job to cluster
-      sid=getMapFromMaps(m,"lenv","remote_script");
+      sid=getMapFromMaps(conf,"lenv","remote_script");
       if(sid!=NULL){
 	json_object *jsStr=json_object_new_string(sid->value);
@@ -234,14 +391,90 @@
     case 5: {
       // Downloading process outputs from cluster
-      json_object* in=mapsToJson(outputs);
-      if(in!=NULL){
-	//json_object_object_add(res,"outputs",in);
-	json_object_put(in);
-      }
+      //json_object* in=mapsToJson(outputs);
+      dumpMaps(outputs);
+      maps* curs=outputs;
+      char *keys[8][2]={
+	{
+	  "Reference",
+	  "ref"
+	},
+	{
+	  "storage",
+	  "cachefile"
+	},
+	{
+	  "fmimeType",
+	  "mimetype"
+	},
+	{
+	  "size",
+	  "size"
+	},
+	{
+	  "ref_wms_link",
+	  "ref_wms_link"
+	},
+	{
+	  "ref_wcs_link",
+	  "ref_wcs_link"
+	},
+	{
+	  "ref_wfs_link",
+	  "ref_wfs_link"
+	},
+	{
+	  "geodatatype",
+	  "datatype"
+	}	
+      };
+      json_object *res1=json_object_new_object();
+      while(curs!=NULL){	
+	map* tmpMap=getMap(curs->content,"cache_file");
+	sid=getMap(curs->content,"ref_wms_link");
+	json_object *res2=json_object_new_object();
+	int i=0;
+	int hasRef=-1;
+	for(;i<8;i++){
+	  sid=getMap(curs->content,keys[i][0]);
+	  if(sid!=NULL){
+	    json_object *jsStr=json_object_new_string(sid->value);
+	    json_object_object_add(res2,keys[i][1],jsStr);
+	    if(i==0)
+	      hasRef=1;
+	  }
+	}
+	if(hasRef>0)
+	  json_object_object_add(res1,curs->name,res2);
+	else{
+	  maps* curs0=curs->child;
+	  while(curs0!=NULL){
+	    json_object *res3=json_object_new_object();
+	    int i0=0;
+	    int hasRef0=-1;
+	    for(;i0<8;i0++){
+	      sid=getMap(curs0->content,keys[i0][0]);
+	      if(sid!=NULL){
+		json_object *jsStr=json_object_new_string(sid->value);
+		json_object_object_add(res3,keys[i0][1],jsStr);
+		//if(i0==0)
+		hasRef0=1;
+	      }
+	    }
+	    if(hasRef0<0)
+	      json_object_put(res3);
+	    else
+	      json_object_object_add(res2,curs0->name,res3);
+	    curs0=curs0->next;
+	  }	  
+	  json_object_object_add(res1,curs->name,res2);
+	}
+	curs=curs->next;
+      }
+      json_object_object_add(res,"outputs",res1);
       break;
     }
     case 6: {
       // Finalize HPC
-      sid=getMapFromMaps(m,"lenv","local_script");
+      sid=getMapFromMaps(conf,"lenv","local_script");
       if(sid!=NULL){
 	json_object *jsStr=json_object_new_string(sid->value);
@@ -252,5 +485,5 @@
     case 7: {
       // Error or Dismiss
-      sid=getMapFromMaps(m,"lenv","message");
+      sid=getMapFromMaps(conf,"lenv","message");
       if(sid!=NULL){
 	json_object *jsStr=json_object_new_string(sid->value);
@@ -265,52 +498,31 @@
       }
     }
-    fprintf(stderr,"************************* %s %d\n\n",__FILE__,__LINE__);
-    fflush(stderr);
-    HINTERNET hInternet,res1;
-    hInternet=InternetOpen("ZooWPSClient\0",
-			   INTERNET_OPEN_TYPE_PRECONFIG,
-			   NULL,NULL, 0);
-    if(!CHECK_INET_HANDLE(hInternet)){
-      InternetCloseHandle (&hInternet);
+   
+    local_params* argumentsA=(local_params*)malloc(MAPS_SIZE+MAP_SIZE+sizeof(json_object*)+(2*sizeof(int)));
+    argumentsA->conf=conf;
+    argumentsA->url=url;
+    argumentsA->res=res;
+    argumentsA->step=step;
+    argumentsA->state=state;
+    //pthread_t p1;
+    if(myThreads==NULL)
+      myThreads=(pthread_t*)malloc((nbThreads+1)*sizeof(pthread_t));
+    else
+      myThreads=(pthread_t*)realloc(myThreads,(nbThreads+1)*sizeof(pthread_t));
+    if(pthread_create(&myThreads[nbThreads], NULL, _invokeCallback, (void*)argumentsA)==-1){
+      setMapInMaps(conf,"lenv","message",_("Unable to create a new thread"));
       return false;
     }
-    fprintf(stderr," * JSON: [%s] \n",json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN));
-    fprintf(stderr," * URL: %s%d_%d/ \n\n",url->value,step,state);
-    fflush(stderr);
-    char *URL=(char*)malloc((strlen(url->value)+5)*sizeof(char));
-    sprintf(URL,"%s%d_%d/",url->value,step,state);
-    hInternet.waitingRequests[0] = zStrdup(URL);
-    free(URL);
-    const char* jsonStr=json_object_to_json_string_ext(res,JSON_C_TO_STRING_PLAIN);
-    res1 = InternetOpenUrl (&hInternet,
-		     hInternet.waitingRequests[0],
-		     (char*)jsonStr, strlen(jsonStr),
-		     INTERNET_FLAG_NO_CACHE_WRITE,
-		     0);
-    AddHeaderEntries(&hInternet,m);
-    //curl_easy_setopt(hInternet.ihandle[hInternet.nb].handle, CURLOPT_VERBOSE, 1);
-    processDownloads(&hInternet);
-    char *tmp = (char *) malloc ((hInternet.ihandle[0].nDataLen + 1)
-				 * sizeof (char));
-    if (tmp == NULL)
-      {
-	setMapInMaps(m,"lenv","message",_("Unable to allocate memory"));
-	setMapInMaps(m,"lenv","code","InternalError");
-	return false;
-      }
-    size_t bRead;
-    InternetReadFile (hInternet.ihandle[0],
-		      (LPVOID) tmp,
-		      hInternet.
-		      ihandle[0].nDataLen,
-		      &bRead);
-    tmp[hInternet.ihandle[0].nDataLen] = 0;
-    fprintf(stderr,"Result: \n%s\n\n",tmp);
-    fprintf(stderr,"************************* %s %d\n\n",__FILE__,__LINE__);
-    fflush(stderr);
-    free(tmp);
-    json_object_put(res);
-    InternetCloseHandle(&hInternet);
+    //free(argumentsA);
+    nbThreads++;
     return true;
+  }
+
+  void cleanupCallbackThreads(){
+    int i=0;
+    for(i=0;i<nbThreads;i++){
+      pthread_join(myThreads[i],NULL);
+    }
+    free(myThreads);
   }
 
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_callback.h
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_callback.h	(revision 850)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_callback.h	(revision 851)
@@ -43,5 +43,6 @@
 
   bool invokeCallback(maps*,maps*,maps*,int,int);
-
+  void cleanupCallbackThreads();
+  
 #ifdef __cplusplus
 }
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_hpc.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_hpc.c	(revision 850)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_hpc.c	(revision 851)
@@ -137,5 +137,4 @@
 	  }
 	}
-	
 	addToElements(&cur->child,tmp[0]);
 	addToElements(&cur->child,tmp[1]);
@@ -301,4 +300,5 @@
       char *targetPath=(char*)malloc((strlen(targetPathMap->value)+strlen(targetName)+2)*sizeof(char));
       sprintf(targetPath,"%s/%s",targetPathMap->value,targetName);
+      free(targetName);
       setMapInMaps(*real_outputs,input->name,"generated_file",targetPath);
       // We should verify if any optional tag for output is required
@@ -337,4 +337,5 @@
       char *targetPath=(char*)malloc((strlen(targetPathMap->value)+strlen(targetName)+2)*sizeof(char));
       sprintf(targetPath,"%s/%s",targetPathMap->value,targetName);
+      free(targetName);
       addToMap(input->content,"generated_file",targetPath);
       // We should verify if any optional tag for output is required
@@ -499,4 +500,5 @@
     return -1;
   }
+  free(targetPath);
   fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
   fflush(stderr);
@@ -591,18 +593,16 @@
 		setMapInMaps(output->child,"download_link","generated_file",targetPath);
 		setMapInMaps(output->child,"download_link","useMapserver","false");
-		setMapInMaps(output->child,"WMS_LINK","generated_file",targetPath);
-		setMapInMaps(output->child,"WMS_LINK","useMapserver","true");
-		setMapInMaps(output->child,"WCS_LINK","generated_file",targetPath);
-		setMapInMaps(output->child,"WCS_LINK","useMapserver","true");
+		setMapInMaps(output->child,"wms_link","generated_file",targetPath);
+		setMapInMaps(output->child,"wms_link","useMapserver","true");
+		setMapInMaps(output->child,"wms_link","msOgc","WMS");
+		setMapInMaps(output->child,"wms_link","requestedMimeType","image/png");
+		setMapInMaps(output->child,"wcs_link","generated_file",targetPath);
+		setMapInMaps(output->child,"wcs_link","useMapserver","true");
 	      }
+	      free(targetPath);
 	    }
 	  }
 	  input=input->next;
 	}
-	fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
-	fflush(stderr);
-	invokeCallback(m,NULL,outputs,5,1);
-	fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
-	fflush(stderr);
       }
       //free(buf);
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_ms.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_ms.c	(revision 850)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_ms.c	(revision 851)
@@ -194,26 +194,48 @@
 
   char* webService_url=(char*)malloc((strlen(msUrl->value)+strlen(format->value)+strlen(tmpI->name)+strlen(width->value)+strlen(height->value)+strlen(extent->value)+256)*sizeof(char));
-  map* datatype=getMap(tmpI->content,"datatype");
+  map* datatype=getMap(tmpI->content,"geodatatype");
   
-  sprintf(webService_url,
-	  "%s?map=%s/%s_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
-	  msUrl->value,
-	  dataPath->value,
-	  tmpI->name,
-	  sid->value,
-	  options[proto][2],
-	  options[proto][0],
-	  protoVersion,
-	  layers,
-	  rformat->value,
-	  extent->value,
-	  crs->value
-	  );
   if(proto>0){
-    addToMap(tmpI->content,"Reference",webService_url);
+    sprintf(webService_url,
+	    "%s?map=%s/%s_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
+	    msUrl->value,
+	    dataPath->value,
+	    tmpI->name,
+	    sid->value,
+	    options[proto][2],
+	    options[proto][0],
+	    protoVersion,
+	    layers,
+	    rformat->value,
+	    extent->value,
+	    crs->value
+	    );
+    if(datatype!=NULL && strncasecmp(datatype->value,"raster",6)==0){
+      addToMap(tmpI->content,"ref_wcs_link",webService_url);
+    }
+    else{
+      addToMap(tmpI->content,"ref_wfs_link",webService_url);
+    }
     proto=0;
     rformat=createMap("mimeType","image/png");
   }
   else{
+    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",
+	    msUrl->value,
+	    dataPath->value,
+	    tmpI->name,
+	    sid->value,
+	    options[proto][2],
+	    options[proto][0],
+	    protoVersion,
+	    layers,
+	    width->value,
+	    height->value,
+	    rformat->value,
+	    extent->value,
+	    crs->value
+	    );
+    addToMap(tmpI->content,"ref_wms_link",webService_url);
     if(datatype!=NULL && strncasecmp(datatype->value,"raster",6)==0){
       proto=2;
@@ -225,38 +247,57 @@
     }
   }
-  if(datatype!=NULL && strncasecmp(datatype->value,"raster",6)==0){
-    addToMap(tmpI->content,"ref_wcs_link",webService_url);
-  }
-  else{
-    addToMap(tmpI->content,"ref_wfs_link",webService_url);
-  }
+  addToMap(tmpI->content,"Reference",webService_url);
+
   protoVersion=options[proto][1];
   extent=getMap(tmpI->content,options[proto][4]);
   memset(webService_url,0,strlen(webService_url));
-  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",
-	  msUrl->value,
-	  dataPath->value,
-	  tmpI->name,
-	  sid->value,
-	  options[proto][2],
-	  options[proto][0],
-	  protoVersion,
-	  layers,
-	  width->value,
-	  height->value,
-	  rformat->value,
-	  extent->value,
-	  crs->value
-	  );
   if(proto>0){
-    addToMap(tmpI->content,"Reference",webService_url);
-  }
-  addToMap(tmpI->content,"ref_wms_link",webService_url);
+    sprintf(webService_url,
+	    "%s?map=%s/%s_%s.map&request=%s&service=%s&version=%s&%s&format=%s&bbox=%s&crs=%s",
+	    msUrl->value,
+	    dataPath->value,
+	    tmpI->name,
+	    sid->value,
+	    options[proto][2],
+	    options[proto][0],
+	    protoVersion,
+	    layers,
+	    rformat->value,
+	    extent->value,
+	    crs->value
+	    );
+    if(datatype!=NULL && strncasecmp(datatype->value,"raster",6)==0){
+      addToMap(tmpI->content,"ref_wcs_link",webService_url);
+    }
+    else{
+      addToMap(tmpI->content,"ref_wfs_link",webService_url);
+    }
+  }else{
+    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",
+	    msUrl->value,
+	    dataPath->value,
+	    tmpI->name,
+	    sid->value,
+	    options[proto][2],
+	    options[proto][0],
+	    protoVersion,
+	    layers,
+	    width->value,
+	    height->value,
+	    rformat->value,
+	    extent->value,
+	    crs->value
+	    );
+    addToMap(tmpI->content,"ref_wms_link",webService_url);
+  }
   if(hasCRS==0){
     freeMap(&crs);
     free(crs);
   }
+  freeMap(&rformat);
+  free(rformat);
   free(webService_url);
+  dumpMaps(tmpI);
 }
 
@@ -552,4 +593,5 @@
       i++;
     }
+    OGR_DS_Destroy(poDS1);
   }
   free(sdsName);
@@ -572,5 +614,5 @@
   }
 
-  addToMap(output->content,"datatype","vector");
+  addToMap(output->content,"geodatatype","vector");
   int iLayer = 0;
   for( iLayer=0; iLayer < OGR_DS_GetLayerCount(poDS); iLayer++ ){
@@ -744,5 +786,5 @@
   }
 
-  //OGR_DS_Destroy(poDS);
+  OGR_DS_Destroy(poDS);
   //OGRCleanupAll();
 
@@ -774,4 +816,5 @@
     fprintf(stderr,"Unable to access the DataSource %s \n",pszFilename);
 #endif
+    addToMap(output->content,"geodatatype","other");
     setMapInMaps(conf,"lenv","message","gdalinfo failed - unable to open");
     GDALDestroyDriverManager();
@@ -782,5 +825,5 @@
 #endif
 
-  addToMap(output->content,"datatype","raster");
+  addToMap(output->content,"geodatatype","raster");
   /**
    * Add a new layer set name, data
@@ -1018,5 +1061,4 @@
   GDALClose( hDataset );
   GDALDestroyDriverManager();
-
   CPLCleanupTLS();
   return 1;
Index: /branches/prototype-v0/zoo-project/zoo-kernel/sqlapi.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/sqlapi.c	(revision 850)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/sqlapi.c	(revision 851)
@@ -532,5 +532,5 @@
   execSql(conf,zoo_ds_nb-1,sqlQuery);
   cleanUpResultSet(conf,zoo_ds_nb-1);
-  close_sql(conf,zoo_ds_nb-1);
+  //close_sql(conf,zoo_ds_nb-1);
   free(sqlQuery);
   end_sql();
@@ -604,4 +604,5 @@
     OGRFeature::DestroyFeature( poFeature );
   }
+  cleanUpResultSet(conf,zoo_ds_nb-1);
   if(hasRes<0)
     addToMap(statusInfo,"Status","Failed");
Index: /branches/prototype-v0/zoo-project/zoo-kernel/sshapi.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/sshapi.c	(revision 850)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/sshapi.c	(revision 851)
@@ -337,5 +337,4 @@
     sftp_handle =
       libssh2_sftp_open(sessions[cnt]->sftp_session, targetPath,
-			
 			LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
 			LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
@@ -513,4 +512,5 @@
   sprintf(logPath,"%s/exec_out_%s",tmpPath->value,uuid->value);
   FILE* logFile=fopen(logPath,"wb");
+  free(logPath);
   while(true){
     int rc;
Index: /branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c	(revision 850)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c	(revision 851)
@@ -344,9 +344,19 @@
       free(handle.cookie);
   }
+  fprintf(stderr,"%s%d\n",__FILE__,__LINE__);
+  fflush(stderr);
   if(handle0->handle)
     curl_multi_cleanup(handle0->handle);
+  fprintf(stderr,"%s%d\n",__FILE__,__LINE__);
+  fflush(stderr);
   free(handle0->agent);
+  fprintf(stderr,"%s%d\n",__FILE__,__LINE__);
+  fflush(stderr);
   for(i=handle0->nb-1;i>=0;i--){
+    fprintf(stderr,"%s%d\n",__FILE__,__LINE__);
+    fflush(stderr);
     free(handle0->waitingRequests[i]);
+      fprintf(stderr,"%s%d\n",__FILE__,__LINE__);
+      fflush(stderr);
   }
 }
Index: /branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 850)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 851)
@@ -2269,15 +2269,17 @@
   _tmpMaps = createMaps("renv");
   for (; s; ei++) {
-    int len=strlen(s);
-    char* tmpName=zStrdup(s);
-    char* tmpValue=strstr(s,"=")+1;
-    char* tmpName1=(char*)malloc((1+(len-strlen(tmpValue)))*sizeof(char));
-    snprintf(tmpName1,(len-strlen(tmpValue))+1,"%s",tmpName);
-    if(_tmpMaps->content == NULL)
-      _tmpMaps->content = createMap (tmpName1,tmpValue);
-    else
-      addToMap (_tmpMaps->content,tmpName1,tmpValue);
-    free(tmpName);
-    free(tmpName1);
+    if(strstr(s,"=")!=NULL && strlen(strstr(s,"="))>1){
+      int len=strlen(s);
+      char* tmpName=zStrdup(s);
+      char* tmpValue=strstr(s,"=")+1;
+      char* tmpName1=(char*)malloc((1+(len-strlen(tmpValue)))*sizeof(char));
+      snprintf(tmpName1,(len-strlen(tmpValue))+1,"%s",tmpName);
+      if(_tmpMaps->content == NULL)
+	_tmpMaps->content = createMap (tmpName1,tmpValue);
+      else
+	addToMap (_tmpMaps->content,tmpName1,tmpValue);
+      free(tmpName1);
+      free(tmpName);
+    }
     s = *(orig+ei);
   }
@@ -2353,4 +2355,11 @@
       loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
                          &request_output_real_format, &eres);
+#ifdef RELY_ON_DB
+#ifdef META_DB
+      close_sql(m,1);
+      //end_sql();
+#endif
+      close_sql(m,0);
+#endif      
     }
   else
@@ -2586,4 +2595,10 @@
   if (((int) getpid ()) != cpid || cgiSid != NULL)
     {
+      fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
+      fflush(stderr);
+      invokeCallback(m,NULL,request_output_real_format,5,1);
+      fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
+      fflush(stderr);
+
       fclose (stdout);
 
@@ -2611,5 +2626,5 @@
       recordResponse(m,fbkp1);
       fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
-      invokeCallback(m,NULL,request_output_real_format,5,1);
+      invokeCallback(m,NULL,request_output_real_format,6,0);
       fprintf(stderr,"************************* %s %d \n\n",__FILE__,__LINE__);
 #endif
@@ -2617,10 +2632,14 @@
       free(bmap);
       unlink (fbkp1);
+      unhandleStatus (m);
+#ifdef RELY_ON_DB
+#ifdef META_DB
+      cleanupCallbackThreads();
+      close_sql(m,1);
+      //end_sql();
+#endif
+      close_sql(m,0);
+#endif
       unlink (flog);
-      unhandleStatus (m);
-#ifdef META_DB
-      close_sql(m,0);
-      //end_sql();
-#endif
       free(fbkpid);
       free(fbkpres); 
@@ -2630,5 +2649,5 @@
       if(cgiSid!=NULL)
 	free(cgiSid);
-      //InternetCloseHandle (&hInternet);  
+      //InternetCloseHandle (&hInternet);
       fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
       fflush(stderr);
