diff --git a/src/las.c b/src/las.c
index 2537ca5fc14e2b5a988e366609689e9264fd86a6..8afb9753de8c5fcbe7376d881a63d2104a623cba 100644
--- a/src/las.c
+++ b/src/las.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: las.c,v 1.84 1999/08/20 06:01:30 mast Exp $");
+RCSID("$Id: las.c,v 1.85 1999/09/06 11:13:17 hubbe Exp $");
 
 #include "language.h"
 #include "interpret.h"
@@ -583,6 +583,10 @@ node *mkexternalnode(int level,
 #endif
   res->u.integer.a = level;
   res->u.integer.b = i;
+
+  /* Bzot-i-zot */
+  new_program->flags |= PROGRAM_USES_PARENT;
+
   return res;
 }
 
@@ -2322,7 +2326,20 @@ int eval_low(node *n)
 	  }else{
 	    yyerror("Nonstandard error format.");
 	  }
-	}else{
+	}
+	else if(throw_value.type == T_OBJECT)
+	{
+	  ref_push_object(throw_value.u.object);
+	  push_int(0);
+	  f_index(2);
+	  if(sp[-1].type != T_STRING)
+	    yyerror("Nonstandard error format.");
+	  else
+	    yyerror(sp[-1].u.string->str);
+	  pop_stack();
+	}
+	else
+	{
 	  yyerror("Nonstandard error format.");
 	}
       }
diff --git a/src/module_support.c b/src/module_support.c
index 29de9eb8afd6f475f6c5eb02fa047116f4538802..a14ba33a6213d443c5ff7fed4b92705506e0935e 100644
--- a/src/module_support.c
+++ b/src/module_support.c
@@ -6,7 +6,7 @@
 #include "pike_types.h"
 #include "error.h"
 
