diff --git a/lib/modules/Remote.pmod/call.pike b/lib/modules/Remote.pmod/call.pike
index 8274c96f58caae3a03e1c31bf43b504ae2666bd8..ac44c70cf067b6a2b9f5179aa672bae2b36bb4d0 100644
--- a/lib/modules/Remote.pmod/call.pike
+++ b/lib/modules/Remote.pmod/call.pike
@@ -13,7 +13,8 @@ int _async;
 
 mixed `() (mixed ... args)
 {
-  mixed data = ctx->encode_call(objectid, name, args, _async);
+  mixed data = ctx->encode_call(objectid, name, args,
+				_async ? CTX_CALL_ASYNC : CTX_CALL_SYNC);
   if (_async)
     con->call_async(data);
   else
@@ -23,16 +24,22 @@ mixed `() (mixed ... args)
 
 mixed sync(mixed ... args)
 {
-  mixed data = ctx->encode_call(objectid, name, args, _async);
+  mixed data = ctx->encode_call(objectid, name, args, CTX_CALL_SYNC);
   return con->call_sync(data);
 }
 
 void async(mixed ... args)
 {
-  mixed data = ctx->encode_call(objectid, name, args, 1);
+  mixed data = ctx->encode_call(objectid, name, args, CTX_CALL_ASYNC);
   con->call_async(data);
 }
 
+int exists()
+{
+  mixed data = ctx->encode_call(objectid, name, ({}), CTX_EXISTS);
+  return con->call_sync(data);
+}
+
 int is_async()
 {
   return _async;
diff --git a/lib/modules/Remote.pmod/connection.pike b/lib/modules/Remote.pmod/connection.pike
index 1f13aefa66dbef112f941cf1ef78253830586a1d..acf68c0219018b5d2fdc7704a52b0d0df7c1f0b7 100644
--- a/lib/modules/Remote.pmod/connection.pike
+++ b/lib/modules/Remote.pmod/connection.pike
@@ -165,7 +165,8 @@ void try_close()
     closed = -1;
     catch {
       // This should work with most older Remote implementations.
-      string s = encode_value(ctx->encode_call (0, "sOmE nOnSeNsE..", ({}), 0));
+      string s = encode_value(ctx->encode_call (0, "sOmE nOnSeNsE..", ({}),
+						CTX_CALL_SYNC));
       con->write (sprintf("%4c%s", sizeof(s), s));
     };
 #endif
@@ -405,6 +406,10 @@ void read_some(int ignore, string s)
        }
        break;
 
+     case CTX_EXISTS:
+       return_value (data[4], ctx->decode_existp (data));
+       break;
+
      default:
        error("Unknown message");
     }
@@ -454,10 +459,14 @@ void read_thread()
 
 void server_read_thread()
 {
-  DEBUGMSG("server_read_thread\n");
-  handshake (0, con->read (24, 1));
-  read_thread();
+  mixed err = catch {
+    DEBUGMSG("server_read_thread\n");
+    handshake (0, con->read (24, 1));
+    read_thread();
+  };
+  con = 0;
   DEBUGMSG("server_read_thread exit\n");
+  if (err) throw (err);
 }
 
 void call_thread()
diff --git a/lib/modules/Remote.pmod/context.pike b/lib/modules/Remote.pmod/context.pike
index c609d2ced05fdaf6eb27962717ab93dea45f1571..b938c5edd5f7edee5a05524560be2eee33f90d39 100644
--- a/lib/modules/Remote.pmod/context.pike
+++ b/lib/modules/Remote.pmod/context.pike
@@ -153,20 +153,20 @@ mixed decode(array a)
   }
 }
 
