diff --git a/src/acconfig.h b/src/acconfig.h
index 875f66a88ec7cf9dea0946b0ad912183efb7fb3f..d8dcfdd4f76bdabf88c36548981c8ac5db7fdb82 100644
--- a/src/acconfig.h
+++ b/src/acconfig.h
@@ -65,6 +65,9 @@
 /* Define if you have a working, 8-bit-clean memcmp */
 #undef HAVE_MEMCMP
 
+/* Define if you have gethostname */
+#undef HAVE_GETHOSTNAME
+
 /* Define if you have memmove.  */
 #ifndef __CHECKER__
 #undef HAVE_MEMMOVE
@@ -174,8 +177,18 @@
 /* Define if your cpp supports K&R-style concatenation */
 #undef HAVE_KR_CONCAT
 
+/* Use poll() instead of select() ? */
+#undef HAVE_AND_USE_POLL
+
 @BOTTOM@
 
+/* NT stuff */
+#undef HAVE_GETSYSTEMTIMEASFILETIME
+#undef HAVE_LOADLIBRARY
+#undef HAVE_FREELIBRARY
+#undef HAVE_GETPROCADDRESS
+#undef DL_EXPORT
+
 /* How to set a socket non-blocking */
 #undef USE_IOCTL_FIONBIO
 #undef USE_IOCTLSOCKET_FIONBIO
