diff --git a/src/configure.in b/src/configure.in
index 1afb08704784186d9bcfb28e6d3f587943775c68..3c7b62b93638b40a98ffe0e9668cff4eaae88f74 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1,4 +1,4 @@
-AC_REVISION("$Id: configure.in,v 1.91 1997/04/22 09:18:47 hubbe Exp $")
+AC_REVISION("$Id: configure.in,v 1.92 1997/04/23 01:59:40 hubbe Exp $")
 AC_INIT(interpret.c)
 AC_CONFIG_HEADER(machine.h)
 
@@ -959,7 +959,7 @@ dnl#####################################################################
 
 define(MY_CHECK_FUNCTION,[
 AC_MSG_CHECKING(for working $1)
-AC_CACHE_VAL(pike_cv_have_func_$1,[
+AC_CACHE_VAL(pike_cv_func_$1,[
 AC_TRY_RUN([$2],pike_cv_func_$1=yes,pike_cv_func_$1=no)
 AC_MSG_RESULT([$]pike_cv_func_$1)
 if test [$]pike_cv_func_$1 = yes; then
diff --git a/src/language.yacc b/src/language.yacc
index b3fad0b28136edfdda7154f1ac6e831c05624be8..9ce0b27ab7032a05e1f636b2b69b2edebeea04ab 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -157,7 +157,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.37 1997/04/20 19:29:24 hubbe Exp $");
+RCSID("$Id: language.yacc,v 1.38 1997/04/23 01:59:41 hubbe Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -269,6 +269,7 @@ void fix_comp_stack(int sp)
 %type <number> F_WHILE
 %type <number> arguments
 %type <number> arguments2
+%type <number> func_args
 %type <number> assign
 %type <number> modifier
 %type <number> modifier_list
@@ -483,7 +484,7 @@ def: modifiers type_or_error optional_stars F_IDENTIFIER '(' arguments ')'
     int e;
     /* construct the function type */
     push_finished_type(local_variables->current_type);
-    while($3--) push_type(T_ARRAY);
+    while(--$3>=0) push_type(T_ARRAY);
     
     if(local_variables->current_return_type)
       free_string(local_variables->current_return_type);
@@ -550,7 +551,7 @@ def: modifiers type_or_error optional_stars F_IDENTIFIER '(' arguments ')'
   | import {}
   | constant {}
   | class { free_node($1); }
-  | error 
+  | error ';'
   {
     reset_type_stack();
     if(num_parse_error>5) YYACCEPT;
@@ -585,6 +586,10 @@ new_arg_name: type optional_dot_dot_dot optional_identifier
   }
   ;
 
+func_args: '(' arguments ')' { $$=$2; }
+         | error ')' { $$=0; }
+         ;
+
 arguments: /* empty */ optional_comma { $$=0; }
   | arguments2 optional_comma { $$=$1; }
   ;
@@ -836,7 +841,7 @@ lambda: F_LAMBDA
       free_string(local_variables->current_return_type);
     copy_shared_string(local_variables->current_return_type,any_type_string);
   }
-  '(' arguments ')' block
+  func_args block
   {
     struct pike_string *type;
     char buf[40];
@@ -848,7 +853,7 @@ lambda: F_LAMBDA
     
     push_type(T_MIXED);
     
-    e=$4-1;
+    e=$3-1;
     if(varargs)
     {
       push_finished_type(local_variables->variable[e].type);
@@ -871,21 +876,26 @@ lambda: F_LAMBDA
     name=make_shared_string(buf);
 
     f=dooptcode(name,
-	      mknode(F_ARG_LIST,$6,mknode(F_RETURN,mkintnode(0),0)),
+	      mknode(F_ARG_LIST,$4,mknode(F_RETURN,mkintnode(0),0)),
 	      type,
 	      0);
     free_string(name);
     free_string(type);
+    comp_stackp=$<number>2;
     pop_locals();
     $$=mkidentifiernode(f);
   }
   ;
 
-class: modifiers F_CLASS optional_identifier '{'
+failsafe_program: '{' program '}'
+                | error
+                ;
+
+class: modifiers F_CLASS optional_identifier
   {
     start_new_program();
   }
-  program '}'
+  failsafe_program
   {
     struct svalue s;
     s.u.program=end_program();
diff --git a/src/modules/call_out/Makefile.in b/src/modules/call_out/Makefile.in
index d31956b2403f38fed257d814b0ca34e43baf9399..4a6d70ec6928f8ccab4c76a5b289ea20c94f1afc 100644
--- a/src/modules/call_out/Makefile.in
+++ b/src/modules/call_out/Makefile.in
@@ -2,6 +2,11 @@ SRCDIR=@srcdir@
 VPATH=@srcdir@:@srcdir@/../..:../..
 OBJS=call_out.o
 MODULE_LDFLAGS=@LIBS@
+MODULE_TESTS=local_tests
 
 @static_module_makefile@
+
+local_tests:
+	$(RUNPIKE) $(SRCDIR)/test_co.pike
+
 @dependencies@
diff --git a/src/modules/call_out/call_out.c b/src/modules/call_out/call_out.c
index d0fb9cf09b89d4c29604a587f5e646d3f9171e3f..8fa5550856b2adca71742c58828fb87910eb0fe3 100644
--- a/src/modules/call_out/call_out.c
+++ b/src/modules/call_out/call_out.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: call_out.c,v 1.9 1997/04/12 09:52:45 per Exp $");
+RCSID("$Id: call_out.c,v 1.10 1997/04/23 02:00:34 hubbe Exp $");
 #include "array.h"
 #include "dynamic_buffer.h"
 #include "object.h"
@@ -63,7 +63,7 @@ static void verify_call_outs()
     if(e)
     {
       if(CMP(e, PARENT(e)))
-	fatal("Error in call out heap.\n");
+	fatal("Error in call out heap. (@ %d)\n",e);
     }
     
     if(!(v=CALL(e).args))
@@ -98,6 +98,10 @@ static int adjust_up(int pos)
 {
   int parent=PARENT(pos);
   int from;
+#ifdef DEBUG
+  if(pos <0 || pos>=num_pending_calls)
+    fatal("Bad argument to adjust_up(%d)\n",pos);
+#endif
   if(!pos) return 0;
 
   if(CMP(pos, parent))
@@ -105,13 +109,14 @@ static int adjust_up(int pos)
     SWAP(pos, parent);
     from=pos;
     pos=parent;
-    while(pos && CMP(pos, parent=PARENT(pos)))
+    while(pos && CMP(pos, PARENT(pos)))
     {
+      parent=PARENT(pos);
       SWAP(pos, parent);
       from=pos;
       pos=parent;
     }
-    from^=1;
+    from+=from&1 ? 1 : -1;
     if(from < num_pending_calls && CMP(from, pos))
     {
       SWAP(from, pos);
@@ -354,8 +359,12 @@ void f_remove_call_out(INT32 args)
     free_array(CALL(e).args);
     if(CALL(e).caller)
       free_object(CALL(e).caller);
-    CALL(e)=CALL(--num_pending_calls);
-    adjust(e);
+    --num_pending_calls;
+    if(e!=num_pending_calls)
+    {
+      CALL(e)=CALL(num_pending_calls);
+      adjust(e);
+    }
   }else{
     pop_n_elems(args);
     sp->type=T_INT;
diff --git a/src/modules/call_out/test_co.pike b/src/modules/call_out/test_co.pike
new file mode 100644
index 0000000000000000000000000000000000000000..ecf5ce482b6c87492be16eabf8653db1a733f0f2
--- /dev/null
+++ b/src/modules/call_out/test_co.pike
@@ -0,0 +1,123 @@
+#!/usr/local/bin/pike
+
+void verify();
+
+mapping fc=([]);
+
+int cnt;
+
+#define FUN(X) void X() \
+{ \
+  fc[X]--; \
+  if(!(++cnt & 15)) { verify(); werror("."); } \
+}
+
+FUN(f0)
+FUN(f1)
+FUN(f2)
+FUN(f3)
+FUN(f4)
+FUN(f5)
+FUN(f6)
+FUN(f7)
+FUN(f8)
+FUN(f9)
+
+
+mixed *fn=({f0,f1,f2,f3,f4,f5,f6,f7,f8,f9});
+
+void verify()
+{
+  mapping ff=([]);
+  foreach(call_out_info(), mixed f) ff[f[2]]++;
+  foreach(fn, mixed f)
+  {
+    if(fc[f] != ff[f])
+    {
+      werror("Incorrect number of call outs!\n");
+      werror(sprintf("%O != %O\n",fc,ff));
+      exit(1);
+    }
+  }
+  if(!sizeof(ff)) exit(0);
+}
+
+mixed co(mixed func, mixed ... args)
+{
+  mixed ret;
+  fc[func]++;
+  ret=call_out(func,@args);
+  return ret;
+}
+
+mixed rco(mixed func)
+{
+  mixed ret;
+  if(zero_type(ret=remove_call_out(func))!=1)
+  {
+    if(arrayp(func))
+    {
+      fc[func[0]]--;
+    }else{
+      fc[func]--;
+    }
+  }
+  return ret;
+}
+
+void do_remove()
+{
+  fc[do_remove]--;
+  werror("\nRemoving call outs ");
+  for(int d=0;d<50;d++)
+  {
+    for(int e=0;e<200;e++)
+      rco(fn[random(10)]);
+    
+    verify();
+    werror(".");
+  }
+  werror("\nWaiting to exit \n");
+  call_out(exit,5,30,1);
+}
+
+int main()
+{
+  random_seed(0);
+  write("Creating call outs ");
+  for(int d=0;d<50;d++)
+  {
+    for(int e=0;e<100;e++)
+    {
+      co(fn[random(10)],random(1000)/100.0);
+    }
+    werror(".");
+    verify();
+  }
+
+  werror("\nTesting end of heap ...");
+
+  verify();
+
+  mixed *tmp=allocate(100);
+  for(int e=0;e<sizeof(tmp);e++) tmp[e]=co(f0,50.0);
+
+  verify();
+
+  for(int e=0;e<sizeof(tmp);e++)
+  {
+    if(zero_type(rco(tmp[e]))==1)
+    {
+      werror("Remove call out failed!!!\n");
+      exit(1);
+    }
+  }
+
+  verify();
+  
+  werror("\nWaiting ");
+
+  co(do_remove,1.0);
+  
+  return -17;
+}
diff --git a/src/modules/dynamic_module_makefile.in b/src/modules/dynamic_module_makefile.in
index a8f6cb7b99e07b391c8227d468564f1ea20cd9b4..3c13547e16880286027d2b3b597ff46ea1cdd607 100644
--- a/src/modules/dynamic_module_makefile.in
+++ b/src/modules/dynamic_module_makefile.in
@@ -37,10 +37,10 @@ depend:
 module_testsuite: $(SRCDIR)/testsuite.in
 	$(TMP_BINDIR)/mktestsuite $(SRCDIR)/testsuite.in >module_testsuite -DSRCDIR=$(SRCDIR) 
 
-verify: module_testsuite
+verify: module_testsuite  $(MODULE_TESTS)
 	$(RUNPIKE) $(TMP_BINDIR)/test_pike.pike module_testsuite
 
-verbose_verify: module_testsuite
+verbose_verify: module_testsuite  $(MODULE_TESTS)
 	$(RUNPIKE) $(TMP_BINDIR)/test_pike.pike module_testsuite --verbose
 
 gdb_verify: module_testsuite
diff --git a/src/modules/files/Makefile.in b/src/modules/files/Makefile.in
index fbb34967a25835019bb4500675503a4debe9e8c7..66913b89b26b81e5f5db4875def8ea674e0c8bf8 100644
--- a/src/modules/files/Makefile.in
+++ b/src/modules/files/Makefile.in
@@ -2,6 +2,11 @@ SRCDIR=@srcdir@
 VPATH=@srcdir@:@srcdir@/../..:../..
 OBJS=file.o efuns.o socket.o
 MODULE_LDFLAGS=@LIBS@
+MODULE_TESTS=local_tests
 
 @static_module_makefile@
+
+local_tests:
+	$(RUNPIKE) $(SRCDIR)/socktest.pike
+
 @dependencies@
diff --git a/src/modules/files/socktest.pike b/src/modules/files/socktest.pike
index 345ad497a99b5c6dd681430a0576c934d31181df..6952a7caa054d145425d6038c222fec84c885e9d 100755
--- a/src/modules/files/socktest.pike
+++ b/src/modules/files/socktest.pike
@@ -1,12 +1,16 @@
 #!/usr/local/bin/pike
 
-#include <stdio.h>
+import Stdio;
+import String;
 
 #if !efun(strerror)
 #define strerror(X) ("ERRNO = "+(string)(X))
 #endif
 
 class Socket {
+  import Stdio;
+  import String;
+
   inherit File;
 
   object daemon=function_object(backtrace()[-2][2]);
diff --git a/src/modules/static_module_makefile.in b/src/modules/static_module_makefile.in
index 27f65f4bf2ccdeb437b98c82eca0275c5b7cf602..f63127f9fb35e01e0b58e39b86c4ca5edfa50b21 100644
--- a/src/modules/static_module_makefile.in
+++ b/src/modules/static_module_makefile.in
@@ -28,6 +28,7 @@ module.a: $(OBJS)
 	-rm -f module.a
 	ar cq module.a $(OBJS)
 	-@RANLIB@ module.a
+	touch linker_options
 
 clean:
 	-rm -f *.o *.a *.so module.so module.pmod
@@ -41,10 +42,10 @@ depend:
 module_testsuite: $(SRCDIR)/testsuite.in
 	$(TMP_BINDIR)/mktestsuite $(SRCDIR)/testsuite.in >module_testsuite -DSRCDIR=$(SRCDIR) 
 
-verify: module_testsuite
+verify: module_testsuite $(MODULE_TESTS)
 	$(RUNPIKE) $(TMP_BINDIR)/test_pike.pike module_testsuite
 
-verbose_verify: module_testsuite
+verbose_verify: module_testsuite $(MODULE_TESTS)
 	$(RUNPIKE) $(TMP_BINDIR)/test_pike.pike module_testsuite --verbose
 
 gdb_verify: module_testsuite
diff --git a/src/testsuite.in b/src/testsuite.in
index a848f6e76e2c5ebdc85829f6acbc361301350f8e..769dbcb1c24ce76303f4fc85aa33972f1549accd 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,10 +1,11 @@
-test_true([["$Id: testsuite.in,v 1.38 1997/04/22 00:10:16 grubba Exp $"]])
+test_true([["$Id: testsuite.in,v 1.39 1997/04/23 01:59:41 hubbe Exp $"]])
 test_any([[class foo { constant x=17; }; class bar { inherit foo; constant x=18; }; return bar()->x;]],18)
 test_program([[inline string foo(string s){ while(s[0] == ' ' || s[0] == '\t') s = s[1..]; return(s); } string a() { return foo("   bar"); }]])
 test_true([[lambda(function f) {return 1;}(object_program(this_object()));]])
 test_eq([[class { int `()(){ return 4711; } }()(); ]],4711)
 teste_eval_error(mixed foo=({}); sort(@foo); )
 test_compile_error([[int foo() { return 1} ; constant foo=(["foo":foo]); return foo->foo();]])
+test_compile_error([[class T{void p(object e,object f){lambda::create(f);}}]])
 test_eval_error(mixed *foo=({}); return mkmapping(foo,({1})); )
 test_true(time())
 test_compile_error([[mapping (string:array(string:string)) foo=([]); ]])