-array encode_call(object|string o, string|function f, array args, int async)
+array encode_call(object|string o, string|function f, array args, int type)
 {
-  int type = (async ? CTX_CALL_ASYNC : CTX_CALL_SYNC);
   if(objectp(o))
-    if(stringp(f))
+    if(stringp(f) || !f)
       return ({ type, encode(o), f, encode(args), counter++ });
     else
-      error("If the first argument is an object, the second must be a string");
+      error("If the first argument is an object, "
+	    "the second must be a string or zero");
   else if(stringp(o))
-    if(stringp(f))
+    if(stringp(f) || !f)
       return ({ type, ({ CTX_OBJECT, o }), f, encode(args), counter++ });
     else
       error("If the first argument is an object reference, "
-	    "the second must be a string");
+	    "the second must be a string or zero");
   else if(o)
     error("Error in arguments");
   else if(functionp(f)||programp(f))
@@ -176,7 +176,7 @@ array encode_call(object|string o, string|function f, array args, int async)
   error("Error in arguments");
 }
 
-function decode_call(array data)
+function|object decode_call(array data)
 {
   if((data[0] != CTX_CALL_SYNC) && (data[0] != CTX_CALL_ASYNC))
     error("This is not a call");
@@ -194,7 +194,10 @@ function decode_call(array data)
 #ifdef REMOTE_DEBUG
     if (!o) DEBUGMSG(id + " not found\n");
 #endif
-    return o && o[data[2]];
+    if (data[2])
+      return o && o[data[2]];
+    else
+      return o;
   }
   else {
     string id = data[2][1];
@@ -206,6 +209,36 @@ function decode_call(array data)
   }
 }
 
+int decode_existp(array data)
+{
+  if(data[0] != CTX_EXISTS)
+    error("This is not an exists check");
+  if(data[1])
+  {
+    string id = data[1][1];
+    object o = id2val[id];
+    if (o)
+      DEBUGMSG(id + " found locally\n");
+    else if(!o && server_context && (o=server_context->object_for(id, con))) {
+      DEBUGMSG(id + " found in server_context\n");
+      val2id[o] = id;
+      id2val[id] = o;
+    }
+#ifdef REMOTE_DEBUG
+    if (!o) DEBUGMSG(id + " not found\n");
+#endif
+    return !!o;
+  }
+  else {
+    string id = data[2][1];
+    object o = id2val[id];
+#ifdef REMOTE_DEBUG
+    if (!o) DEBUGMSG(id + " not found\n");
+#endif
+    return !!o;
+  }
+}
+
 void add(object o, string id)
 {
   DEBUGMSG(id + " added locally\n");
@@ -238,6 +271,9 @@ string describe(array data)
     return "<mapping "+sizeof(indices(data[1]))+">";
   case CTX_ARRAY:
     return "<array "+sizeof(data[1])+">";
+  case CTX_EXISTS:
+    return "exists["+(data[1] ? data[1][1]+"->"+data[2] :
+		      "<function "+data[2][1]+">")+"]";
   }
   return "<unknown "+data[0]+">";
 }
diff --git a/lib/modules/Remote.pmod/obj.pike b/lib/modules/Remote.pmod/obj.pike
index d19cc23e4640ffb912d55a4af3cffe5c9f76a4cf..44f2d2f2930f1cd0b70d58b167e7a23cd86540c0 100644
--- a/lib/modules/Remote.pmod/obj.pike
+++ b/lib/modules/Remote.pmod/obj.pike
@@ -29,6 +29,12 @@ mixed `-> (string f)
   return get_function(f);
 }
 
+int exists()
+{
+  mixed data = ctx->encode_call(id, 0, ({}), CTX_EXISTS);
+  return con->call_sync(data);
+}
+
 void create(string i, object cn, object ct)
 {
   id  = i;
diff --git a/lib/modules/Remote.pmod/remote.h b/lib/modules/Remote.pmod/remote.h
index f04d4d5859726af8368948d12be6be02fdebfb24..7b29b70f92d650783b398173bbf8858526ea7750 100644
--- a/lib/modules/Remote.pmod/remote.h
+++ b/lib/modules/Remote.pmod/remote.h
@@ -27,3 +27,5 @@ program Obj = ((program)"obj");
 #define CTX_RETURN     6
 #define CTX_MAPPING    7
 #define CTX_CALL_ASYNC 8
+#define CTX_EXISTS  9
+#define CTX_EXIST_RES  10