diff --git a/src/array.c b/src/array.c
index 4cbf089a8d2baa893de37bf07d4c83d1b6565462..3e3e679f73664eaf0747a8f06adc86e84544f35f 100644
--- a/src/array.c
+++ b/src/array.c
@@ -270,6 +270,10 @@ struct array *array_insert(struct array *v,struct svalue *s,INT32 index)
  */
 struct array *resize_array(struct array *a, INT32 size)
 {
+#ifdef DEBUG
+  if(d_flag > 1)  array_check_type_field(a);
+#endif
+
   if(a->size == size) return a;
   if(size > a->size)
   {
@@ -425,6 +429,8 @@ struct array *slice_array(struct array *v,INT32 start,INT32 end)
 #ifdef DEBUG
   if(start > end || end>v->size || start<0)
     fatal("Illegal arguments to slice_array()\n");
+
+  if(d_flag > 1)  array_check_type_field(v);
 #endif
 
   if(start==0 && v->refs==1)	/* Can we use the same array? */
@@ -452,6 +458,8 @@ struct array *friendly_slice_array(struct array *v,INT32 start,INT32 end)
 #ifdef DEBUG
   if(start > end || end>v->size || start<0)
     fatal("Illegal arguments to slice_array()\n");
+
+  if(d_flag > 1)  array_check_type_field(v);
 #endif
 
   a=allocate_array_no_init(end-start,0);
@@ -1288,6 +1296,13 @@ struct array *aggregate_array(INT32 args)
   return a;
 }
 
+struct array *append_array(struct array *a, struct svalue *s)
+{
+  a=resize_array(a,a->size+1);
+  array_set_index(a, a->size-1, s);
+  return a;
+}
+
 struct array *explode(struct pike_string *str,
 		       struct pike_string *del)
 {
@@ -1385,6 +1400,10 @@ struct array *copy_array_recursively(struct array *a,struct processing *p)
   struct processing doing;
   struct array *ret;
 
+#ifdef DEBUG
+  if(d_flag > 1)  array_check_type_field(a);
+#endif
+
   doing.next=p;
   doing.pointer_a=(void *)a;
   for(;p;p=p->next)
@@ -1401,6 +1420,8 @@ struct array *copy_array_recursively(struct array *a,struct processing *p)
   doing.pointer_b=(void *)ret;
 
   copy_svalues_recursively_no_free(ITEM(ret),ITEM(a),a->size,&doing);
+
+  ret->type_field=a->type_field;
   return ret;
 }
 
diff --git a/src/array.h b/src/array.h
index 107f97495449c785b44fc92fe455cd5bb98a1902..c6cb4eaf12d3ac9c50b308de3ed4cdeb79c02e70 100644
--- a/src/array.h
+++ b/src/array.h
@@ -63,7 +63,6 @@ typedef short_cmpfun (*cmpfun_getter)(TYPE_T);
 struct array *low_allocate_array(INT32 size,INT32 extra_space);
 void really_free_array(struct array *v);
 void do_free_array(struct array *a);
-struct array *resize_array(struct array *a, INT32 size);
 void array_index_no_free(struct svalue *s,struct array *v,INT32 index);
 void array_index(struct svalue *s,struct array *v,INT32 index);
 void simple_array_index_no_free(struct svalue *s,
@@ -72,6 +71,7 @@ void array_free_index(struct array *v,INT32 index);
 void array_set_index(struct array *v,INT32 index, struct svalue *s);
 void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s);
 struct array *array_insert(struct array *v,struct svalue *s,INT32 index);
+struct array *resize_array(struct array *a, INT32 size);
 struct array *array_shrink(struct array *v,INT32 size);
 struct array *array_remove(struct array *v,INT32 index);
 INT32 array_search(struct array *v, struct svalue *s,INT32 start);
@@ -119,6 +119,7 @@ void describe_index(struct array *a,
 		    int indent);
 void describe_array(struct array *a,struct processing *p,int indent);
 struct array *aggregate_array(INT32 args);
+struct array *append_array(struct array *a, struct svalue *s);
 struct array *explode(struct pike_string *str,
 		       struct pike_string *del);
 struct pike_string *implode(struct array *a,struct pike_string *del);
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 0712e11149322e6aebae3d1ffb8254c5ab05126a..7290e4fe6927103c508f76512e12384b09c6895b 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.73 1998/02/24 14:51:16 grubba Exp $");
+RCSID("$Id: builtin_functions.c,v 1.74 1998/02/27 08:39:13 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -1986,9 +1986,6 @@ static struct array* diff_build(struct array *a,
    struct array *ad,*bd;
    int bi,ai,lbi,lai,i,eqstart;
 
-   b->refs++;
-   a->refs++;  /* protect from getting optimized... */
-
    /* FIXME(?) memory unfreed upon error here (and later) */
    ad=low_allocate_array(0,32);
    bd=low_allocate_array(0,32);
@@ -2004,27 +2001,22 @@ static struct array* diff_build(struct array *a,
 	 /* insert the equality */
 	 if (lbi>=eqstart)
 	 {
-	    struct array *eq;
-	    eq=slice_array(b,eqstart,lbi+1);
-	    push_array(eq); sp--;
-	    ad=resize_array(ad,ad->size+1);
-	    bd=resize_array(bd,bd->size+1);
-
-	    sp->u.refs[0]++;
-	    ad->item[ad->size-1] = bd->item[bd->size-1] = *sp;
+	    push_array(friendly_slice_array(b,eqstart,lbi+1));
+	    ad=append_array(ad,sp-1);
+	    bd=append_array(bd,sp-1);
+	    pop_stack();
 	 }
 	 /* insert the difference */
 	 lai=ai;
 	 ai=array_search(a,b->item+bi,ai+1)-1;
 
-	 bd=resize_array(bd,bd->size+1);
-	 ad=resize_array(ad,ad->size+1);
-
-	 push_array(slice_array(b,lbi+1,bi));
-	 bd->item[bd->size-1]=*--sp;
+	 push_array(friendly_slice_array(b,lbi+1,bi));
+	 bd=append_array(bd, sp-1);
+	 pop_stack();
 
-	 push_array(slice_array(a,lai+1,ai+1));
-	 ad->item[ad->size-1]=*--sp;
+	 push_array(friendly_slice_array(a,lai+1,ai+1));
+	 ad=append_array(ad,sp-1);
+	 pop_stack();
 
 	 eqstart=bi;
       }
@@ -2034,36 +2026,26 @@ static struct array* diff_build(struct array *a,
 
    if (lbi>=eqstart)
    {
-      struct array *eq;
-      eq=slice_array(b,eqstart,lbi+1);
-      push_array(eq); sp--;
-      ad=resize_array(ad,ad->size+1);
-      bd=resize_array(bd,bd->size+1);
-      
-      sp->u.refs[0]++;
-      ad->item[ad->size-1] = bd->item[bd->size-1] = *sp;
+      push_array(friendly_slice_array(b,eqstart,lbi+1));
+      ad=append_array(ad,sp-1);
+      bd=append_array(bd,sp-1);
+      pop_stack();
    }
 
    if (b->size>bi+1 || a->size>ai+1)
    {
-      ad=resize_array(ad,ad->size+1);
-      bd=resize_array(bd,bd->size+1);
-
-      push_array(slice_array(b,lbi+1,b->size));
-      bd->item[bd->size-1]=*--sp;
+      push_array(friendly_slice_array(b,lbi+1,b->size));
+      bd=append_array(bd, sp-1);
+      pop_stack();
       
-      push_array(slice_array(a,ai+1,a->size));
-      ad->item[ad->size-1]=*--sp;
+      push_array(friendly_slice_array(a,ai+1,a->size));
+      ad=append_array(ad,sp-1);
+      pop_stack();
    }
 
-   b->refs--;
-   a->refs--; /* i know what i'm doing... */
-
    push_array(ad);
    push_array(bd);
-   f_aggregate(2);
-   sp--;
-   return sp->u.array;
+   return aggregate_array(2);
 }
 
 void f_diff(INT32 args)
diff --git a/src/compilation.h b/src/compilation.h
index 70ecf28bc35b26fbcbcec4b9ba1d3bc8d9885ff6..955af80fd5a63b57b0354f49a03de5f748890198 100644
--- a/src/compilation.h
+++ b/src/compilation.h
@@ -88,6 +88,7 @@
   IMEMBER(int,comp_stackp)
   IMEMBER(int,compiler_pass)
   ZMEMBER(int,local_class_counter)
+  ZMEMBER(int,catch_level)
   SEND
 
 #undef PCODE
diff --git a/src/configure.in b/src/configure.in
index 0d51333b4ed6c4826f2d5f58641dd52528c0b283..2b49a2ca507caa084dc3b60fe626d76f3fcb6e99 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1,4 +1,4 @@
-AC_REVISION("$Id: configure.in,v 1.159 1998/02/20 01:05:34 hubbe Exp $")
+AC_REVISION("$Id: configure.in,v 1.160 1998/02/27 08:39:15 hubbe Exp $")
 AC_INIT(interpret.c)
 AC_CONFIG_HEADER(machine.h)
 
@@ -99,6 +99,8 @@ AC_ARG_WITH(ssleay,    [  --without-ssleay       no support for the secure socke
 AC_ARG_WITH(mysql,     [  --without-mysql        no support for the Mysql database],[],[with_mysql=yes])
 AC_ARG_WITH(dmalloc,   [  --with-dmalloc         enable memory-leak tests],[AC_DEFINE(DEBUG_MALLOC)],[])
 AC_ARG_WITH(profiling, [  --with-profiling       add code used to profile pike code ],[AC_DEFINE(PROFILING)],[])
+AC_ARG_WITH(poll,      [  --with-poll            use poll instead of select],[AC_DEFINE(HAVE_AND_USE_POLL)],[])
+AC_ARG_WITH(max-fd,    [  --with-max-fd=X        set how many filedescriptors can be used at once],[pike_cv_max_open_fd=$withval],[])
 
 #
 # Allow --with(out)-debug to toggle both cdebug and rtldebug, but
@@ -950,7 +952,6 @@ AC_CHECK_FUNCS( \
  strtok \
  strtol \
  time \
- GetSystemTimeAsFileTime \
  times \
  vfprintf \
  vsprintf \
@@ -973,6 +974,15 @@ AC_CHECK_FUNCS( \
  initgroups setgroups
 )
 
+if test x$pike_cv_sys_os = xWindows_NT ; then
+ AC_DEFINE(HAVE_LOADLIBRARY)
+ AC_DEFINE(HAVE_FREELIBRARY)
+ AC_DEFINE(HAVE_GETPROCADDRESS)
+ AC_DEFINE(DL_EXPORT, _dlspec(export))
+else
+ AC_DEFINE(DL_EXPORT, [])
+fi
+
 if test $ac_cv_func_crypt$ac_cv_func__crypt = nono ; then
   AC_CHECK_LIB(crypt,crypt,[LIBS="${LIBS} -lcrypt" ; AC_DEFINE(HAVE_CRYPT)],
 [
@@ -990,31 +1000,6 @@ fi
 
 AC_STRUCT_TM
 
-#############################################################################
-AC_MSG_CHECKING(working strcoll)
-AC_CACHE_VAL(pike_cv_func_strcoll,
-[
-AC_TRY_RUN([
-#include <string.h>
-#include <locale.h>
-int main()
-{
-  setlocale(LC_CTYPE, "ISO-8859-1");
-  exit(strcoll("abc", "def") >= 0 ||
-       strcoll("ABC", "DEF") >= 0 ||
-       strcoll("ABC", "ABCD") >= 0 ||
-       strcoll("ABCD", "ABC") <= 0 ||
-       strcoll("*^#", "*^#") != 0 ||
-       strcoll("123", "456") >= 0);
-}
-],pike_cv_func_strcoll=yes,pike_cv_func_strcoll=no,pike_cv_func_strcoll=no)
-])
-
-if test $pike_cv_func_strcoll = yes; then
-  AC_DEFINE(HAVE_STRCOLL)
-fi
-
-AC_MSG_RESULT($pike_cv_func_strcoll)
 #############################################################################
 
 AC_MSG_CHECKING(extern int timezone)
@@ -1312,6 +1297,53 @@ int main()
   exit(0);
 }])
 
+#############################################################################
+MY_CHECK_FUNCTION(GetSystemTimeAsFileTime,
+[
+#include <windows.h>
+#include <winbase.h>
+
+int main()
+{
+  FILETIME f;
+  GetSystemTimeAsFileTime(&f);
+  exit(0);
+}
+])
+#############################################################################
+MY_CHECK_FUNCTION(gethostname,
+[
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+
+int main(int argc, char **argv)
+{
+  char buffer[10000];
+  char *x=gethostname(buffer,sizeof(buffer));
+  exit(0);
+}
+])
+#############################################################################
+MY_CHECK_FUNCTION(strcoll,
+[
+#include <string.h>
+#include <locale.h>
+int main()
+{
+  setlocale(LC_CTYPE, "ISO-8859-1");
+  exit(strcoll("abc", "def") >= 0 ||
+       strcoll("ABC", "DEF") >= 0 ||
+       strcoll("ABC", "ABCD") >= 0 ||
+       strcoll("ABCD", "ABC") <= 0 ||
+       strcoll("*^#", "*^#") != 0 ||
+       strcoll("123", "456") >= 0);
+}
+])
+
 ########################################################################
 
 MY_CHECK_FUNCTION(memmem,
@@ -1810,6 +1842,7 @@ then
 	OpenBSD*) LDSHARED="ld -Bshareable";;
 	SCO_SV*) LDSHARED="cc -G -KPIC -Wl,-Bexport";;
 	UNIX_SV) LDSHARED="ld -G";;
+        Windows_NT*) LDSHARED="$CC -shared";;
 	*) LDSHARED="ld";;
 	esac
 fi
