Index: /branches/prototype-v0/zoo-project/zoo-kernel/response_print.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/response_print.c	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/response_print.c	(revision 896)
@@ -1776,5 +1776,5 @@
  * @param outputs the outputs generated by the service
  */
-void printProcessResponse(maps* m,map* request, int pid,service* serv,const char* service,int status,maps* inputs,maps* outputs){
+void printProcessResponse(maps* m,map* request, int pid,service* serv,const char* service,int status,maps* inputs,maps* outputs){	
   xmlNsPtr ns,ns_ows,ns_xlink;
   xmlNodePtr nr,n,nc,nc1=NULL,nc3;
@@ -1797,5 +1797,5 @@
   char stored_path[1024];
   memset(stored_path,0,1024);
-    
+  
   if(vid==0){
     char tmp[256];
@@ -1982,5 +1982,5 @@
     }
   }
-
+  
   /**
    * Display the process output only when requested !
@@ -1993,12 +1993,12 @@
     maps* mcursor=outputs;
     elements* scursor=serv->outputs;
-    map* testResponse=getMap(request,"RawDataOutput");
+    map* testResponse=getMap(request,"RawDataOutput");	
     if(testResponse==NULL)
       testResponse=getMap(request,"ResponseDocument");
-    while(mcursor!=NULL){
+    while(mcursor!=NULL){		
       map* tmp0=getMap(mcursor->content,"inRequest");
-      scursor=getElements(serv->outputs,mcursor->name);
-      if(scursor!=NULL){
-	if(testResponse==NULL || tmp0==NULL){
+      scursor=getElements(serv->outputs,mcursor->name);	  
+      if(scursor!=NULL){		  
+	if(testResponse==NULL || tmp0==NULL){		
 	  if(vid==0)
 	    printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
@@ -2007,10 +2007,10 @@
 	}
 	else
-	  if(tmp0!=NULL && strncmp(tmp0->value,"true",4)==0){
+	  if(tmp0!=NULL && strncmp(tmp0->value,"true",4)==0){		  
 	    if(vid==0)
 	      printIOType(doc,nc,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
 	    else
 	      printIOType(doc,n,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
-	  }
+	  }	
       }else
 	/**
@@ -2023,9 +2023,8 @@
 	  printIOType(doc,n,ns,ns_ows,ns_xlink,scursor,mcursor,"Output",vid);
       mcursor=mcursor->next;
-    }
+    }	
     if(vid==0)
       xmlAddChild(n,nc);
-  }
-
+  }  
   if(vid==0 && 
      hasStoredExecuteResponse==true 
@@ -2176,6 +2175,5 @@
  * @param type the type
  */
-void printIOType(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,elements* e,maps* m,const char* type,int vid){
-
+void printIOType(xmlDocPtr doc,xmlNodePtr nc,xmlNsPtr ns_wps,xmlNsPtr ns_ows,xmlNsPtr ns_xlink,elements* e,maps* m,const char* type,int vid){	
   xmlNodePtr nc1,nc2,nc3;
   nc1=xmlNewNode(ns_wps, BAD_CAST type);
@@ -2184,6 +2182,5 @@
     tmp=e->content;
   else
-    tmp=m->content;
-
+    tmp=m->content;  
   if(vid==0){
     nc2=xmlNewNode(ns_ows, BAD_CAST "Identifier");
@@ -2225,7 +2222,7 @@
     xmlNewProp(nc1,BAD_CAST "id",BAD_CAST (e!=NULL?e->name:m->name));
   }
-
+  
   // IO type nested outputs
-  if(m->child!=NULL){
+  if(m->child!=NULL){	  
     maps* curs=m->child;
     elements* ecurs=getElements(e,(e!=NULL?e->name:m->name));
@@ -2241,11 +2238,11 @@
     }
   }
-  else{
+  else{	  
     map *tmpMap=getMap(m->content,"Reference");
-    if(tmpMap==NULL){
+    if(tmpMap==NULL){		
       nc2=xmlNewNode(ns_wps, BAD_CAST "Data");
-      if(e!=NULL && e->format!=NULL){
-	if(strncasecmp(e->format,"LiteralOutput",strlen(e->format))==0)
-	  nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
+      if(e!=NULL && e->format!=NULL){		  
+		  if (strncasecmp(e->format, "LiteralOutput", strlen(e->format)) == 0)		  			  
+			  nc3 = xmlNewNode(ns_wps, BAD_CAST "LiteralData");		  
 	else
 	  if(strncasecmp(e->format,"ComplexOutput",strlen(e->format))==0)
@@ -2254,8 +2251,8 @@
 	    nc3=xmlNewNode(ns_wps, BAD_CAST "BoundingBoxData");
 	  else
-	    nc3=xmlNewNode(ns_wps, BAD_CAST e->format);
-      }
-      else {
-	map* tmpV=getMapFromMaps(m,"format","value");
+	    nc3=xmlNewNode(ns_wps, BAD_CAST e->format);		  
+      }
+      else {		  
+	map* tmpV=getMapFromMaps(m,"format","value");	
 	if(tmpV!=NULL)
 	  nc3=xmlNewNode(ns_wps, BAD_CAST tmpV->value);
@@ -2263,6 +2260,6 @@
 	  nc3=xmlNewNode(ns_wps, BAD_CAST "LiteralData");
       } 
-      tmp=m->content;
-      
+      tmp=m->content;	  
+
       while(tmp!=NULL){
 	if(strcasecmp(tmp->name,"mimeType")==0 ||
@@ -2270,6 +2267,5 @@
 	   strcasecmp(tmp->name,"schema")==0 ||
 	   strcasecmp(tmp->name,"datatype")==0 ||
-	   strcasecmp(tmp->name,"uom")==0) {
-	  
+	   strcasecmp(tmp->name,"uom")==0) {	
 	  if(vid==0)
 	    xmlNewProp(nc3,BAD_CAST tmp->name,BAD_CAST tmp->value);
@@ -2282,7 +2278,8 @@
 	  }
 	}
+
 	if(vid==0)
 	  xmlAddChild(nc2,nc3);
-	tmp=tmp->next;
+	tmp=tmp->next;	
       }
       if(e!=NULL && e->format!=NULL && strcasecmp(e->format,"BoundingBoxData")==0) {
@@ -2295,10 +2292,11 @@
 	}
       }
-      else {
-	if(e!=NULL)
-	  tmp=getMap(e->defaults->content,"mimeType");
+      else {		  
+		  //if (e != NULL) {
+		  if (e != NULL && e->defaults != NULL) { // knut: add extra NULL pointer check in case user omits <Default> block in config file			  
+			  tmp = getMap(e->defaults->content, "mimeType");
+		  }
 	else
-	  tmp=NULL;
-	
+	  tmp=NULL;	
 	map* tmp1=getMap(m->content,"encoding");
 	map* tmp2=getMap(m->content,"mimeType");
@@ -2640,5 +2638,5 @@
   dumpMaps(request_outputs);
   fprintf(stderr,"printProcessResponse\n");
-#endif
+#endif  
   map* toto=getMap(request_inputs1,"RawDataOutput");
   int asRaw=0;
@@ -2727,5 +2725,5 @@
   }
 
-  if(res!=SERVICE_SUCCEEDED){
+  if(res!=SERVICE_SUCCEEDED){	  
     printProcessResponse(m,request_inputs1,cpid,
                          s, s->name,res,  // replace serviceProvider with serviceName in stored response file name
@@ -2734,6 +2732,5 @@
     return;
   }
-    
-	
+      
   map *tmp1=getMapFromMaps(m,"main","tmpPath");
   if(asRaw==0){
@@ -2757,5 +2754,5 @@
 #endif
       map *gfile=getMap(tmpI->content,"generated_file");
-      char *file_name=NULL;
+      char *file_name=NULL;	  
       if(gfile!=NULL){
 	gfile=getMap(tmpI->content,"expected_generated_file");
@@ -2765,5 +2762,5 @@
 	readGeneratedFile(m,tmpI->content,gfile->value);
 	file_name=zStrdup((gfile->value)+strlen(tmp1->value));
-      }
+      }	  
       toto=getMap(tmpI->content,"asReference");
 #ifdef USE_MS
@@ -2776,5 +2773,5 @@
 	if(toto!=NULL && strcasecmp(toto->value,"true")==0)
 #endif
-	  {
+	  {		
 	    elements* in=getElements(s->outputs,tmpI->name);
 	    if(in==NULL && s->outputs->child!=NULL){
@@ -2791,6 +2788,5 @@
 	      addToMap(tmpI->content,"encoding","UTF-8");
 	      addToMap(tmpI->content,"schema","http://schemas.opengis.net/ows/1.1.0/owsCommon.xsd");
-	    }
-
+	    }		
 	    char *file_path=NULL;
 	    if(gfile==NULL) {
@@ -2880,5 +2876,5 @@
 	  }
 	}
-#endif
+#endif	
       if(file_name!=NULL){
 	free(file_name);
@@ -2896,5 +2892,5 @@
     fprintf(stderr,"SERVICE : %s\n",s->name);
     dumpMaps(m);
-#endif
+#endif	
     if(error<0)
       printProcessResponse(m,request_inputs1,cpid,
Index: /branches/prototype-v0/zoo-project/zoo-kernel/response_print.h
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/response_print.h	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/response_print.h	(revision 896)
@@ -38,5 +38,7 @@
 
 #include <libintl.h>
-#include <xlocale.h>
+//#include <xlocale.h> //#include <xlocale> 
+#include <locale.h>
+
 /**
  * ZOO-Kernel internal messages translation function
@@ -80,5 +82,6 @@
 #endif
 #ifndef WIN32
-#include <locale.h>
+//#include <locale.h>
+#include <xlocale.h> // knut: this appears to be a non-standard header file that has been removed in newer versions of glibc; it may be sufficient to include <locale.h> (see above) 
 #endif
 #include "ulinet.h"
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service.c	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service.c	(revision 896)
@@ -25,4 +25,8 @@
 #include "service.h"
 
+ // knut: time utilities required for new log function (logMessage)
+#include <ctime>
+#include <chrono>
+#include <process.h>
 
 #if defined(_MSC_VER) && _MSC_VER < 1800
@@ -507,17 +511,19 @@
  */
 void addToMap(map* m,const char* n,const char* v){
-  if(hasKey(m,n)==false){
-    map* _cursor=m;
-    while(_cursor->next!=NULL){
-      _cursor=_cursor->next;
-    }
-    _cursor->next=createMap(n,v);
-  }
-  else{
-    map *tmp=getMap(m,n);
-    if(tmp->value!=NULL)
-      free(tmp->value);
-    tmp->value=zStrdup(v);
-  }
+    if (m != NULL) { // knut: add NULL-pointer check
+        if (hasKey(m, n) == false) {
+            map* _cursor = m;
+            while (_cursor->next != NULL) {
+                _cursor = _cursor->next;
+            }
+            _cursor->next = createMap(n, v);
+        }
+        else {
+            map *tmp = getMap(m, n);
+            if (tmp->value != NULL)
+                free(tmp->value);
+            tmp->value = zStrdup(v);
+        }
+    }
 }
 
@@ -1690,2 +1696,113 @@
   m=&trorf;
 }
+
+/**
+ * Verify that a map has a value
+ *
+ * @param map pointer to map that should be checked
+ * @return true if map has a value or false if value is missing/empty/NULL
+ */
+bool nonempty(map* map) {
+	return (map != NULL && map->value != NULL && strlen(map->value) > 0 && strcmp(map->value, "NULL") != 0);
+}
+
+/**
+ * Verify that a particular map value exists in a maps
+ * data structure, and obtain that value
+ *
+ * @param source pointer to maps structure
+ * @param node name of maps node to search
+ * @param key name of map node to find
+ * @param kvp address to the map* if it exists, otherwise NULL
+ * @return true if map has a value or false if value is missing/NULL
+ *
+ * @note The map assigned to kvp is owned by the source maps
+ */
+bool hasvalue(maps* source, const char* node, const char* key, map** kvp) {
+	*kvp = getMapFromMaps(source, node, key);
+	return (*kvp != NULL && (*kvp)->value != NULL &&
+		strlen((*kvp)->value) > 0 && strcmp((*kvp)->value, "NULL") != 0);
+}
+
+/*
+ * Set error message in configuration maps
+ *
+ * @param conf reference to configuration maps
+ * @param service name of service
+ * @param exc WPSException code
+ * @param message exception text (default: exception text in WPS specification)
+ */
+void setErrorMessage(maps*& conf, const char* service, WPSException exc, const char* message) {
+
+	if (message == NULL) {
+		message = WPSExceptionText[exc];
+	}
+
+	size_t len = strlen(service) + strlen(": ") + strlen(message) + strlen(": ") + strlen(WPSExceptionCode[exc]) + 16;
+	char* msg = (char*)malloc(len * sizeof(char));
+
+	if (msg != NULL) {
+		snprintf(msg, len * sizeof(char), "\n%s: %s: %s\n", service, message, WPSExceptionCode[exc]);
+		setMapInMaps(conf, "lenv", "message", msg);
+		free(msg);
+	}
+}
+
+void logMessage(const char* source, const char* function, int line, const char* file, const char* message) { //, const char* source, const char* function, int line) {
+
+	size_t msglen = 512;
+	const char empty[] = "";
+
+	FILE* log;
+
+	// system time, process time [nanoseconds]   
+	unsigned long long sys_t, proc_t;
+
+	// processor time consumed by the program:
+	clock_t t = clock();
+
+	// system time:
+	std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
+
+	std::time_t now_t = std::chrono::system_clock::to_time_t(now);
+	std::tm* tm = localtime(&now_t);
+	char* str = asctime(tm);
+	str[strlen(str) - 1] = '\0'; // remove newline
+
+	sys_t = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch()).count();
+	//proc_t = (unsigned long long)(1.0e9*t/CLOCKS_PER_SEC);
+	proc_t = t;
+
+	if (message != NULL) {
+		msglen += strlen(message);
+	}
+	else {
+		message = empty;
+	}
+	//getLastErrorMessage(); // cgiScriptName  
+	char* text = (char*)malloc(sizeof(char)*msglen);
+
+	snprintf(text, msglen, "pid: %d %s line %d %s() %s systime: %lld ns ticks: %lld %s\n",
+		_getpid(), source, line, function, str, sys_t, proc_t, message); // __FILE__ __LINE__ __func__ //
+
+	if (file != NULL && (log = fopen(file, "a+")) != NULL) {
+		fputs(text, log);
+		fclose(log);
+	}
+	else {
+#ifdef MSG_LOG_FILE
+		if ((log = fopen(MSG_LOG_FILE, "a+")) != NULL) {
+			fputs(text, log);
+			fclose(log);
+		}
+#endif
+	}
+
+	if (text != NULL) free(text);
+}
+
+// knut:
+// Example:
+// zooLog;
+// zooLogMsg(NULL, getLastErrorMessage()); 
+// zooLogMsg("log.txt", getLastErrorMessage()); 
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service.h
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service.h	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service.h	(revision 896)
@@ -32,4 +32,18 @@
 #else
 #define ZOO_DLL_EXPORT 
+#endif
+
+ // knut: add bool if necessary
+#ifndef __cplusplus
+#ifndef WIN32
+#include <stdbool.h>
+#else
+typedef int bool;
+#define false 0
+#define true 1	
+#endif
+#endif
+#ifndef __bool_true_false_are_defined
+#define __bool_true_false_are_defined 1
 #endif
 
@@ -229,7 +243,8 @@
 #ifdef WIN32
 #define NULLMAP ((map*) 0)
-#define bool int
-#define true 1
-#define false 0
+// knut: see new definition above
+//#define bool int
+//#define true 1
+//#define false 0
 #else
 #define NULLMAP NULL
@@ -303,4 +318,90 @@
     struct registry* next; //!< the next registry pointer
   } registry;
+
+  // knut
+  enum WPSException {
+	  /*
+	  * StatusOK is not a WPS exception, it is added
+	  * here for convenience.
+	  */
+	  StatusOK,
+	  /*
+	  * See WPS 1.0 specification, Table 38 and Table 62.
+	  */
+	  MissingParameterValue,
+	  InvalidParameterValue,
+	  NoApplicableCode,
+	  NotEnoughStorage,
+	  ServerBusy,
+	  FileSizeExceeded,
+	  StorageNotSupported,
+	  VersionNegotiationFailed,
+	  /*
+	  * See WPS 2.0 specification, Tables 41, 46, 48, and 50.
+	  */
+	  NoSuchProcess,
+	  NoSuchMode,
+	  NoSuchInput,
+	  NoSuchOutput,
+	  DataNotAccessible,
+	  SizeExceeded,
+	  TooManyInputs,
+	  TooManyOutputs,
+	  NoSuchFormat,
+	  WrongInputData,
+	  InternalServerError,
+	  NoSuchJob,
+	  ResultNotReady
+  };
+
+  static const char* const WPSExceptionCode[] = {
+	"StatusOK",
+	"MissingParameterValue",
+	"InvalidParameterValue",
+	"NoApplicableCode",
+	"NotEnoughStorage",
+	"ServerBusy",
+	"FileSizeExceeded",
+	"StorageNotSupported",
+	"VersionNegotiationFailed",
+	"NoSuchProcess",
+	"NoSuchMode",
+	"NoSuchInput",
+	"NoSuchOutput",
+	"DataNotAccessible",
+	"SizeExceeded",
+	"TooManyInputs",
+	"TooManyOutputs",
+	"NoSuchFormat",
+	"WrongInputData",
+	"InternalServerError",
+	"NoSuchJob",
+	"ResultNotReady"
+  };
+
+  static const char* const WPSExceptionText[] = {
+	"No problem detected",
+	"Operation request does not include a parameter value, and this server did not declare a default value for that parameter.",
+	"Operation request contains an invalid parameter value.",
+	"No other exceptionCode specified by this service and server applies to this exception.",
+	"The server does not have enough space available to store the inputs and outputs associated with the request.",
+	"The server is too busy to accept and queue the request at this time.",
+	"The file size of one of the input parameters was too large for this process to handle.",
+	"Execute operation request included transmission=”reference” for one of the outputs, but storage is not offered by this server.",
+	"Service version for a ComplexData xlink:href input was not supported by the referenced server, and version negotiation failed.",
+	"One of the identifiers passed does not match with any of the processes offered by this server.",
+	"The process does not permit the desired execution mode.",
+	"One or more of the input identifiers passed does not match with any of the input identifiers of this process.",
+	"One or more of the output identifiers passed does not match with any of the input identifiers of this process.",
+	"One of the referenced input data sets was inaccessible.",
+	"The size of one of the input parameters was too large for this process to handle.",
+	"Too many input items have been specified.",
+	"Too many output items have been specified.",
+	"One or more of the input or output formats specified in the request did not match with any of the formats defined for that particular input or output.",
+	"One or more of inputs for which the service was able to retrieve the data but could not read it.",
+	"",
+	"The JobID from the request does not match any of the Jobs running on this server.",
+	"The result for the requested JobID has not yet been generated."
+  };
 
   ZOO_DLL_EXPORT void _dumpMap(map*);
@@ -370,4 +471,13 @@
   ZOO_DLL_EXPORT int snprintf(char *buffer, size_t n, const char *format, ...);
 #endif
+
+  // knut: some new utility functions; logMessage is primarily intended for debugging 	
+  ZOO_DLL_EXPORT bool nonempty(map* map);
+  ZOO_DLL_EXPORT bool hasvalue(maps* source, const char* node, const char* key, map** kvp);
+  ZOO_DLL_EXPORT void setErrorMessage(maps*& conf, const char* service, WPSException exc, const char* message = NULL);
+  ZOO_DLL_EXPORT void logMessage(const char* source, const char* function, int line, const char* file = NULL, const char* message = NULL);
+  #define zooLogMsg(file,message) logMessage(__FILE__, __func__, __LINE__, (file), (message)) 
+  #define zooLog logMessage(__FILE__, __func__, __LINE__)  
+
 #ifdef __cplusplus
 }
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_internal.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_internal.c	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_internal.c	(revision 896)
@@ -917,2 +917,29 @@
 }
 
+/**
+ * Check if file exists in specified folder
+ *
+ * @param dir the folder in which to search for file
+ * @param name the name of the file (not full path) 
+ * @return a character string with the full path [dir/name], or NULL if the file does not exist
+ *
+ * @attention Caller is responsible for applying free() to the returned pointer
+ */
+char* file_exists(const char* dir, const char* name) {
+	char* d = (dir != NULL ? dir : ".");
+	if (name != NULL) {
+		size_t length = strlen(d) + strlen(name) + 2; // including file separator and \0 character
+		char* path = (char*)calloc(length, sizeof(char));
+		snprintf(path, length, "%s/%s", d, name);
+
+		struct stat buffer;
+		if (stat(path, &buffer) != 0) {
+			free(path);
+			path = NULL;
+		}
+		return path;
+	}
+	else {
+		return NULL;
+	}
+}
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_internal.h
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_internal.h	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_internal.h	(revision 896)
@@ -38,5 +38,5 @@
 
 #include <libintl.h>
-#include <xlocale.h>
+#include <locale.h>
 /**
  * ZOO-Kernel internal messages translation function
@@ -162,4 +162,6 @@
   ZOO_DLL_EXPORT int unlockShm(semid);
 
+  ZOO_DLL_EXPORT char* file_exists(const char* dir, const char* name); 
+
 #ifdef __cplusplus
 }
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_mono.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_mono.c	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_mono.c	(revision 896)
@@ -30,4 +30,7 @@
 #include "response_print.h"
 
+MonoClass *iclasses[4];
+MonoMethod *imethods[10];
+
 /**
  * Load a Mono dll then run the static public method corresponding to the 
@@ -69,21 +72,52 @@
     mono_config_parse(NULL);
 
-  MonoDomain* monoDomain = mono_jit_init_version("ZOO_Embedded_Domain",
-                                                 "v4.0.30319");
-
-  map* cwdMap=getMapFromMaps(*main_conf,"main","servicePath");
-  if(cwdMap==NULL)
-    cwdMap=getMapFromMaps(*main_conf,"lenv","cwd");
-  
-  char *zooAssembly=(char*)malloc((strlen(cwdMap->value)+11)*sizeof(char));
-  sprintf(zooAssembly,"%s/ZMaps.dll",cwdMap->value);
-  assembly = mono_domain_assembly_open(monoDomain,zooAssembly);
-  if(assembly==NULL){
-    setMapInMaps(*main_conf,"lenv","message",_("The ZMaps.dll assembly cannot be found!"));
-    return 4;
-  }
-  mono_add_internal_call ("ZOO_API::Translate", MonoTranslate);
-  mono_add_internal_call ("ZOO_API::UpdateStatus", MonoUpdateStatus);
-
+  MonoDomain* monoDomain;
+  map* mono;
+  if (hasvalue(*main_conf, "mono", "version", &mono)) {	  
+	  monoDomain = mono_jit_init_version("ZOO_Embedded_Domain", mono->value);
+  }
+  else {	  
+	  monoDomain = mono_jit_init("ZOO_Embedded_Domain"); // use default framework version
+  }
+
+  //MonoDomain* monoDomain = mono_jit_init_version("ZOO_Embedded_Domain", "v4.0.30319"); 
+  //MonoDomain* monoDomain = mono_jit_init("ZOO_Embedded_Domain");  
+
+  char* ZMapsLib = "ZMaps.dll";
+  char *zooAssembly = NULL;
+  
+  map* config = NULL, *basedir = NULL;
+  if (hasvalue(*main_conf, "mono", "configdir", &basedir) && // knut: rename to e.g. "base_dir"?
+	  hasvalue(*main_conf, "mono", "configfile", &config)) {	  
+	  mono_domain_set_config(monoDomain, basedir->value, config->value); 
+	  zooAssembly = file_exists(basedir->value, ZMapsLib);
+  }
+  else {	  
+	  mono_domain_set_config(monoDomain, "./", "");
+  }    
+
+  map* cwdMap;
+  if (! hasvalue(*main_conf, "main", "servicePath", &cwdMap) &&
+	  ! hasvalue(*main_conf, "main", "libPath", &cwdMap) ) {
+	  cwdMap = getMapFromMaps(*main_conf, "lenv", "cwd");
+  }  
+
+  if (zooAssembly != NULL || (zooAssembly = file_exists(cwdMap->value, ZMapsLib)) != NULL) {
+	  assembly = mono_domain_assembly_open(monoDomain, zooAssembly);
+  }
+  else { 
+	  // try to load from default locations (GAC?)
+	  assembly = mono_domain_assembly_open(monoDomain, ZMapsLib);
+  }  
+  free(zooAssembly);
+
+  if (assembly == NULL) {
+	  setMapInMaps(*main_conf, "lenv", "message", _("The ZMaps.dll assembly cannot be found!"));
+	  return 4;
+  }
+
+  mono_add_internal_call ("ZOO_API::Translate", MonoTranslate);    
+  mono_add_internal_call("ZOO_API::UpdateStatus", MonoUpdateStatus);
+  
   monoImage = mono_assembly_get_image(assembly);
   MonoClass *KeysList = mono_class_from_name(monoImage, "ZooGenerics", "KeysList");
@@ -104,6 +138,7 @@
   MonoClass *classes[3]={_ZMapsClass,ZMapsClass,ZMapClass};
   MonoMethod *methods[5]={ZMapsAdd,_ZMapsSetContent,_ZMapsSetChild,ZMapAdd,ZMapDisplay};
-
+  
   MonoMethod *ZMapsGetKeys = mono_class_get_method_from_name(ZMapsClass, "getKeys", 0);
+  
   MonoMethod *ZMapsGetKeysCount = mono_class_get_method_from_name(ZMapsClass, "getKeysCount", 0);
   MonoMethod *ZMapsGetKey = mono_class_get_method_from_name(ZMapsClass, "getKey", 1);
@@ -116,5 +151,5 @@
   MonoClass *oclasses[4]={_ZMapsClass,ZMapsClass,ZMapClass,KeysList};
   MonoMethod *omethods[10]={ZMapsGetMaps,ZMapsGetKeysCount,ZMapsGetKey,ZMapGetMap,ZMapGetKeysCount,ZMapGetKey,_ZMapsGetContent,_ZMapsGetChild,ZMapGetSize,ZMapGetMapAsBytes};
-
+  
   for(int i=0;i<4;i++){
     iclasses[i]=oclasses[i];
@@ -131,13 +166,30 @@
 
   MonoObject * out=ZMapsFromMaps(monoDomain,classes,methods,&exc,outputs);
-
+  
   args [0] = main;
   args [1] = in;
   args [2] = out;
 
-  tmp=getMap(s->content,"serviceProvider");
-  char *sName=(char*)malloc((strlen(tmp->value)+strlen(cwdMap->value)+2)*sizeof(char));
-  sprintf(sName,"%s/%s",cwdMap->value,tmp->value);
-  MonoAssembly* serviceAssembly = mono_domain_assembly_open(monoDomain,sName);
+  char* sName = NULL;
+  MonoAssembly* serviceAssembly = NULL;
+  
+  tmp = getMap(s->content, "serviceProvider");  
+  char* test = file_exists(NULL, "log.txt");
+  if ( (sName = file_exists(cwdMap->value, tmp->value)) != NULL ||
+	   (sName = file_exists(".", tmp->value)) != NULL ||  // in case servicePath is defined but serviceProvider is in working directory
+	   (basedir != NULL && (sName = file_exists(basedir->value, tmp->value)) != NULL) ) {
+
+	   serviceAssembly = mono_domain_assembly_open(monoDomain, sName);
+  }
+  else {
+	  // try to open from default locations	  
+	  serviceAssembly = mono_domain_assembly_open(monoDomain, tmp->value);
+  }
+  free(sName);
+
+  //char *sName=(char*)malloc((strlen(tmp->value)+strlen(cwdMap->value)+2)*sizeof(char));
+  //sprintf(sName,"%s/%s",cwdMap->value,tmp->value);
+  //MonoAssembly* serviceAssembly = mono_domain_assembly_open(monoDomain,sName);
+  
   if(serviceAssembly==NULL){
     char *msg=(char*)malloc((strlen(_("Your service assembly: %s cannot be found!"))+strlen(tmp->value)+1)*sizeof(char));
@@ -147,8 +199,9 @@
     return 4;
   }
-
+  
   MonoImage* serviceImage = mono_assembly_get_image(serviceAssembly);
 
   map* tmp1=getMap(s->content,"serviceNameSpace");
+  
   tmp=getMap(s->content,"serviceClass");
   MonoClass *serviceClass = mono_class_from_name(serviceImage, tmp1->value, tmp->value);
@@ -160,4 +213,5 @@
     return 4;
   }
+  
   MonoMethod *serviceFunction = mono_class_get_method_from_name(serviceClass, s->name, 3);
   if(serviceFunction==NULL){
@@ -168,18 +222,28 @@
     return 4;
   }
+  
   MonoObject *exception=NULL;
   MonoObject *result = mono_runtime_invoke(serviceFunction,NULL,args,&exception);
+  
+  if (exception != NULL) { // knut: add exception handling
+	  MonoString* pMsg = mono_object_to_string(exception, NULL);	  
+	  setErrorMessage(*main_conf, s->name, NoApplicableCode, mono_string_to_utf8(pMsg));
+	  return 4;
+  }
+
   res=*(int*)mono_object_unbox (result);
+  
   if(res==3){
     freeMaps(&outputs);
     free(outputs);
-    outputs=mapsFromZMaps(monoDomain,oclasses,omethods,args[2]);
+    outputs=mapsFromZMaps(monoDomain,oclasses,omethods,(MonoObject*)args[2]);
     *real_outputs=outputs;
   }
+  
   freeMaps(&m);
   free(m);
-  m=mapsFromZMaps(monoDomain,oclasses,omethods,args[0]);
+  m=mapsFromZMaps(monoDomain,oclasses,omethods,(MonoObject*)args[0]);
   *main_conf=m;
-  mono_jit_cleanup (monoDomain);
+  mono_jit_cleanup (monoDomain);  
   return res;
 }
@@ -288,10 +352,10 @@
       values[0]=&i;
       exc=NULL;
-      MonoObject *okey = (MonoString*) mono_runtime_invoke(methods[2],m,values,&exc);
+      MonoString *okey = (MonoString*) mono_runtime_invoke(methods[2],m,values,&exc);
       char* key = mono_string_to_utf8(okey);
       maps* tmp=createMaps(key);
       values[0]=mono_string_new (domain, key);
-      MonoObject *content_ZMaps = (MonoString*) mono_runtime_invoke(methods[0],m,values,&exc);
-      MonoObject *content = mono_runtime_invoke(methods[6],content_ZMaps,NULL,&exc);
+      MonoString *content_ZMaps = (MonoString*) mono_runtime_invoke(methods[0],m,values,&exc);
+      MonoObject *content = mono_runtime_invoke(methods[6],(MonoObject*)content_ZMaps,NULL,&exc);
       tmp->content=mapFromZMap(domain,classes,methods,content);
       MonoObject *childs = mono_runtime_invoke(methods[7],content_ZMaps,NULL,&exc);
@@ -329,9 +393,9 @@
       values[0]=&i;
       exc=NULL;
-      MonoObject *okey = (MonoString*) mono_runtime_invoke(methods[5],m,values,&exc);
+      MonoString *okey = (MonoString*) mono_runtime_invoke(methods[5],m,values,&exc);
       char* key = mono_string_to_utf8(okey);
       values[0]=mono_string_new (domain, key);
       exc=NULL;
-      MonoObject *ovalue = (MonoString*) mono_runtime_invoke(methods[3],m,values,&exc);
+      MonoString *ovalue = (MonoString*) mono_runtime_invoke(methods[3],m,values,&exc);
       char* value = mono_string_to_utf8(ovalue);
       if(res==NULL)
@@ -350,5 +414,5 @@
  */
 static MonoString* MonoTranslate(MonoString *str){
-  return mono_string_new (mono_domain_get(), mono_string_to_utf8(_(str)));
+  return mono_string_new (mono_domain_get(), _(mono_string_to_utf8(str)));
 }
 
@@ -360,18 +424,15 @@
  * @return the translated string
  */
-static void MonoUpdateStatus(MonoObject* obj,MonoString *str,int* p){
-  MonoDomain* domain = mono_object_get_domain (obj);
-  maps *confMaps=mapsFromZMaps(domain,iclasses,imethods,obj);
-  setMapInMaps(confMaps,"lenv","message",mono_string_to_utf8(str));
-  int tmp=p;
-  if (p < 0 || p > 100){
-    tmp=-1;
-  }
-  char tmpStatus[5];
-  snprintf(tmpStatus, 4, "%d", tmp);
-  setMapInMaps(confMaps,"lenv","status",(char*)tmpStatus);
-  _updateStatus(confMaps);
-  freeMaps(&confMaps);
-  free(confMaps);
-  return;
-}
+static void MonoUpdateStatus(MonoObject* obj, MonoString *str, int p) {	
+	MonoDomain* domain = mono_object_get_domain(obj);	
+	maps *confMaps = mapsFromZMaps(domain, iclasses, imethods, obj);	
+	setMapInMaps(confMaps, "lenv", "message", mono_string_to_utf8(str));	
+	int tmp = p > 100 || p < 0 ? -1 : p;	
+	char tmpStatus[5];
+	snprintf(tmpStatus, 4, "%d", tmp);	
+	setMapInMaps(confMaps, "lenv", "status", (char*)tmpStatus);	
+	_updateStatus(confMaps);	
+	freeMaps(&confMaps);	
+	free(confMaps);
+	return;
+}
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_mono.h
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_mono.h	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_mono.h	(revision 896)
@@ -45,7 +45,8 @@
   map* mapFromZMap(MonoDomain*,MonoClass**,MonoMethod**,MonoObject*);
   static MonoString* MonoTranslate(MonoString*);
-  static void MonoUpdateStatus(MonoObject*,MonoString*,int*);
-  MonoClass *iclasses[4];
-  MonoMethod *imethods[10];
+  //static void MonoUpdateStatus(MonoObject*,MonoString*,int*);
+  static void MonoUpdateStatus(MonoObject*, MonoString*, int);
+  //MonoClass *iclasses[4]; // knut: move declarations to service_internal_mono.c
+  //MonoMethod *imethods[10];
 
 #ifdef __cplusplus
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_php7.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_php7.c	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_php7.c	(revision 896)
@@ -25,4 +25,5 @@
 #ifdef WIN32
   #define NO_FCGI_DEFINES
+  #define ZEND_WIN32_KEEP_INLINE
 #endif
 
Index: /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_python.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_python.c	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/service_internal_python.c	(revision 896)
@@ -146,14 +146,32 @@
  */
 int zoo_python_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
+
   char *pythonpath;
   char *python_path;
+
+#ifdef WIN32
+  char* os_pathsep = ";";
+#else
+  char* os_pathsep = ":";
+#endif
+
   maps* m=*main_conf;
   maps* inputs=*real_inputs;
   maps* outputs=*real_outputs;
   map* tmp0=getMapFromMaps(*main_conf,"lenv","cwd");
-  char *ntmp=tmp0->value;
+  char *ntmp=tmp0->value;  
   map* tmp=NULL;
   int hasToClean=0;
-  tmp=getMapFromMaps(*main_conf,"env","PYTHONPATH");
+  tmp=getMapFromMaps(*main_conf,"env","PYTHONPATH"); 
+
+  map* kvp = NULL;
+  char* libPath = NULL;
+  if (hasvalue(*main_conf, "main", "libPath", &kvp)) {
+	  libPath = kvp->value;
+  }
+  else {
+	  libPath = "";
+  }
+
 #ifdef DEBUG
   fprintf(stderr,"PYTHON SUPPORT \n");
@@ -172,30 +190,42 @@
       python_path=cwdMap->value;
     else
-      python_path=(char*)".";
+      python_path=(char*)".";	
   }
   tmp=NULL;
   tmp=getMap(request,"metapath");
   if(tmp!=NULL && strcmp(tmp->value,"")!=0){
-    pythonpath=(char*)malloc((4+strlen(python_path)+strlen(ntmp)+strlen(tmp->value))*sizeof(char));
+    //pythonpath=(char*)malloc((4+strlen(python_path)+strlen(ntmp)+strlen(tmp->value))*sizeof(char));
+	  pythonpath = (char*)malloc((5 + strlen(python_path) + strlen(ntmp) + strlen(tmp->value) + strlen(libPath)) * sizeof(char));
 #ifdef WIN32
-  sprintf(pythonpath,"%s/%s/;%s",ntmp,tmp->value,python_path);
+  //sprintf(pythonpath,"%s/%s/;%s",ntmp,tmp->value,python_path);
+	sprintf(pythonpath, "%s/%s/;%s;%s", ntmp, tmp->value, python_path, libPath);
 #else
-  sprintf(pythonpath,"%s/%s/:%s",ntmp,tmp->value,python_path);
+  //sprintf(pythonpath,"%s/%s/:%s",ntmp,tmp->value,python_path);
+  sprintf(pythonpath, "%s/%s/:%s:%s", ntmp, tmp->value, python_path, libPath);  
 #endif
   }
   else{
-    pythonpath=(char*)malloc((2+strlen(python_path)+strlen(ntmp))*sizeof(char));
+    //pythonpath=(char*)malloc((2+strlen(python_path)+strlen(ntmp))*sizeof(char));
+	  pythonpath = (char*)malloc((3 + strlen(python_path) + strlen(ntmp) + strlen(libPath)) * sizeof(char));
 #ifdef WIN32
-    sprintf(pythonpath,"%s;%s",ntmp,python_path);
+    //sprintf(pythonpath,"%s;%s",ntmp,python_path);
+	sprintf(pythonpath, "%s;%s;%s", ntmp, python_path, libPath);
 #else
-    sprintf(pythonpath,"%s:%s",ntmp,python_path);
-#endif
+    //sprintf(pythonpath,"%s:%s",ntmp,python_path);
+	sprintf(pythonpath, "%s:%s:%s", ntmp, python_path, libPath);
+#endif	
   }
 #ifdef DEBUG
     fprintf(stderr,"PYTHONPATH=%s\n",pythonpath);
 #endif
-#ifndef WIN32
-  setenv("PYTHONPATH",pythonpath,1);
-#else
+	map* home = NULL;
+// knut: also set PYTHONHOME environment variable so that Python can load standard modules
+#ifndef WIN32	
+  setenv("PYTHONPATH",pythonpath,1);  
+  //= getMapFromMaps(*main_conf, "env", "PYTHONHOME"); 
+  if (hasvalue(*main_conf, "env", "PYTHONHOME", &home)) {
+	  setenv("PYTHONHOME", home->value, 1); // overwrite
+  }
+#else	
   SetEnvironmentVariable("PYTHONPATH",pythonpath);
   char* toto=(char*)malloc((strlen(pythonpath)+12)*sizeof(char));
@@ -203,5 +233,9 @@
   _putenv(toto);
   free(toto);
-#endif
+  if (hasvalue(*main_conf, "env", "PYTHONHOME", &home)) { 
+	  SetEnvironmentVariable("PYTHONHOME", home->value);
+  }
+  char buffer[128];        
+#endif  
   if(hasToClean>0)
     free(python_path);
@@ -209,16 +243,16 @@
 
   PyThreadState *mainstate;
-#if PY_MAJOR_VERSION >= 3
-  PyImport_AppendInittab("zoo", init_zoo);
+#if PY_MAJOR_VERSION >= 3  
+  PyImport_AppendInittab("zoo", init_zoo);  
 #else
   PyEval_InitThreads();
-#endif
-  Py_Initialize();
-#if PY_MAJOR_VERSION >= 3
+#endif  
+  Py_Initialize();  
+#if PY_MAJOR_VERSION >= 3  
   PyEval_InitThreads();
-  PyImport_ImportModule("zoo");
+  PyImport_ImportModule("zoo");  
 #else
   init_zoo();
-#endif
+#endif  
   mainstate = PyThreadState_Swap(NULL);
   PyEval_ReleaseLock();
@@ -240,5 +274,5 @@
       char *mn=(char*)malloc((strlen(mps)+strlen(tmp->value)+2)*sizeof(char));
       sprintf(mn,"%s.%s",mps,tmp->value);
-      pName = PyString_FromString(mn);
+      pName = PyString_FromString(mn);	  
       free(mn);
       free(mps);
@@ -251,6 +285,6 @@
     errorException (m, "Unable to parse serviceProvider please check your zcfg file.", "NoApplicableCode", NULL);
     exit(-1);
-  }
-  pModule = PyImport_Import(pName);
+  }  
+  pModule = PyImport_Import(pName);    
   int res=SERVICE_FAILED;
   if (pModule != NULL) {
@@ -267,5 +301,5 @@
       PyTuple_SetItem(pArgs, 1, (PyObject *)arg2);
       PyTuple_SetItem(pArgs, 2, (PyObject *)arg3);
-      pValue = PyObject_CallObject(pFunc, pArgs);
+      pValue = PyObject_CallObject(pFunc, pArgs);	  
       if (pValue != NULL) {
 	res=PyInt_AsLong(pValue);
@@ -275,5 +309,5 @@
 	free(*main_conf);
 	*main_conf=mapsFromPyDict(arg1);
-	*real_outputs=mapsFromPyDict(arg3);
+	*real_outputs=mapsFromPyDict(arg3);	
 #ifdef DEBUG
 	fprintf(stderr,"Result of call: %i\n", PyInt_AsLong(pValue));
@@ -301,5 +335,5 @@
 #endif
   PyThreadState_Swap(mainstate);
-  Py_Finalize();
+  Py_Finalize();  
   return res;
 }
Index: /branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/ulinet.c	(revision 896)
@@ -118,5 +118,5 @@
 	;
 #endif
-    tmp=strtok(buffer,";");
+    tmp=strtok((char*) buffer,";"); // knut: added cast to char*
     int cnt=0;
     _HINTERNET *psInternet=(_HINTERNET *)data;
@@ -322,17 +322,31 @@
  * @return 1 if the host is listed as protected, 0 in other case
  */
-int isProtectedHost(const char* protectedHosts,const char* url){
-  char *token, *saveptr;
-  token = strtok_r (url, "//", &saveptr);
-  int cnt=0;
-  char* host;
-  while(token!=NULL && cnt<=1){
-    if(cnt==1 && strstr(protectedHosts,token)!=NULL){
-      return 1;
-    }
-    token = strtok_r (NULL, "/", &saveptr);
-    cnt+=1;
-  }
-  return 0;
+int isProtectedHost(const char* protectedHosts, const char* url) {
+	char *token, *saveptr;
+	int cnt;
+	char* host;
+
+	// knut: make a copy of url since strtok family modifies first argument and cannot be used on constant strings  
+	char* urlcpy = (char*)malloc(sizeof(char)*(strlen(url) + 1));
+	urlcpy = strncpy(urlcpy, url, strlen(url) + 1); // since count > strlen(url), a null character is properly appended
+
+	//token = strtok_r (url, "//", &saveptr);
+	token = strtok_r(urlcpy, "//", &saveptr);   // knut
+	cnt = 0;
+	while (token != NULL && cnt <= 1) {
+		fprintf(stderr, "%s %d %s \n", __FILE__, __LINE__, token);
+		if (cnt == 1)
+			fprintf(stderr, "%s %d %s \n", __FILE__, __LINE__, strstr(protectedHosts, token));
+		fflush(stderr);
+		if (cnt == 1 && strstr(protectedHosts, token) != NULL) {
+			fprintf(stderr, "%s %d %s \n", __FILE__, __LINE__, strstr(protectedHosts, token));
+			free(urlcpy);
+			return 1;
+		}
+		token = strtok_r(NULL, "/", &saveptr);
+		cnt += 1;
+	}
+	free(urlcpy);
+	return 0;
 }
 
@@ -457,5 +471,5 @@
   int ldwFlags=INTERNET_FLAG_NEED_FILE;
   struct MemoryStruct header;
-  map* memUse=getMapFromMaps(conf,"main","memory");
+  map* memUse=getMapFromMaps((maps*) conf,"main","memory"); // knut: addad cast to maps*
 
   hInternet->ihandle[hInternet->nb].handle=curl_easy_init( );
@@ -505,5 +519,5 @@
       map* tmpPath=NULL;
       if(conf!=NULL){
-	tmpPath=getMapFromMaps(conf,"main","tmpPath");
+	tmpPath=getMapFromMaps((maps*) conf,"main","tmpPath"); // knut added cast to maps*
       }
       if(tmpPath==NULL)
Index: /branches/prototype-v0/zoo-project/zoo-kernel/ulinet.h
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/ulinet.h	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/ulinet.h	(revision 896)
@@ -46,11 +46,12 @@
 #endif
 #ifndef __cplusplus
-#ifndef bool
-#define bool int
-#endif
-#ifndef true
-#define true 1
-#define false 0
-#endif
+// knut: see new def of bool in service.h
+//#ifndef bool
+//#define bool int
+//#endif
+//#ifndef true
+//#define true 1
+//#define false 0
+//#endif
 #endif
 
@@ -157,7 +158,8 @@
   typedef size_t* LPDWORD;
 #endif
-#ifndef bool
-#define bool int
-#endif
+// knut: see new definition of bool in service.h
+//#ifndef bool
+//#define bool int
+//#endif
 
 #  define CHECK_INET_HANDLE(h) (h.handle != 0)
Index: /branches/prototype-v0/zoo-project/zoo-kernel/zoo_loader.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/zoo_loader.c	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/zoo_loader.c	(revision 896)
@@ -123,5 +123,5 @@
        if(res!=NULL)
 	 free(res);
-    }else{
+    }else{		
       char *buffer=new char[cgiContentLength+1];
       if(fread(buffer,sizeof(char),cgiContentLength,cgiIn)>0){
@@ -163,5 +163,5 @@
     }	
   }
-  else{
+  else{	  
 #ifdef DEBUG
     dumpMap(tmpMap);
@@ -187,9 +187,9 @@
     cgiStringArrayFree(array);
   }
-
+ 
 #ifdef WIN32
-  map *tmpReq=getMap(tmpMap,"rfile");
-  if(tmpReq!=NULL){
-    FILE *lf=fopen(tmpReq->value,"r");
+  map *tmpReq=getMap(tmpMap,"rfile");  
+  if(tmpReq!=NULL){	  	  
+    FILE *lf=fopen(tmpReq->value,"r");	
     fseek(lf,0,SEEK_END);
     long flen=ftell(lf);
@@ -395,5 +395,5 @@
     }
   }
-
+  
   if(strncasecmp(cgiContentType,"multipart/form-data",19)==0){
     map* tmp=getMap(tmpMap,"dataInputs");
@@ -408,5 +408,5 @@
   if(strQuery!=NULL)
     free(strQuery);
-
+  
   runRequest(&tmpMap);
 
Index: /branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c
===================================================================
--- /branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 895)
+++ /branches/prototype-v0/zoo-project/zoo-kernel/zoo_service_loader.c	(revision 896)
@@ -229,7 +229,9 @@
   fread (tmps1, flen, 1, f2);
 #ifdef WIN32
+  /* knut: I think this block can be dropped; pchr may be NULL if result is not in XML format
   char *pchr=strrchr(tmps1,'>');
   flen=strlen(tmps1)-strlen(pchr)+1;
   tmps1[flen]=0;
+  */
 #endif
   fwrite (tmps1, 1, flen, f3);
@@ -483,6 +485,5 @@
 #endif
 
-  map* libp = getMapFromMaps(m, "main", "libPath");
-
+  map* libp = getMapFromMaps(m, "main", "libPath");  
   if (strlen (r_inputs->value) == 1
       && strncasecmp (r_inputs->value, "C", 1) == 0)
@@ -707,9 +708,9 @@
 #ifdef USE_PYTHON
   if (strncasecmp (r_inputs->value, "PYTHON", 6) == 0)
-    {	  
+    {		  
       *eres =
         zoo_python_support (&m, request_inputs, s1,
                             &request_input_real_format,
-                            &request_output_real_format);
+                            &request_output_real_format);	  
     }
   else
@@ -798,5 +799,5 @@
     }
   *myMap = m;
-  *ioutputs = request_output_real_format;
+  *ioutputs = request_output_real_format;  
 }
 
@@ -2359,5 +2360,5 @@
 	dumpMapsValuesToFiles(&m,&request_input_real_format);
       loadServiceAndRun (&m, s1, request_inputs, &request_input_real_format,
-                         &request_output_real_format, &eres);
+                         &request_output_real_format, &eres);	  
 
 #ifdef META_DB
@@ -2593,5 +2594,5 @@
         }
     }
-
+	
 #ifdef DEBUG
   fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
@@ -2602,6 +2603,5 @@
   rewind(stdout);
 
-  //fprintf(stderr,"%s %d %d\n",__FILE__,__LINE__,eres);
-
+  //fprintf(stderr,"%s %d %d\n",__FILE__,__LINE__,eres);  
   if (eres != -1)
     outputResponse (s1, request_input_real_format,
@@ -2609,5 +2609,5 @@
                     cpid, m, eres);
   fflush (stdout);
-
+  
   /**
    * Ensure that if error occurs when freeing memory, no signal will return
