diff --git a/lib/master.pike b/lib/master.pike
index eee2ac43801f3e2637e2fa329721ced17fb6d996..0201231720025974f37b13d2fa4673dc56f87312 100644
--- a/lib/master.pike
+++ b/lib/master.pike
@@ -24,23 +24,6 @@ mapping (string:program) programs=(["/master":object_program(this_object())]);
 
 #define capitalize(X) (upper_case((X)[..0])+(X)[1..])
 
-/* This function is called whenever a module has built a clonable program
- * with functions written in C and wants to notify the Pike part about
- * this. It also supplies a suggested name for the program.
- */
-void add_precompiled_program(string name, program p)
-{
-  programs[name]=p;
-
-  if(sscanf(name, "/precompiled/%s", name)) {
-    string const="";
-    foreach(reverse(name/"/"), string s) {
-      const = capitalize(s) + const;
-      add_constant(const, p);
-    }
-  }
-}
-
 static program findprog(string pname)
 {
   program ret;
@@ -55,11 +38,10 @@ static program findprog(string pname)
   {
     ret=compile_file(pname+".pike");
   }
-#if efun(load_module)
+#if constant(load_module)
   else if(file_stat(pname+".so"))
   {
-    load_module(pname+".so");
-    ret=programs[pname];
+    ret=load_module(pname+".so");
   }
 #endif
   if(ret)
@@ -152,7 +134,7 @@ program handle_inherit(string pname, string current_file)
   return cast_to_program(tmp*"/");
 }
 
-mapping (string:object) objects=(["/master.pike":this_object()]);
+mapping (string:object) objects=(["/master":this_object()]);
 
 /* This function is called when the drivers wants to cast a string
  * to an object because of an implict or explicit cast. This function
@@ -185,40 +167,111 @@ class dirnode
   }
 };
 
-object findmodule(string fullname)
+class mergenode
 {
-  mixed *stat;
-  if(mixed *stat=file_stat(fullname))
+  mixed *modules;
+  void create(mixed * m) { modules=m; }
+  mixed `[](string index)
   {
-    if(stat[1]==-2) return dirnode(fullname);
+    foreach(modules, mixed mod)
+      if(mixed ret=mod[index]) return ret;
+    return UNDEFINED;
   }
+};
+
+object findmodule(string fullname)
+{
+  mixed *stat;
   program p;
   if(p=(program)(fullname+".pmod"))
     return (object)(fullname+".pmod");
+
+#if constant(load_module)
+  if(file_stat(fullname+".so"))
+  {
+    return (object)(fullname);
+  }
+#endif
+
+  /* Hack for pre-install testing */
+  if(mixed *stat=file_stat(fullname))
+  {
+    if(stat[1]==-2)
+      return findmodule(fullname+"/module");
+  }
+
+  if(mixed *stat=file_stat(fullname+".pmd"))
+  {
+    if(stat[1]==-2)
+      return dirnode(fullname+".pmd");
+  }
+    
   return UNDEFINED;
 }
 
+static mixed idiresolv(string identifier)
+{
+  string path=combine_path(pike_library_path+"/modules",identifier);
+  if(mixed ret=findmodule(path)) return ret;
+  return _static_modules[identifier];
+}
+
 mixed resolv(string identifier, string current_file)
 {
   mixed ret;
   string *tmp,path;
+  multiset tested=(<>);
+  mapping tested=([]);
+  mixed *modules=({});
 
   tmp=current_file/"/";
   tmp[-1]=identifier;
   path=combine_path(getcwd(), tmp*"/");
-  if(ret=findmodule(path)) return tmp;
+  if(!tested[path])
+  {
+    tested[path]=1;
+    if(ret=findmodule(path)) modules+=({ret});
+  }
 
   if(path=getenv("PIKE_MODULE_PATH"))
   {
     foreach(path/":", path)
       {
+	if(!sizeof(path)) continue;
 	path=combine_path(path,identifier);
-	if(ret=findmodule(path)) return ret;
+	if(!tested[path])
+	{
+	  tested[path]=1;
+	  if(ret=findmodule(path)) modules+=({ret});
+	}
       }
   }
+  string path=combine_path(pike_library_path+"/modules",identifier);
+  if(!tested[path])
+  {
+    tested[path]=1;
+    if(ret=findmodule(path)) modules+=({ret});
+  }
+  if(ret=_static_modules[identifier]) modules+=({ret});
 
-  path=combine_path(pike_library_path+"/modules",identifier);
-  return findmodule(path);
+  switch(sizeof(modules))
+  {
+  default:
+    mixed tmp=mergenode(modules);
+    werror(sprintf("%O\n",tmp["file"]));
+    return tmp;
+  case 1:
+    return modules[0];
+  case 0:
+    switch(identifier)
+    {
+    case "readline":
+      if(!resolv("readlinemod", current_file))
+	werror("No readline module.\n");
+      return all_constants()->readline;
+    }
+    return UNDEFINED;
+  }
 }
 
 /* This function is called when all the driver is done with all setup
@@ -239,20 +292,21 @@ void _main(string *argv, string *env)
   add_constant("getenv",getenv);
   add_constant("putenv",putenv);
 
-  add_constant("write",cast_to_program("/precompiled/file")("stdout")->write);
+  add_constant("write",idiresolv("files")->file("stdout")->write);
 
   a=backtrace()[-1][0];
   q=a/"/";
   pike_library_path = q[0..sizeof(q)-2] * "/";
 
-  tmp=new(pike_library_path+"/include/getopt.pre.pike");
+  tmp=idiresolv("getopt");
 
   foreach(tmp->find_all_options(argv,({
     ({"version",tmp->NO_ARG,({"-v","--version"})}),
       ({"help",tmp->NO_ARG,({"-h","--help"})}),
 	({"execute",tmp->HAS_ARG,({"-e","--execute"})}),
-	  ({"ignore",tmp->HAS_ARG,"-ms"}),
-	    ({"ignore",tmp->MAY_HAVE_ARG,"-Ddatpl",0,1})}),1),
+	  ({"modpath",tmp->HAS_ARG,({"-M","--module-path"})}),
+	    ({"ignore",tmp->HAS_ARG,"-ms"}),
+	      ({"ignore",tmp->MAY_HAVE_ARG,"-Ddatpl",0,1})}),1),
 	  mixed *opts)
     {
       switch(opts[0])
@@ -281,6 +335,10 @@ void _main(string *argv, string *env)
 	compile_string("#include <simulate.h>\nmixed create(){"+opts[1]+";}")();
 	exit(0);
 
+      case "modpath":
+	putenv("PIKE_MODULE_PATH",opts[1]+":"+(getenv("PIKE_MODULE_PATH")||""));
+	break;
+
       case "ignore":
 	break;
       }
@@ -294,9 +352,22 @@ void _main(string *argv, string *env)
     argv=argv[0]/"/";
     argv[-1]="hilfe";
     argv=({ argv*"/" });
+    if(!file_stat(argv[0]))
+    {
+      if(file_stat("/usr/local/bin/hilfe"))
+	argv[0]="/usr/local/bin/hilfe";
+      else if(file_stat("../bin/hilfe"))
+	argv[0]="/usr/local/bin/hilfe";
+      else
+      {
+	werror("Couldn't find hilfe.\n");
+	exit(1);
+      }
+    }
   }else{
     argv=argv[1..];
   }
+
   script=(object)argv[0];
 
   if(!script->main)
@@ -366,6 +437,7 @@ string handle_include(string f,
     {
       foreach(path/":", path)
       {
+	if(!sizeof(path)) continue;
 	path=combine_path(path,f);
 	if(file_stat(path))
 	  break;