@@ -1827,6 +1860,7 @@ if test -z "$CCSHARED" ; then
 	FreeBSD*) CCSHARED="-fpic";;
 	SCO_SV*) CCSHARED="-KPIC -dy -Bdynamic";;
 	Solaris*) CCSHARED="-KPIC -Bdynamic";;
+        Windows_NT*) CCSHARED="-shared" ;;
     esac
   fi
 fi
@@ -1839,6 +1873,7 @@ AC_CACHE_VAL(pike_cv_sys_linkforshared,[
 # the pike executable -- this is only needed for a few systems
 if test -z "$LINKFORSHARED"
 then
+  LINKFORSHARED=""
   if test "$GCC" = yes ; then
     case $pike_cv_sys_os in
 	AIX*)	LINKFORSHARED="-Wl,-bexpall -Wl,-brtl";;
@@ -1939,7 +1974,9 @@ AC_SUBST(DEBUGDEF)
 AC_SUBST(ac_configure_args)
 
 if test x$ac_cv_func_dlopen$ac_cv_func_dld_link = xnono ; then
-  with_dynamic_modules=no
+  if test x$pike_cv_sys_os != xWindows_NT ; then
+    with_dynamic_modules=no
+  fi
 fi
 
 if test x$with_dynamic_modules = xyes ; then
diff --git a/src/dynamic_load.c b/src/dynamic_load.c
index b5a9ce8463543e674405b7af32cdb698b318f3c2..7fabc497766216982f7de10f28f55c75cd7f892a 100644
--- a/src/dynamic_load.c
+++ b/src/dynamic_load.c
@@ -8,14 +8,73 @@
 #  include "pike_macros.h"
 #endif
 
-#if !defined(HAVE_DLOPEN) && defined(HAVE_DLD_LINK) && defined(HAVE_DLD_GET_FUNC)
+#if !defined(HAVE_DLOPEN)
+
+#if defined(HAVE_DLD_LINK) && defined(HAVE_DLD_GET_FUNC)
 #define USE_DLD
+#define HAVE_SOME_DLOPEN
+#define EMULATE_DLOPEN
+#else
+#if defined(HAVE_LOADLIBRARY) && defined(HAVE_FREELIBRARY) && \
+    defined(HAVE_GETPROCADDRESS) && defined(HAVE_WINBASE_H)
+#define USE_LOADLIBRARY
+#define HAVE_SOME_DLOPEN
+#define EMULATE_DLOPEN
+#endif
+#endif
+#else
+#define HAVE_SOME_DLOPEN
 #endif
 
-#if defined(HAVE_DLOPEN) || defined(USE_DLD)
+
+#ifdef HAVE_SOME_DLOPEN
 
 typedef void (*modfun)(void);
 
+#ifdef USE_LOADLIBRARY
+#include <windows.h>
+
+static TCHAR *convert_string(char *str, int len)
+{
+  int e;
+  TCHAR *ret=(TCHAR *)xalloc((len+1) * sizeof(TCHAR));
+  for(e=0;e<len;e++) ret[e]=EXTRACT_UCHAR(str+e);
+  ret[e]=0;
+  return ret;
+}
+
+static void *dlopen(char *foo, int how)
+{
+  TCHAR *tmp;
+  HINSTANCE ret;
+  tmp=convert_string(foo, strlen(foo));
+  ret=LoadLibrary(tmp);
+  free((char *)tmp);
+  return (void *)ret;
+}
+
+static char * dlerror(void)
+{
+  static char buffer[200];
+  sprintf(buffer,"LoadLibrary failed with error: %d",GetLastError());
+  return buffer;
+}
+
+static void *dlsym(void *module, char * function)
+{
+  return (void *)GetProcAddress((HMODULE)module,
+				function);
+}
+
+static void dlclose(void *module)
+{
+  FreeLibrary((HMODULE)module);
+}
+
+#define dlinit()
+
+#endif
+
 #ifdef USE_DLD
 #include <dld.h>
 static void *dlopen(char *foo, int how)
@@ -57,7 +116,10 @@ static void dlinit(void)
 }
 
 
