diff --git a/src/sbbs3/js_bbs.cpp b/src/sbbs3/js_bbs.cpp
index 67c00b4036ccbb44217f421f350997eec46e98a6..61053af6fd340aecdeb674c8262e53785646f35f 100644
--- a/src/sbbs3/js_bbs.cpp
+++ b/src/sbbs3/js_bbs.cpp
@@ -3007,6 +3007,20 @@ static jsSyncMethodSpec js_bbs_functions[] = {
 	{0}
 };
 
+static JSBool js_bbs_resolve(JSContext *cx, JSObject *obj, jsval id)
+{
+	char*			name=NULL;
+
+	if(id != JSVAL_NULL)
+		name=JS_GetStringBytes(JSVAL_TO_STRING(id));
+
+	return(js_SyncResolve(cx, obj, name, js_bbs_properties, js_bbs_functions, NULL, 0));
+}
+
+static JSBool js_bbs_enumerate(JSContext *cx, JSObject *obj)
+{
+	return(js_bbs_resolve(cx, obj, JSVAL_NULL));
+}
 
 static JSClass js_bbs_class = {
      "BBS"					/* name			*/
@@ -3015,8 +3029,8 @@ static JSClass js_bbs_class = {
 	,JS_PropertyStub		/* delProperty	*/
 	,js_bbs_get				/* getProperty	*/
 	,js_bbs_set				/* setProperty	*/
-	,JS_EnumerateStub		/* enumerate	*/
-	,JS_ResolveStub			/* resolve		*/
+	,js_bbs_enumerate		/* enumerate	*/
+	,js_bbs_resolve			/* resolve		*/
 	,JS_ConvertStub			/* convert		*/
 	,JS_FinalizeStub		/* finalize		*/
 };
@@ -3032,12 +3046,6 @@ JSObject* js_CreateBbsObject(JSContext* cx, JSObject* parent)
 	if(obj==NULL)
 		return(NULL);
 
-	if(!js_DefineSyncProperties(cx, obj, js_bbs_properties))
-		return(NULL);
-
-	if (!js_DefineSyncMethods(cx, obj, js_bbs_functions, FALSE)) 
-		return(NULL);
-
 	if((mods=JS_DefineObject(cx, obj, "mods", NULL, NULL ,JSPROP_ENUMERATE))==NULL)
 		return(NULL);
 
diff --git a/src/sbbs3/js_client.c b/src/sbbs3/js_client.c
index 8b05395e4d8447beadbc05f6dd87a296db002bec..faac6a968d6449187d20fd4134908016a35f49c0 100644
--- a/src/sbbs3/js_client.c
+++ b/src/sbbs3/js_client.c
@@ -127,6 +127,21 @@ static jsSyncPropertySpec js_client_properties[] = {
 	{0}
 };
 
+static JSBool js_client_resolve(JSContext *cx, JSObject *obj, jsval id)
+{
+	char*			name=NULL;
+
+	if(id != JSVAL_NULL)
+		name=JS_GetStringBytes(JSVAL_TO_STRING(id));
+
+	return(js_SyncResolve(cx, obj, name, js_client_properties, NULL, NULL, 0));
+}
+
+static JSBool js_client_enumerate(JSContext *cx, JSObject *obj)
+{
+	return(js_client_resolve(cx, obj, JSVAL_NULL));
+}
+
 static JSClass js_client_class = {
      "Client"				/* name			*/
     ,JSCLASS_HAS_PRIVATE	/* flags		*/
@@ -134,8 +149,8 @@ static JSClass js_client_class = {
 	,JS_PropertyStub		/* delProperty	*/
 	,js_client_get			/* getProperty	*/
 	,js_client_set			/* setProperty	*/
-	,JS_EnumerateStub		/* enumerate	*/
-	,JS_ResolveStub			/* resolve		*/
+	,js_client_enumerate	/* enumerate	*/
+	,js_client_resolve		/* resolve		*/
 	,JS_ConvertStub			/* convert		*/
 	,JS_FinalizeStub		/* finalize		*/
 };
@@ -153,8 +168,6 @@ JSObject* DLLCALL js_CreateClientObject(JSContext* cx, JSObject* parent
 
 	JS_SetPrivate(cx, obj, client);	/* Store a pointer to client_t */
 
-	js_DefineSyncProperties(cx, obj, js_client_properties);
-
 	js_CreateSocketObject(cx, obj, "socket", sock);
 
 #ifdef BUILD_JSDOCS
diff --git a/src/sbbs3/js_console.cpp b/src/sbbs3/js_console.cpp
index 5b6a7b806dc6c0345f965d22f2e3a023e3ed55e2..9535536a8b204ae95e2d7f7168805c0d3bca3da1 100644
--- a/src/sbbs3/js_console.cpp
+++ b/src/sbbs3/js_console.cpp
@@ -1428,6 +1428,21 @@ static jsSyncMethodSpec js_console_functions[] = {
 };
 
 
+static JSBool js_console_resolve(JSContext *cx, JSObject *obj, jsval id)
+{
+	char*			name=NULL;
+
+	if(id != JSVAL_NULL)
+		name=JS_GetStringBytes(JSVAL_TO_STRING(id));
+
+	return(js_SyncResolve(cx, obj, name, js_console_properties, js_console_functions, NULL, 0));
+}
+
+static JSBool js_console_enumerate(JSContext *cx, JSObject *obj)
+{
+	return(js_console_resolve(cx, obj, JSVAL_NULL));
+}
+
 static JSClass js_console_class = {
      "Console"				/* name			*/
     ,0						/* flags		*/
@@ -1435,8 +1450,8 @@ static JSClass js_console_class = {
 	,JS_PropertyStub		/* delProperty	*/
 	,js_console_get			/* getProperty	*/
 	,js_console_set			/* setProperty	*/
-	,JS_EnumerateStub		/* enumerate	*/
-	,JS_ResolveStub			/* resolve		*/
+	,js_console_enumerate	/* enumerate	*/
+	,js_console_resolve		/* resolve		*/
 	,JS_ConvertStub			/* convert		*/
 	,JS_FinalizeStub		/* finalize		*/
 };
@@ -1453,12 +1468,6 @@ JSObject* js_CreateConsoleObject(JSContext* cx, JSObject* parent)
 		,JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
 		return(NULL);
 
-	if(!js_DefineSyncProperties(cx, obj, js_console_properties))
-		return(NULL);
-
-	if (!js_DefineSyncMethods(cx, obj, js_console_functions, FALSE)) 
-		return(NULL);
-
 	/* Create an array of pre-defined colors */
 
 	JSObject* color_list;
@@ -1475,7 +1484,7 @@ JSObject* js_CreateConsoleObject(JSContext* cx, JSObject* parent)
 		jsval val=INT_TO_JSVAL(sbbs->cfg.color[i]);
 		if(!JS_SetElement(cx, color_list, i, &val))
 			return(NULL);
-	}	
+	}
 
 #ifdef BUILD_JSDOCS
 	js_DescribeSyncObject(cx,obj,"Controls the user's Telnet/RLogin terminal",310);
diff --git a/src/sbbs3/js_file.c b/src/sbbs3/js_file.c
index ba871b065b57cd3da86fb005c46cd43ca4c7d9ac..cc8fc002c41964f36f12519f3be4d647a740a433 100644
--- a/src/sbbs3/js_file.c
+++ b/src/sbbs3/js_file.c
@@ -1903,6 +1903,21 @@ static void js_finalize_file(JSContext *cx, JSObject *obj)
 	JS_SetPrivate(cx, obj, NULL);
 }
 
+static JSBool js_file_resolve(JSContext *cx, JSObject *obj, jsval id)
+{
+	char*			name=NULL;
+
+	if(id != JSVAL_NULL)
+		name=JS_GetStringBytes(JSVAL_TO_STRING(id));
+
+	return(js_SyncResolve(cx, obj, name, js_file_properties, js_file_functions, NULL, 0));
+}
+
+static JSBool js_file_enumerate(JSContext *cx, JSObject *obj)
+{
+	return(js_file_resolve(cx, obj, JSVAL_NULL));
+}
+
 static JSClass js_file_class = {
      "File"					/* name			*/
     ,JSCLASS_HAS_PRIVATE	/* flags		*/
@@ -1910,8 +1925,8 @@ static JSClass js_file_class = {
 	,JS_PropertyStub		/* delProperty	*/
 	,js_file_get			/* getProperty	*/
 	,js_file_set			/* setProperty	*/
-	,JS_EnumerateStub		/* enumerate	*/
-	,JS_ResolveStub			/* resolve		*/
+	,js_file_enumerate		/* enumerate	*/
+	,js_file_resolve		/* resolve		*/
 	,JS_ConvertStub			/* convert		*/
 	,js_finalize_file		/* finalize		*/
 };
@@ -1943,16 +1958,6 @@ js_file_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
 		return(JS_FALSE);
 	}
 
-	if(!js_DefineSyncProperties(cx, obj, js_file_properties)) {
-		dbprintf(TRUE, p, "js_DefineSyncProperties failed");
-		return(JS_FALSE);
-	}
-
-	if(!js_DefineSyncMethods(cx, obj, js_file_functions, FALSE)) {
-		dbprintf(TRUE, p, "js_DefineSyncMethods failed");
-		return(JS_FALSE);
-	}
-
 #ifdef BUILD_JSDOCS
 	js_DescribeSyncObject(cx,obj,"Class used for opening, creating, reading, or writing files on the local file system<p>"
 		"Special features include:</h2><ol type=disc>"
@@ -2016,12 +2021,6 @@ JSObject* DLLCALL js_CreateFileObject(JSContext* cx, JSObject* parent, char *nam
 	if(obj==NULL)
 		return(NULL);
 
-	if(!js_DefineSyncProperties(cx, obj, js_file_properties))
-		return(NULL);
-
-	if (!js_DefineSyncMethods(cx, obj, js_file_functions, FALSE)) 
-		return(NULL);
-
 	if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL)
 		return(NULL);
 
diff --git a/src/sbbs3/js_queue.c b/src/sbbs3/js_queue.c
index 18e7edd8a9ced22e73c9fa6f8b20d71e08ff4197..efbf4a50ee770cb5be9a5ed408775c0695f40eef 100644
--- a/src/sbbs3/js_queue.c
+++ b/src/sbbs3/js_queue.c
@@ -373,19 +373,6 @@ static jsSyncPropertySpec js_queue_properties[] = {
 	{0}
 };
 
-static JSClass js_queue_class = {
-     "Queue"				/* name			*/
-    ,JSCLASS_HAS_PRIVATE	/* flags		*/
-	,JS_PropertyStub		/* addProperty	*/
-	,JS_PropertyStub		/* delProperty	*/
-	,js_queue_get			/* getProperty	*/
-	,JS_PropertyStub		/* setProperty	*/
-	,JS_EnumerateStub		/* enumerate	*/
-	,JS_ResolveStub			/* resolve		*/
-	,JS_ConvertStub			/* convert		*/
-	,js_finalize_queue		/* finalize		*/
-};
-
 static jsSyncMethodSpec js_queue_functions[] = {
 	{"poll",		js_poll,		1,	JSTYPE_UNDEF,	"[timeout=<tt>0</tt>]"
 	,JSDOCSTR("wait for any value to be written to the queue for up to <i>timeout</i> milliseconds "
@@ -411,6 +398,34 @@ static jsSyncMethodSpec js_queue_functions[] = {
 	{0}
 };
 
+static JSBool js_queue_resolve(JSContext *cx, JSObject *obj, jsval id)
+{
+	char*			name=NULL;
+
+	if(id != JSVAL_NULL)
+		name=JS_GetStringBytes(JSVAL_TO_STRING(id));
+
+	return(js_SyncResolve(cx, obj, name, js_queue_properties, js_queue_functions, NULL, 0));
+}
+
+static JSBool js_queue_enumerate(JSContext *cx, JSObject *obj)
+{
+	return(js_queue_resolve(cx, obj, JSVAL_NULL));
+}
+
+static JSClass js_queue_class = {
+     "Queue"				/* name			*/
+    ,JSCLASS_HAS_PRIVATE	/* flags		*/
+	,JS_PropertyStub		/* addProperty	*/
+	,JS_PropertyStub		/* delProperty	*/
+	,js_queue_get			/* getProperty	*/
+	,JS_PropertyStub		/* setProperty	*/
+	,js_queue_enumerate		/* enumerate	*/
+	,js_queue_resolve		/* resolve		*/
+	,JS_ConvertStub			/* convert		*/
+	,js_finalize_queue		/* finalize		*/
+};
+
 /* Queue Constructor (creates queue) */
 
 static JSBool
@@ -459,16 +474,6 @@ js_queue_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsva
 		return(JS_FALSE);
 	}
 
-	if(!js_DefineSyncProperties(cx, obj, js_queue_properties)) {
-		JS_ReportError(cx,"js_DefineSyncProperties failed");
-		return(JS_FALSE);
-	}
-
-	if(!js_DefineSyncMethods(cx, obj, js_queue_functions, FALSE)) {
-		JS_ReportError(cx,"js_DefineSyncMethods failed");
-		return(JS_FALSE);
-	}
-
 #ifdef BUILD_JSDOCS
 	js_DescribeSyncObject(cx,obj,"Class for bi-directional message queues. "
 		"Used for inter-thread/module communications.", 312);
@@ -509,15 +514,9 @@ JSObject* DLLCALL js_CreateQueueObject(JSContext* cx, JSObject* parent, char *na
 	if(obj==NULL)
 		return(NULL);
 
-	if(!js_DefineSyncProperties(cx, obj, js_queue_properties))
-		return(NULL);
-
 	if(!JS_SetPrivate(cx, obj, q))
 		return(NULL);
 
-	if (!js_DefineSyncMethods(cx, obj, js_queue_functions, FALSE)) 
-		return(NULL);
-
 	return(obj);
 }
 
diff --git a/src/sbbs3/js_server.c b/src/sbbs3/js_server.c
index 12a08fec77408d856c9aa041af2bd0e922443529..4f48c21eaf6fae2fa7d434447ee85523f5cc38e1 100644
--- a/src/sbbs3/js_server.c
+++ b/src/sbbs3/js_server.c
@@ -134,6 +134,20 @@ static char* server_prop_desc[] = {
 };
 #endif
 
+static JSBool js_server_resolve(JSContext *cx, JSObject *obj, jsval id)
+{
+	char*			name=NULL;
+
+	if(id != JSVAL_NULL)
+		name=JS_GetStringBytes(JSVAL_TO_STRING(id));
+
+	return(js_SyncResolve(cx, obj, name, js_server_properties, NULL, NULL, 0));
+}
+
+static JSBool js_server_enumerate(JSContext *cx, JSObject *obj)
+{
+	return(js_server_resolve(cx, obj, JSVAL_NULL));
+}
 
 static JSClass js_server_class = {
      "Server"				/* name			*/
@@ -142,8 +156,8 @@ static JSClass js_server_class = {
 	,JS_PropertyStub		/* delProperty	*/
 	,js_server_get			/* getProperty	*/
 	,js_server_set			/* setProperty	*/
-	,JS_EnumerateStub		/* enumerate	*/
-	,JS_ResolveStub			/* resolve		*/
+	,js_server_enumerate	/* enumerate	*/
+	,js_server_resolve		/* resolve		*/
 	,JS_ConvertStub			/* convert		*/
 	,JS_FinalizeStub		/* finalize		*/
 };
@@ -160,9 +174,6 @@ JSObject* DLLCALL js_CreateServerObject(JSContext* cx, JSObject* parent
 	if(!JS_SetPrivate(cx, obj, props))
 		return(NULL);
 
-	if(!js_DefineSyncProperties(cx, obj, js_server_properties))
-		return(NULL);
-
 #ifdef BUILD_JSDOCS
 	js_DescribeSyncObject(cx,obj,"Server-specifc properties",310);
 	js_CreateArrayOfStrings(cx,obj,"_property_desc_list", server_prop_desc, JSPROP_READONLY);
diff --git a/src/sbbs3/js_socket.c b/src/sbbs3/js_socket.c
index ef33cd4919fc1a5183ed2362ffb1625c3fb7d4ca..1268051ca7a8b4086560af9e945ac36a939b51f2 100644
--- a/src/sbbs3/js_socket.c
+++ b/src/sbbs3/js_socket.c
@@ -1231,19 +1231,6 @@ static jsSyncPropertySpec js_socket_properties[] = {
 	{0}
 };
 
-static JSClass js_socket_class = {
-     "Socket"				/* name			*/
-    ,JSCLASS_HAS_PRIVATE	/* flags		*/
-	,JS_PropertyStub		/* addProperty	*/
-	,JS_PropertyStub		/* delProperty	*/
-	,js_socket_get			/* getProperty	*/
-	,js_socket_set			/* setProperty	*/
-	,JS_EnumerateStub		/* enumerate	*/
-	,JS_ResolveStub			/* resolve		*/
-	,JS_ConvertStub			/* convert		*/
-	,js_finalize_socket		/* finalize		*/
-};
-
 static jsSyncMethodSpec js_socket_functions[] = {
 	{"close",		js_close,		0,	JSTYPE_VOID,	""
 	,JSDOCSTR("close (shutdown) the socket immediately")
@@ -1333,6 +1320,34 @@ static jsSyncMethodSpec js_socket_functions[] = {
 	{0}
 };
 
+static JSBool js_socket_resolve(JSContext *cx, JSObject *obj, jsval id)
+{
+	char*			name=NULL;
+
+	if(id != JSVAL_NULL)
+		name=JS_GetStringBytes(JSVAL_TO_STRING(id));
+
+	return(js_SyncResolve(cx, obj, name, js_socket_properties, js_socket_functions, NULL, 0));
+}
+
+static JSBool js_socket_enumerate(JSContext *cx, JSObject *obj)
+{
+	return(js_socket_resolve(cx, obj, JSVAL_NULL));
+}
+
+static JSClass js_socket_class = {
+     "Socket"				/* name			*/
+    ,JSCLASS_HAS_PRIVATE	/* flags		*/
+	,JS_PropertyStub		/* addProperty	*/
+	,JS_PropertyStub		/* delProperty	*/
+	,js_socket_get			/* getProperty	*/
+	,js_socket_set			/* setProperty	*/
+	,js_socket_enumerate	/* enumerate	*/
+	,js_socket_resolve		/* resolve		*/
+	,JS_ConvertStub			/* convert		*/
+	,js_finalize_socket		/* finalize		*/
+};
+
 static BOOL js_DefineSocketOptionsArray(JSContext *cx, JSObject *obj, int type)
 {
 	size_t		i;
@@ -1395,19 +1410,9 @@ js_socket_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsv
 		return(JS_FALSE);
 	}
 
-	if(!js_DefineSyncProperties(cx, obj, js_socket_properties)) {
-		JS_ReportError(cx,"js_DefineSyncProperties failed");
-		return(JS_FALSE);
-	}
-
 	if(!js_DefineSocketOptionsArray(cx, obj, type))
 		return(JS_FALSE);
 
-	if(!js_DefineSyncMethods(cx, obj, js_socket_functions, FALSE)) {
-		JS_ReportError(cx,"js_DefineSyncMethods failed");
-		return(JS_FALSE);
-	}
-
 #ifdef BUILD_JSDOCS
 	js_DescribeSyncObject(cx,obj,"Class used for TCP/IP socket communications",310);
 	js_DescribeSyncConstructor(cx,obj,"To create a new Socket object: "
diff --git a/src/sbbs3/js_uifc.c b/src/sbbs3/js_uifc.c
index b36097f78a150d350983a39857cdbb4e4bdd3e70..f661eea7c076f56d65db07f18437116e837d589f 100644
--- a/src/sbbs3/js_uifc.c
+++ b/src/sbbs3/js_uifc.c
@@ -473,6 +473,20 @@ static jsSyncMethodSpec js_functions[] = {
 	{0}
 };
 
+static JSBool js_uifc_resolve(JSContext *cx, JSObject *obj, jsval id)
+{
+	char*			name=NULL;
+
+	if(id != JSVAL_NULL)
+		name=JS_GetStringBytes(JSVAL_TO_STRING(id));
+
+	return(js_SyncResolve(cx, obj, name, js_properties, js_functions, NULL, 0));
+}
+
+static JSBool js_uifc_enumerate(JSContext *cx, JSObject *obj)
+{
+	return(js_uifc_resolve(cx, obj, JSVAL_NULL));
+}
 
 static JSClass js_uifc_class = {
      "UIFC"					/* name			*/
@@ -506,12 +520,6 @@ JSObject* js_CreateUifcObject(JSContext* cx, JSObject* parent)
 	if(!JS_SetPrivate(cx, obj, api))	/* Store a pointer to uifcapi_t */
 		return(NULL);
 
-	if(!js_DefineSyncProperties(cx, obj, js_properties))	/* expose them */
-		return(NULL);
-
-	if(!js_DefineSyncMethods(cx, obj, js_functions, /* append? */ FALSE)) 
-		return(NULL);
-
 	return(obj);
 }