-RCSID("$Id: module_support.c,v 1.25 1999/04/25 21:16:36 grubba Exp $");
+RCSID("$Id: module_support.c,v 1.26 1999/09/06 11:13:18 hubbe Exp $");
 
 /* Checks that args_to_check arguments are OK.
  * Returns 1 if everything worked ok, zero otherwise.
@@ -257,9 +257,21 @@ int va_get_args(struct svalue *s,
         return ret;
       break;
     case 'p':
-      if(s->type != T_PROGRAM) return ret;
-      *va_arg(ap, struct program **)=s->u.program;
+      switch(s->type)
+      {
+	case T_PROGRAM:
+	  *va_arg(ap, struct program **)=s->u.program;
+	  break;
+
+	case T_FUNCTION:
+	  if((*va_arg(ap, struct program **)=program_from_svalue(s)))
+	    break;
+
+	default:
+	  return;
+      }
       break;
+
     case '*':
       *va_arg(ap, struct svalue **)=s;
       break;
diff --git a/src/program.c b/src/program.c
index f62f8dd7c18ed14266da08e67da81d420f151eb0..07988abf38295adee8eea4b37137c4a029a091eb 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.133 1999/08/20 05:08:25 hubbe Exp $");
+RCSID("$Id: program.c,v 1.134 1999/09/06 11:13:19 hubbe Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -1227,13 +1227,25 @@ void low_inherit(struct program *p,
   struct inherit inherit;
   struct pike_string *s;
 
-  
   if(!p)
   {
     yyerror("Illegal program pointer.");
     return;
   }
 
+  if(p->flags & PROGRAM_USES_PARENT)
+  {
+    if(!parent && !parent_offset)
+    {
+      yyerror("Parent pointer lost, cannot inherit!");
+      /* We inherit it anyways, to avoid causing more errors */
+    }
+  }
+
+ /* parent offset was increased by one for above test.. */
+  parent_offset--;
+
+
   if(!(p->flags & (PROGRAM_FINISHED | PROGRAM_PASS_1_DONE)))
   {
     yyerror("Cannot inherit program which is not fully compiled yet.");
@@ -1424,7 +1436,7 @@ void compiler_do_inherit(node *n,
       low_inherit(p,
 		  0,
 		  numid,
-		  n->u.integer.a,
+		  n->u.integer.a+1,
 		  flags,
 		  name);
       break;
@@ -1574,12 +1586,16 @@ int define_variable(struct pike_string *name,
 
   if(n != -1)
   {
+    /* not inherited */
+    if(new_program->identifier_references[n].inherit_offset == 0) 
+    {
+      my_yyerror("Identifier '%s' defined twice.",name->str);
+      return n;
+    }
+
     if (IDENTIFIERP(n)->id_flags & ID_NOMASK)
       my_yyerror("Illegal to redefine 'nomask/final' variable/functions \"%s\"", name->str);
 
-    if(PROG_FROM_INT(new_program, n) == new_program)
-      my_yyerror("Variable '%s' defined twice.",name->str);
-
     if(!(IDENTIFIERP(n)->id_flags & ID_INLINE) || compiler_pass!=1)
     {
       if(ID_FROM_INT(new_program, n)->type != type)
@@ -1701,8 +1717,12 @@ int add_constant(struct pike_string *name,
     if(IDENTIFIERP(n)->id_flags & ID_NOMASK)
       my_yyerror("Illegal to redefine 'nomask' identifier \"%s\"", name->str);
 
-    if(PROG_FROM_INT(new_program, n) == new_program)
+    /* not inherited */
+    if(new_program->identifier_references[n].inherit_offset == 0) 
+    {
       my_yyerror("Identifier '%s' defined twice.",name->str);
+      return n;
+    }
 
     if(!(IDENTIFIERP(n)->id_flags & ID_INLINE))
     {
@@ -1875,9 +1895,10 @@ INT32 define_function(struct pike_string *name,
 
     if(ref.inherit_offset == 0) /* not inherited */
     {
-      if(!(!func || func->offset == -1) && !(funp->func.offset == -1))
+      if( !( IDENTIFIER_IS_FUNCTION(funp->identifier_flags) &&
+	     ( (!func || func->offset == -1) || (funp->func.offset == -1))))
       {
-	my_yyerror("Redeclaration of function %s.",name->str);
+	my_yyerror("Identifier '%s' defined twice.",name->str);
 	return i;
       }
 
@@ -1900,6 +1921,7 @@ INT32 define_function(struct pike_string *name,
       
       funp->identifier_flags=function_flags;
     }else{
+
       if((ref.id_flags & ID_NOMASK)
 #if 0
 	 && !(funp->func.offset == -1)
@@ -1908,6 +1930,7 @@ INT32 define_function(struct pike_string *name,
       {
 	my_yyerror("Illegal to redefine 'nomask' function %s.",name->str);
       }
+      
 
       if(ref.id_flags & ID_INLINE)
       {
@@ -2224,6 +2247,7 @@ void program_index_no_free(struct svalue *to, struct program *p,
 	  get_name_of_type(ind->type));
   }
   s = ind->u.string;
+#if 0
   for (e = p->num_identifier_references; e--; ) {
     struct identifier *id;
     if (p->identifier_references[e].id_flags & ID_HIDDEN) {
@@ -2233,6 +2257,14 @@ void program_index_no_free(struct svalue *to, struct program *p,
     if (id->name != s) {
       continue;
     }
+
+#else
+  e=find_shared_string_identifier(s, p);
+  if(e!=-1)
+  {
+    struct identifier *id;
+    id=ID_FROM_INT(p, e);
+#endif
     if (IDENTIFIER_IS_CONSTANT(id->identifier_flags)) {
       struct program *p2 = PROG_FROM_INT(p, e);
       assign_svalue_no_free(to, (p2->constants + id->func.offset));
@@ -2245,11 +2277,18 @@ void program_index_no_free(struct svalue *to, struct program *p,
       }
     }
   }
+
+#if 1
+  to->type=T_INT;
+  to->subtype=NUMBER_UNDEFINED;
+  to->u.integer=0;
+#else
   if (s->len < 1024) {
     error("No such index \"%s\".\n", s->str);
   } else {
     error("No such index.\n");
   }
+#endif
 }
 
 /*
diff --git a/src/program.h b/src/program.h
index 44c95f01a09d241936659e723b1024f0612e76ae..3e27b4a81851c6b1f285dc3a46b8a541f16b4f6f 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.55 1999/08/20 05:08:26 hubbe Exp $
+ * $Id: program.h,v 1.56 1999/09/06 11:13:21 hubbe Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -120,6 +120,7 @@ union idptr
 #define IDENTIFIER_PROTOTYPED 16
 
 #define IDENTIFIER_IS_FUNCTION(X) ((X) & IDENTIFIER_FUNCTION)
+#define IDENTIFIER_IS_PIKE_FUNCTION(X) ((X) & IDENTIFIER_PIKE_FUNCTION)
 #define IDENTIFIER_IS_CONSTANT(X) ((X) & IDENTIFIER_CONSTANT)
 #define IDENTIFIER_IS_VARIABLE(X) (!((X) & (IDENTIFIER_FUNCTION | IDENTIFIER_CONSTANT)))
 
@@ -195,10 +196,12 @@ struct inherit
 /* Self explanatory, automatically detected */
 #define PROGRAM_HAS_C_METHODS 32
 
-
 /* All non-static functions are inlinable */
 #define PROGRAM_CONSTANT 64
 
+/* */
+#define PROGRAM_USES_PARENT 128
+
 struct program
 {
   INT32 refs;
diff --git a/src/testsuite.in b/src/testsuite.in
index bf3385d7a575bb06edd071f85c929fc894f0f1cc..418c7b4a6e563b15d471fc8d3ea4e8c204483400 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-stest_true([["$Id: testsuite.in,v 1.191 1999/08/20 06:04:01 mast Exp $"]])
+test_true([["$Id: testsuite.in,v 1.192 1999/09/06 11:13:22 hubbe Exp $"]])
 cond([[all_constants()->_verify_internals]],
 [[
   test_do(_verify_internals())
@@ -151,6 +151,14 @@ test_eval_error([[ return 0.0[0]; ]])
 test_eval_error([[ return 0[0]; ]])
 test_compile_error([[constant x=class {}(); ]])
 
+test_compile_error_low([[
+ mixed foo;
+ mapping query_variables() { return ([]); };
+ mixed foo(mixed bar) { return 1/foo; }
+]])
+
+
+
 test_compile([[int x=(gauge { return; },1);]])
 cond( [[ master()->resolv("Gmp")->mpz ]],
 [[
@@ -236,6 +244,97 @@ test_any([[
   return d->a + d->b + d->c;
 ]], 7)
 
+test_compile_error_low([[
+  class AScope
+  {
+     int gurka;
+     class A
+     {
+  	int func() { return gurka; }
+     }
+  }
+  
+  class CScope
+  {
+     string hohum;
+     class C
+     {
+  	inherit AScope.A;
+     }
+  }
+
+]])
+
+
+test_any([[
+ class A {};
+ class B { inherit A; };
+ class C { inherit B; };
+ class D { inherit C; };
+ return Program.inherits(D,A);
+]],1)
+
+test_any([[
+ class A {};
+ class B { inherit A; };
+ class C { inherit B; };
+ class D { inherit C; };
+ return Program.inherits(A,D);
+]],0)
+
+test_any([[
+ class A {};
+ class B { inherit A; };
+ class C { inherit B; };
+ class D { inherit C; };
+ return Program.inherits(A,C);
+]],0)
+
+test_any([[
+ class A {};
+ class B { inherit A; };
+ class C { inherit B; };
+ class D { inherit C; };
+ return Program.inherits(C,A);
+]],1)
+
+test_any_equal([[
+ class A {};
+ class B { inherit A; };
+ class C { inherit B; };
+ class D { inherit C; };
+ return Program.inherit_list(D);
+]],[[ ({ C }) ]] )
+
+test_any_equal([[
+ class A {};
+ class B { inherit A; };
+ class C { inherit B; };
+ class D { inherit A; inherit B; inherit C; };
+ return Program.inherit_list(D);
+]],[[ ({ A,B,C }) ]])
+
+test_any_equal([[
+ class A {};
+ class B { inherit A; };
+ class C { inherit B; };
+ class D { inherit C; };
+ return Program.inherit_tree(D);
+]],[[  ({D, ({C, ({B, ({A})})})}) ]])
+
+test_any([[
+ class A {};
+ class B { inherit A; };
+ class C { inherit B; };
+ class D { inherit C; };
+ return sizeof( Program.all_inherits(D) - ({A,B,C}) );
+]],0)
+
+test_true([[Program.implements( class { int x; string y; void foo(int x) {} },
+	class { void foo(mixed z) {} int x; })]])
+test_false([[Program.implements( class { int x; string y; void foo(int x) {} },
+	class { void foo(mixed z) {} string x; })]])
+
 test_eq([[object_program(master())]],[[(program)"/master"]])
 test_compile([[object("master") m = master();]])
 test_any([[int x; x++; if(x) return x; return -1;]],1)
@@ -1941,6 +2040,9 @@ test_eq([[cpp("#define MAX(X,Y) ((X)>(Y)?(X):(Y))\n#define MAX3(X,Y,Z) MAX(MAX(X
 test_eq([[cpp("foo\xfeff""bar \xfeff gazonk")]],[[cpp("foobar  gazonk")]])
 
 test_any(int e; object o=clone(Stdio.File); if(!o->open("conftest.h","wct")) return -1; e=o->write("return 17;\n"); if(!o->close()) return -1; return e,11)
+
+test_compile_any([[import Stdio.Readline; mapping x=([]);]]);
+
 test_any([[
 #include "conftest.h"
 ]],17)
diff --git a/src/threads.h b/src/threads.h
index 96f113d73117c7de3933a18dfc1e02a4638d8083..0115b47a57ed1bc1de4b93de904fd4037d3ea128 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -1,5 +1,5 @@
 /*
- * $Id: threads.h,v 1.69 1999/08/30 06:23:51 hubbe Exp $
+ * $Id: threads.h,v 1.70 1999/09/06 11:13:23 hubbe Exp $
  */
 #ifndef THREADS_H
 #define THREADS_H
@@ -586,6 +586,12 @@ void th_farm(void (*fun)(void *), void *here);
 /* Prototypes end here */
 
 #else
+
+#define th_atfork(X,Y,Z)
+#define th_atfork_prepare()
+#define th_atfork_parent()
+#define th_atfork_child()
+
 #define th_setconcurrency(X)
 #define DEFINE_MUTEX(X)
 #define DEFINE_IMUTEX(X)