-#else
+#endif
+
+#ifndef EMULATE_DLOPEN
+
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
diff --git a/src/interpret.c b/src/interpret.c
index bbfc97f72f34b5e372e46c6985bb3900100d2f90..42f5f4112f538796ac9000f0868c6d8647f6311e 100644
--- a/src/interpret.c
+++ b/src/interpret.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: interpret.c,v 1.68 1998/02/03 23:12:26 hubbe Exp $");
+RCSID("$Id: interpret.c,v 1.69 1998/02/27 08:39:17 hubbe Exp $");
 #include "interpret.h"
 #include "object.h"
 #include "program.h"
@@ -365,21 +365,6 @@ void print_return_value(void)
 #define print_return_value()
 #endif
 
-
-void pop_n_elems(INT32 x)
-{
-  if(!x) return;
-#ifdef DEBUG
-  if(sp - evaluator_stack < x)
-    fatal("Popping out of stack.\n");
-
-  if(x < 0) fatal("Popping negative number of args....\n");
-#endif
-  sp-=x;
-  free_svalues(sp,x,BIT_MIXED);
-}
-
-
 struct callback_list evaluator_callbacks;
 
 #ifdef DEBUG
@@ -513,7 +498,7 @@ static int eval_instruction(unsigned char *pc)
 #ifdef DEBUG
     if(d_flag)
     {
-#ifdef _REENTRANT
+#if defined(_REENTRANT) && !defined(__NT__)
       if(!mt_trylock(& interpreter_lock))
 	fatal("Interpreter running unlocked!\n");
 #endif
diff --git a/src/interpret.h b/src/interpret.h
index 7c3b0da92956599dda5d77b3cf3cd931397d7018..caf4f79c1022bfd6989db4f430796861b84e41ae 100644
--- a/src/interpret.h
+++ b/src/interpret.h
@@ -28,12 +28,22 @@ struct frame
 
 #ifdef DEBUG
 #define debug_check_stack() do{if(sp<evaluator_stack)fatal("Stack error.\n");}while(0)
+#define check__positive(X,Y) if((X)<0) fatal(Y)
+#include "error.h"
 #else
+#define check__positive(X,Y)
 #define debug_check_stack() 
 #endif
 
 #define pop_stack() do{ free_svalue(--sp); debug_check_stack(); }while(0)
 
+#define pop_n_elems(X)						\
+ do { int x_=(X); if(x_) { 					\
+   check__positive(x_,"Popping negative number of args....\n");	\
+   sp-=x_; debug_check_stack();					\
+  free_svalues(sp,x_,BIT_MIXED);				\
+ } } while (0)
+
 #define push_program(P) do{ struct program *_=(P); debug_malloc_touch(_); sp->u.program=_; sp++->type=T_PROGRAM; }while(0)
 #define push_int(I) do{ INT32 _=(I); sp->u.integer=_;sp->type=T_INT;sp++->subtype=NUMBER_NUMBER; }while(0)
 #define push_mapping(M) do{ struct mapping *_=(M); debug_malloc_touch(_); sp->u.mapping=_; sp++->type=T_MAPPING; }while(0)
@@ -117,7 +127,6 @@ void lvalue_to_svalue_no_free(struct svalue *to,struct svalue *lval);
 void assign_lvalue(struct svalue *lval,struct svalue *from);
 union anything *get_pointer_if_this_type(struct svalue *lval, TYPE_T t);
 void print_return_value(void);
-void pop_n_elems(INT32 x);
 void reset_evaluator(void);
 struct backlog;
 void dump_backlog(void);
diff --git a/src/language.yacc b/src/language.yacc
index 2ef3d02d0178a6486b54e53f1bf4b94178e5b6e6..88b469763de56bdd029bbccf11b34e47d1b5ea00 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -162,7 +162,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.60 1998/02/24 23:01:28 hubbe Exp $");
+RCSID("$Id: language.yacc,v 1.61 1998/02/27 08:39:19 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -1421,7 +1421,15 @@ catch_arg: '(' comma_expr ')'  { $$=$2; }
   | block
   ; 
 
-catch: F_CATCH catch_arg { $$=mknode(F_CATCH,$2,NULL); } ;
+catch: F_CATCH
+     {
+       catch_level++;
+     }
+     catch_arg
+     {
+       $$=mknode(F_CATCH,$3,NULL);
+       catch_level--;
+      } ;
 
 sscanf: F_SSCANF '(' expr0 ',' expr0 lvalue_list ')'
   {
diff --git a/src/las.c b/src/las.c
index d3596454d8dd5f41309cc80cb20b5f2bbe240d34..2d98cc82b8d17ce46f2879f486ec8c94a748d5ee 100644
--- a/src/las.c
+++ b/src/las.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: las.c,v 1.52 1998/02/24 23:01:29 hubbe Exp $");
+RCSID("$Id: las.c,v 1.53 1998/02/27 08:39:20 hubbe Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -1405,18 +1405,12 @@ void fix_type_field(node *n)
     break;
 
   case F_INDEX:
-    type_a=CAR(n)->type;
-    type_b=CDR(n)->type;
-    if(!check_indexing(type_a, type_b, n))
-      my_yyerror("Indexing on illegal type.");
-    n->type=index_type(type_a,n);
-    break;
-
   case F_ARROW:
     type_a=CAR(n)->type;
     type_b=CDR(n)->type;
     if(!check_indexing(type_a, type_b, n))
-      my_yyerror("Indexing on illegal type.");
+      if(!catch_level)
+        my_yyerror("Indexing on illegal type.");
     n->type=index_type(type_a,n);
     break;
 
@@ -1479,7 +1473,7 @@ void fix_type_field(node *n)
 
       if(max_args < args)
       {
-	my_yyerror("Too many arguments to %s. (%d %d)\n",name,max_args,args);
+	my_yyerror("Too many arguments to %s.\n",name);
       }
       else if(max_correct_args == args)
       {
@@ -2107,18 +2101,21 @@ int eval_low(node *n)
     if(apply_low_safe_and_stupid(fake_object, jump))
     {
       /* Generate error message */
-      if(throw_value.type == T_ARRAY && throw_value.u.array->size)
+      if(!catch_level)
       {
-	union anything *a;
-	a=low_array_get_item_ptr(throw_value.u.array, 0, T_STRING);
-	if(a)
-	{
-	  yyerror(a->string->str);
+        if(throw_value.type == T_ARRAY && throw_value.u.array->size)
+        {
+	  union anything *a;
+	  a=low_array_get_item_ptr(throw_value.u.array, 0, T_STRING);
+	  if(a)
+	  {
+	    yyerror(a->string->str);
+	  }else{
+	    yyerror("Nonstandard error format.");
+	  }
 	}else{
 	  yyerror("Nonstandard error format.");
 	}
-      }else{
-	yyerror("Nonstandard error format.");
       }
     }else{
       if(foo.yes)
@@ -2162,11 +2159,17 @@ static node *eval(node *n)
     break;
 
   case 0:
+    if(catch_level) return n;
     free_node(n);
     n=0;
     break;
 
   case 1:
+    if(catch_level && IS_ZERO(sp-1))
+    {
+      pop_stack();
+      return n;
+    }
     free_node(n);
     n=mksvaluenode(sp-1);
     pop_stack();
diff --git a/src/main.c b/src/main.c
index 4f6a80e22236837f3be87b863cd1e8324283d920..0c20d37ffe9037f5fc964c77047db7d4f2a3df52 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: main.c,v 1.41 1998/02/11 00:05:01 hubbe Exp $");
+RCSID("$Id: main.c,v 1.42 1998/02/27 08:39:20 hubbe Exp $");
 #include "fdlib.h"
 #include "backend.h"
 #include "module.h"
@@ -109,23 +109,27 @@ int dbm_main(int argc, char **argv)
 #if __NT__
   if(!master_file)
   {
+    HKEY k;
     char buffer[4096];
     DWORD len=sizeof(buffer)-1,type=REG_SZ;
-    
-    if(RegQueryValueEx(HKEY_CURRENT_USER,
-		       "SOFTWARE\\Idonex\\Pike\\0.6\\PIKE_MASTER",
-		       0,
-		       &type,
-		       buffer,
-		       &len)==ERROR_SUCCESS ||
-       RegQueryValueEx(HKEY_LOCAL_MACHINE,
-		       "SOFTWARE\\Idonex\\Pike\\0.6\\PIKE_MASTER",
-		       0,
-		       &type,
-		       buffer,
-		       &len)==ERROR_SUCCESS)
+    long ret;
+    if(RegOpenKeyEx(HKEY_CURRENT_USER,
+		     (LPCTSTR)"SOFTWARE\\Idonex\\Pike\\0.6",
+		     0,KEY_READ,&k)==ERROR_SUCCESS ||
+       RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+		    (LPCTSTR)"SOFTWARE\\Idonex\\Pike\\0.6",
+		    0,KEY_READ,&k)==ERROR_SUCCESS)
     {
-      master_file=strdup(buffer);
+      if(RegQueryValueEx(k,
+			 "PIKE_MASTER",
+			 0,
+			 &type,
+			 buffer,
+			 &len)==ERROR_SUCCESS)
+      {
+	master_file=strdup(buffer);
+      }
+      RegCloseKey(k);
     }
   }
 #endif
diff --git a/src/modules/Makefile.in b/src/modules/Makefile.in
index f63dde70bcc5d6cf591f40c2b82f97da761f330a..2de628b58b5825fd991d4cbb918de1b301cf18b3 100644
--- a/src/modules/Makefile.in
+++ b/src/modules/Makefile.in
@@ -2,7 +2,7 @@
 
 CC=@CC@
 CPP=@CPP@
-
+SRCDIR=@srcdir@
 AR=@AR@
 
 MODULES=@subdirs@
@@ -46,4 +46,11 @@ verify:
 verbose_verify:
 	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) MODNAME=$$a verbose_verify ) || exit $$? ; done
 
+testsuites:
+	for a in $(MODULES) ; do $(TMP_BINDIR)/mktestsuite $(SRCDIR)/$$a/testsuite.in >$$a/module_testsuite -DSRCDIR=$(SRCDIR)/$$a  || exit $$? ; done
+
+extra_tests:
+	for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) MODNAME=$$a extra_tests ) || exit $$? ; done
+
+
 @dependencies@
diff --git a/src/modules/dynamic_module_makefile.in b/src/modules/dynamic_module_makefile.in
index c8e3e2e3a974415f415dea0b0be1ff4f0c5c7909..688cd11b90e0dce6108a38b69c58fb57fd15cefe 100644
--- a/src/modules/dynamic_module_makefile.in
+++ b/src/modules/dynamic_module_makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id: dynamic_module_makefile.in,v 1.30 1998/02/20 00:43:16 hubbe Exp $
+# $Id: dynamic_module_makefile.in,v 1.31 1998/02/27 08:40:57 hubbe Exp $
 #
 
 
@@ -55,6 +55,8 @@ depend:
 module_testsuite: $(SRCDIR)/testsuite.in
 	$(TMP_BINDIR)/mktestsuite $(SRCDIR)/testsuite.in >module_testsuite -DSRCDIR=$(SRCDIR) 
 
+extra_tests: $(MODULE_TESTS)
+
 verify: module_testsuite  $(MODULE_TESTS)
 	$(RUNPIKE) $(TMP_BINDIR)/test_pike.pike module_testsuite
 
diff --git a/src/modules/spider/dumudp.c b/src/modules/spider/dumudp.c
index 2cea665ab0c784cf269e8e49cba0bd4df1ef9272..2877948236079f1a2919b333b2ef4ffbd4a6f48d 100644
--- a/src/modules/spider/dumudp.c
+++ b/src/modules/spider/dumudp.c
@@ -1,7 +1,7 @@
 #include "config.h"
 
 #include "global.h"
-RCSID("$Id: dumudp.c,v 1.33 1998/02/11 01:10:57 hubbe Exp $");
+RCSID("$Id: dumudp.c,v 1.34 1998/02/27 08:41:20 hubbe Exp $");
 #include "fdlib.h"
 #include "interpret.h"
 #include "svalue.h"
@@ -105,7 +105,7 @@ static void udp_bind(INT32 args)
   if(FD != -1)
   {
     set_read_callback( FD, 0, 0 );
-    fd_close(FD);	/* Shouldn't this be some other taste of close()? */
+    fd_close(FD);	/* Shouldn't this be some other taste of close()? No - Hubbe */
     FD = -1;
   }
 
@@ -120,7 +120,7 @@ static void udp_bind(INT32 args)
   o=1;
   if(fd_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&o, sizeof(int)) < 0)
   {
-    close(fd);
+    fd_close(fd);
     error("setsockopt failed\n");
     return;
   }
@@ -140,7 +140,7 @@ static void udp_bind(INT32 args)
 
   if(tmp)
   {
-    close(fd);
+    fd_close(fd);
     pop_n_elems(args);
     push_int(0);
     return;
diff --git a/src/modules/static_module_makefile.in b/src/modules/static_module_makefile.in
index 9d8d370af8fb4ecc291742d936907d66abf51a34..e9608e0484a021d3b94fcf359ce1d185255f016d 100644
--- a/src/modules/static_module_makefile.in
+++ b/src/modules/static_module_makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id: static_module_makefile.in,v 1.24 1998/02/20 00:43:17 hubbe Exp $
+# $Id: static_module_makefile.in,v 1.25 1998/02/27 08:40:57 hubbe Exp $
 #
 
 
@@ -63,6 +63,8 @@ depend:
 module_testsuite: $(SRCDIR)/testsuite.in
 	$(TMP_BINDIR)/mktestsuite $(SRCDIR)/testsuite.in >module_testsuite -DSRCDIR=$(SRCDIR) 
 
+extra_tests: $(MODULE_TESTS)
+
 verify: module_testsuite $(MODULE_TESTS)
 	$(RUNPIKE) $(TMP_BINDIR)/test_pike.pike module_testsuite
 
diff --git a/src/modules/system/system.c b/src/modules/system/system.c
index e783b8b84fa36c6a5b523fb99e6d32fafa70c1cb..918f9bfce86f19201522ac0d4a023acf66d4e90e 100644
--- a/src/modules/system/system.c
+++ b/src/modules/system/system.c
@@ -1,5 +1,5 @@
 /*
- * $Id: system.c,v 1.41 1998/02/11 01:12:54 hubbe Exp $
+ * $Id: system.c,v 1.42 1998/02/27 08:41:45 hubbe Exp $
  *
  * System-call module for Pike
  *
@@ -14,7 +14,7 @@
 #include "system.h"
 
 #include "global.h"
-RCSID("$Id: system.c,v 1.41 1998/02/11 01:12:54 hubbe Exp $");
+RCSID("$Id: system.c,v 1.42 1998/02/27 08:41:45 hubbe Exp $");
 #ifdef HAVE_WINSOCK_H
 #include <winsock.h>
 #endif
@@ -871,6 +871,76 @@ static void f_cp(INT32 args)
   pop_n_elems(args);
   push_int(ret);
 }
+
+void f_RegGetValue(INT32 args)
+{
+  long ret;
+  INT32 hkey;
+  HKEY new_key;
+  char *key, *ind;
+  DWORD len,type;
+  char buffer[8192];
+  len=sizeof(buffer)-1;
+  get_all_args("RegQueryValue",args,"%d%s%s",&hkey,&key,&ind);
+  ret=RegOpenKeyEx((HKEY)hkey, (LPCTSTR)key, 0, KEY_READ,  &new_key);
+  if(ret != ERROR_SUCCESS)
+    error("RegOpenKeyEx failed with error %d\n",ret);
+
+  ret=RegQueryValueEx(new_key,ind, 0, &type, buffer, &len);
+  RegCloseKey(new_key);
+
+  if(ret==ERROR_SUCCESS)
+  {
+    pop_n_elems(args);
+    switch(type)
+    {
+      case REG_RESOURCE_LIST:
+      case REG_NONE:
+      case REG_LINK:
+      case REG_BINARY:
+	push_string(make_shared_binary_string(buffer,len));
+	break;
+
+      case REG_SZ:
+	push_string(make_shared_binary_string(buffer,len-1));
+	break;
+
+      case REG_EXPAND_SZ:
+	type=ExpandEnvironmentStrings((LPCTSTR)buffer,
+				      buffer+len,
+				      sizeof(buffer)-len-1);
+	if(type>sizeof(buffer)-len-1 || !type)
+	  error("RegGetValue: Failed to expand data.\n");
+	push_string(make_shared_string(buffer+len));
+	break;
+
+      case REG_MULTI_SZ:
+	push_string(make_shared_binary_string(buffer,len-1));
+	push_string(make_shared_binary_string("\000",1));
+	f_divide(2);
+	break;
+
+      case REG_DWORD_LITTLE_ENDIAN:
+	push_int(EXTRACT_UCHAR(buffer)+
+	  (EXTRACT_UCHAR(buffer+1)<<1)+
+	  (EXTRACT_UCHAR(buffer+2)<<2)+
+	  (EXTRACT_UCHAR(buffer+3)<<3));
+	break;
+
+      case REG_DWORD_BIG_ENDIAN:
+	push_int(EXTRACT_UCHAR(buffer+3)+
+	  (EXTRACT_UCHAR(buffer+2)<<1)+
+	  (EXTRACT_UCHAR(buffer+1)<<2)+
+	  (EXTRACT_UCHAR(buffer)<<3));
+	break;
+
+      default:
+	error("RegGetValue: cannot handle this data type.\n");
+    }
+  }else{
+    error("RegQueryValueEx failed with error %d\n",ret);
+  }
+}
 #endif
 
 /*
@@ -997,6 +1067,14 @@ void pike_module_init(void)
 
 #ifdef __NT__
   add_function("cp",f_cp,"function(string,string:int)", 0);
+#define ADD_GLOBAL_INTEGER_CONSTANT(X,Y) \
+   push_int((long)(Y)); low_add_constant(X,sp-1); pop_stack();
+
+  ADD_GLOBAL_INTEGER_CONSTANT("HKEY_LOCAL_MACHINE",HKEY_LOCAL_MACHINE);
+  ADD_GLOBAL_INTEGER_CONSTANT("HKEY_CURRENT_USER",HKEY_CURRENT_USER);
+  ADD_GLOBAL_INTEGER_CONSTANT("HKEY_USERS",HKEY_USERS);
+  ADD_GLOBAL_INTEGER_CONSTANT("HKEY_CLASSES_ROOT",HKEY_CLASSES_ROOT);
+  add_efun("RegGetValue",f_RegGetValue,"function(int,string,string:string|int|string*)",OPT_EXTERNAL_DEPEND);
 #endif
 }
 
diff --git a/src/program.c b/src/program.c
index a1647e69c327ea26e1b25bc8bbe8d24577f276c8..7ccef474a82852d8873ed7ffbd400c9d6b13e0cb 100644
--- a/src/program.c
+++ b/src/program.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: program.c,v 1.63 1998/02/24 23:01:32 hubbe Exp $");
+RCSID("$Id: program.c,v 1.64 1998/02/27 08:39:21 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -98,6 +98,7 @@ struct program *malloc_size_program=0;
 int compiler_pass;
 int compilation_depth;
 long local_class_counter;
+int catch_level;
 struct compiler_frame *compiler_frame=0;
 static INT32 last_line = 0;
 static INT32 last_pc = 0;
diff --git a/src/program.h b/src/program.h
index 8582ceddcd72b73c70a962b1d0375ee26701da3a..de40cfdbc92a2c46223c6561a3b1815bce0a09c3 100644
--- a/src/program.h
+++ b/src/program.h
@@ -221,6 +221,9 @@ extern struct program *new_program;
 extern struct program *first_program;
 extern int compiler_pass;
 extern long local_class_counter;
+extern int catch_level;
+
+#define COMPILER_IN_CATCH 1
 
 #define FOO(NUMTYPE,TYPE,NAME) void PIKE_CONCAT(add_to_,NAME(TYPE ARG));
 #include "program_areas.h"