Backout 3bfef7f630dc and all ancestors until cba5d081f15d inclusive (bug 683802, bug 684327 & bug 652571); a=use-try-before-crapping-23-changesets-on-the-tree-thank-you-please
authorEd Morley <bmo@edmorley.co.uk>
Sat, 24 Sep 2011 03:33:31 +0100
changeset 77492 91b82bc49470fcbbc2ef727ea5b8ad279e04fe40
parent 77491 e9f4b05cfbaaa7f474e2d212e2dcae0f33557226
child 77493 cf051f97c0934928c51d557ddd61c3ac5b25c259
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersuse-try-before-crapping-23-changesets-on-the-tree-thank-you-please
bugs683802, 684327, 652571
milestone9.0a1
backs out3bfef7f630dc04b2c642d13d177c9b73bc8d962d
Backout 3bfef7f630dc and all ancestors until cba5d081f15d inclusive (bug 683802, bug 684327 & bug 652571); a=use-try-before-crapping-23-changesets-on-the-tree-thank-you-please
content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
js/src/xpconnect/src/xpccontext.cpp
js/src/xpconnect/src/xpcconvert.cpp
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/src/xpcvariant.cpp
js/src/xpconnect/src/xpcwrappedjsclass.cpp
js/src/xpconnect/src/xpcwrappednative.cpp
js/src/xpconnect/tests/Makefile.in
js/src/xpconnect/tests/TestXPC.cpp
js/src/xpconnect/tests/components/Makefile.in
js/src/xpconnect/tests/components/js/Makefile.in
js/src/xpconnect/tests/components/js/xpctest.manifest
js/src/xpconnect/tests/components/js/xpctest_attributes.js
js/src/xpconnect/tests/components/js/xpctest_params.js
js/src/xpconnect/tests/components/native/Makefile.in
js/src/xpconnect/tests/components/native/xpctest.manifest
js/src/xpconnect/tests/components/native/xpctest_attributes.cpp
js/src/xpconnect/tests/components/native/xpctest_module.cpp
js/src/xpconnect/tests/components/native/xpctest_params.cpp
js/src/xpconnect/tests/components/native/xpctest_private.h
js/src/xpconnect/tests/components/xpctest_array.cpp
js/src/xpconnect/tests/components/xpctest_attributes.cpp
js/src/xpconnect/tests/components/xpctest_calljs.cpp
js/src/xpconnect/tests/components/xpctest_child.cpp
js/src/xpconnect/tests/components/xpctest_const.cpp
js/src/xpconnect/tests/components/xpctest_domstring.cpp
js/src/xpconnect/tests/components/xpctest_echo.cpp
js/src/xpconnect/tests/components/xpctest_in.cpp
js/src/xpconnect/tests/components/xpctest_inout.cpp
js/src/xpconnect/tests/components/xpctest_module.cpp
js/src/xpconnect/tests/components/xpctest_multiple.cpp
js/src/xpconnect/tests/components/xpctest_noisy.cpp
js/src/xpconnect/tests/components/xpctest_out.cpp
js/src/xpconnect/tests/components/xpctest_overloaded.cpp
js/src/xpconnect/tests/components/xpctest_private.h
js/src/xpconnect/tests/components/xpctest_string.cpp
js/src/xpconnect/tests/components/xpctest_variant.cpp
js/src/xpconnect/tests/idl/Makefile.in
js/src/xpconnect/tests/idl/xpctest.idl
js/src/xpconnect/tests/idl/xpctest2.idl
js/src/xpconnect/tests/idl/xpctest_attributes.idl
js/src/xpconnect/tests/idl/xpctest_calljs.idl
js/src/xpconnect/tests/idl/xpctest_const.idl
js/src/xpconnect/tests/idl/xpctest_domstring.idl
js/src/xpconnect/tests/idl/xpctest_in.idl
js/src/xpconnect/tests/idl/xpctest_inout.idl
js/src/xpconnect/tests/idl/xpctest_multiple.idl
js/src/xpconnect/tests/idl/xpctest_out.idl
js/src/xpconnect/tests/idl/xpctest_params.idl
js/src/xpconnect/tests/js/readwriteattributes.js
js/src/xpconnect/tests/unit/test_attributes.js
js/src/xpconnect/tests/unit/test_params.js
js/src/xpconnect/tests/unit/xpcshell.ini
xpcom/reflect/xptcall/public/xptcall.h
xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_darwin.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp
xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_solaris.cpp
xpcom/reflect/xptinfo/public/xptinfo.h
--- a/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
+++ b/content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
@@ -345,26 +345,21 @@ private:
     PRUint8 mCount;
 };
 
 txParamArrayHolder::~txParamArrayHolder()
 {
     PRUint8 i;
     for (i = 0; i < mCount; ++i) {
         nsXPTCVariant &variant = mArray[i];
-        if (variant.DoesValNeedCleanup()) {
-            if (variant.type.TagPart() == nsXPTType::T_DOMSTRING)
-                delete (nsAString*)variant.val.p;
-            else {
-                NS_ABORT_IF_FALSE(variant.type.TagPart() == nsXPTType::T_INTERFACE ||
-                                  variant.type.TagPart() == nsXPTType::T_INTERFACE_IS,
-                                  "We only support cleanup of strings and interfaces "
-                                  "here, and this looks like neither!");
-                static_cast<nsISupports*>(variant.val.p)->Release();
-            }
+        if (variant.IsValInterface()) {
+            static_cast<nsISupports*>(variant.val.p)->Release();
+        }
+        else if (variant.IsValDOMString()) {
+            delete (nsAString*)variant.val.p;
         }
     }
 }
 
 PRBool
 txParamArrayHolder::Init(PRUint8 aCount)
 {
     mCount = aCount;
@@ -419,17 +414,17 @@ txXPCOMExtensionFunctionCall::evaluate(t
         // Create context wrapper.
         context = new txFunctionEvaluationContext(aContext, mState);
         if (!context) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
 
         nsXPTCVariant &invokeParam = invokeParams[0];
         invokeParam.type = paramInfo.GetType();
-        invokeParam.SetValNeedsCleanup();
+        invokeParam.SetValIsInterface();
         NS_ADDREF((txIFunctionEvaluationContext*&)invokeParam.val.p = context);
 
         // Skip first argument, since it's the context.
         paramStart = 1;
     }
     else {
         context = nsnull;
     }
@@ -467,17 +462,17 @@ txXPCOMExtensionFunctionCall::evaluate(t
                 if (!adaptor) {
                     return NS_ERROR_OUT_OF_MEMORY;
                 }
 
                 nsCOMPtr<txINodeSet> nodeSet = adaptor;
                 rv = adaptor->Init();
                 NS_ENSURE_SUCCESS(rv, rv);
 
-                invokeParam.SetValNeedsCleanup();
+                invokeParam.SetValIsInterface();
                 nodeSet.swap((txINodeSet*&)invokeParam.val.p);
                 break;
             }
             case eBOOLEAN:
             {
                 rv = expr->evaluateToBool(aContext, invokeParam.val.b);
                 NS_ENSURE_SUCCESS(rv, rv);
 
@@ -497,33 +492,33 @@ txXPCOMExtensionFunctionCall::evaluate(t
                 nsString *value = new nsString();
                 if (!value) {
                     return NS_ERROR_OUT_OF_MEMORY;
                 }
 
                 rv = expr->evaluateToString(aContext, *value);
                 NS_ENSURE_SUCCESS(rv, rv);
 
-                invokeParam.SetValNeedsCleanup();
+                invokeParam.SetValIsDOMString();
                 invokeParam.val.p = value;
                 break;
             }
             case eOBJECT:
             {
               nsRefPtr<txAExprResult> exprRes;
               rv = expr->evaluate(aContext, getter_AddRefs(exprRes));
               NS_ENSURE_SUCCESS(rv, rv);
 
               nsCOMPtr<txIXPathObject> adaptor =
                 new txXPathObjectAdaptor(exprRes);
               if (!adaptor) {
                   return NS_ERROR_OUT_OF_MEMORY;
               }
 
-              invokeParam.SetValNeedsCleanup();
+              invokeParam.SetValIsInterface();
               adaptor.swap((txIXPathObject*&)invokeParam.val.p);
               break;
             }
             case eCONTEXT:
             case eUNKNOWN:
             {
                 // We only support passing the context as the *first* argument.
                 return NS_ERROR_FAILURE;
@@ -540,24 +535,25 @@ txXPCOMExtensionFunctionCall::evaluate(t
     nsXPTCVariant &returnParam = invokeParams[inArgs];
     returnParam.type = returnInfo.GetType();
     if (returnType == eSTRING) {
         nsString *value = new nsString();
         if (!value) {
             return NS_ERROR_FAILURE;
         }
 
-        returnParam.SetValNeedsCleanup();
+        returnParam.SetValIsDOMString();
         returnParam.val.p = value;
     }
     else {
-        returnParam.SetIndirect();
+        returnParam.SetPtrIsData();
         if (returnType == eNODESET || returnType == eOBJECT) {
-            returnParam.SetValNeedsCleanup();
+            returnParam.SetValIsInterface();
         }
+        returnParam.ptr = &returnParam.val;
     }
 
     rv = NS_InvokeByIndex(mHelper, mMethodIndex, paramCount, invokeParams);
 
     // In case someone is holding on to the txFunctionEvaluationContext which
     // could thus stay alive longer than this function.
     if (context) {
         context->ClearContext();
--- a/js/src/xpconnect/src/xpccontext.cpp
+++ b/js/src/xpconnect/src/xpccontext.cpp
@@ -53,16 +53,18 @@ XPCContext::XPCContext(XPCJSRuntime* aRu
         mSecurityManager(nsnull),
         mException(nsnull),
         mCallingLangType(LANG_UNKNOWN),
         mSecurityManagerFlags(0)
 {
     MOZ_COUNT_CTOR(XPCContext);
 
     PR_INIT_CLIST(&mScopes);
+    for(const char** p =  XPC_ARG_FORMATTER_FORMAT_STRINGS; *p; p++)
+        JS_AddArgumentFormatter(mJSContext, *p, XPC_JSArgumentFormatter);
 
     NS_ASSERTION(!mJSContext->data2, "Must be null");
     mJSContext->data2 = this;
 }
 
 XPCContext::~XPCContext()
 {
     MOZ_COUNT_DTOR(XPCContext);
--- a/js/src/xpconnect/src/xpcconvert.cpp
+++ b/js/src/xpconnect/src/xpcconvert.cpp
@@ -667,33 +667,45 @@ XPCConvert::JSData2Native(XPCCallContext
             {
                 *((uint16*)d) = 0;
                 break;
             }
             *((uint16*)d) = (uint16) chars[0];
             break;
         }
     case nsXPTType::T_JSVAL :
-        *((jsval*)d) = s;
-        break;
+        {
+            if (useAllocator) {
+                // The C++ type is (const jsval &), which here means (jsval *).
+                jsval *buf = new jsval(s);
+                if(!buf)
+                    return JS_FALSE;
+                *((jsval**)d) = buf;
+            } else {
+                *((jsval*)d) = s;
+            }
+            break;
+        }
     default:
         if(!type.IsPointer())
         {
             NS_ERROR("unsupported type");
             return JS_FALSE;
         }
 
         switch(type.TagPart())
         {
         case nsXPTType::T_VOID:
             XPC_LOG_ERROR(("XPCConvert::JSData2Native : void* params not supported"));
             NS_ERROR("void* params not supported");
             return JS_FALSE;
         case nsXPTType::T_IID:
         {
+            NS_ASSERTION(useAllocator,"trying to convert a JSID to nsID without allocator : this would leak");
+
             JSObject* obj;
             const nsID* pid=nsnull;
 
             if(JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s))
             {
                 if(type.IsReference())
                 {
                     if(pErr)
@@ -813,16 +825,23 @@ XPCConvert::JSData2Native(XPCCallContext
                 else
                     ws->Assign(chars, length);
             }
             return JS_TRUE;
         }
 
         case nsXPTType::T_CHAR_STR:
         {
+            NS_ASSERTION(useAllocator,"cannot convert a JSString to char * without allocator");
+            if(!useAllocator)
+            {
+                NS_ERROR("bad type");
+                return JS_FALSE;
+            }
+            
             if(JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s))
             {
                 if(type.IsReference())
                 {
                     if(pErr)
                         *pErr = NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF;
                     return JS_FALSE;
                 }
@@ -883,30 +902,41 @@ XPCConvert::JSData2Native(XPCCallContext
                 *((jschar**)d) = nsnull;
                 return JS_TRUE;
             }
 
             if(!(str = JS_ValueToString(cx, s)))
             {
                 return JS_FALSE;
             }
-            if(!(chars = JS_GetStringCharsZ(cx, str)))
+            if(useAllocator)
             {
-                return JS_FALSE;
+                if(!(chars = JS_GetStringCharsZ(cx, str)))
+                {
+                    return JS_FALSE;
+                }
+                int len = JS_GetStringLength(str);
+                int byte_len = (len+1)*sizeof(jschar);
+                if(!(*((void**)d) = nsMemory::Alloc(byte_len)))
+                {
+                    // XXX should report error
+                    return JS_FALSE;
+                }
+                jschar* destchars = *((jschar**)d);
+                memcpy(destchars, chars, byte_len);
+                destchars[len] = 0;
             }
-            int len = JS_GetStringLength(str);
-            int byte_len = (len+1)*sizeof(jschar);
-            if(!(*((void**)d) = nsMemory::Alloc(byte_len)))
+            else
             {
-                // XXX should report error
-                return JS_FALSE;
+                if(!(chars = JS_GetStringCharsZ(cx, str)))
+                {
+                    return JS_FALSE;
+                }
+                *((const jschar**)d) = chars;
             }
-            jschar* destchars = *((jschar**)d);
-            memcpy(destchars, chars, byte_len);
-            destchars[len] = 0;
 
             return JS_TRUE;
         }
 
         case nsXPTType::T_UTF8STRING:            
         {
             const jschar* chars;
             PRUint32 length;
@@ -1814,16 +1844,117 @@ XPCConvert::JSErrorToXPCException(XPCCal
     {
         rv = ConstructException(NS_ERROR_XPC_JAVASCRIPT_ERROR,
                                 nsnull, ifaceName, methodName, nsnull,
                                 exceptn, nsnull, nsnull);
     }
     return rv;
 }
 
+
+/***************************************************************************/
+
+/*
+** Note: on some platforms va_list is defined as an array,
+** and requires array notation.
+*/
+#ifdef HAVE_VA_COPY
+#define VARARGS_ASSIGN(foo, bar)	VA_COPY(foo,bar)
+#elif defined(HAVE_VA_LIST_AS_ARRAY)
+#define VARARGS_ASSIGN(foo, bar)	foo[0] = bar[0]
+#else
+#define VARARGS_ASSIGN(foo, bar)	(foo) = (bar)
+#endif
+
+// We assert below that these formats all begin with "%i".
+const char* XPC_ARG_FORMATTER_FORMAT_STRINGS[] = {"%ip", "%iv", "%is", nsnull};
+
+JSBool
+XPC_JSArgumentFormatter(JSContext *cx, const char *format,
+                        JSBool fromJS, jsval **vpp, va_list *app)
+{
+    XPCCallContext ccx(NATIVE_CALLER, cx);
+    if(!ccx.IsValid())
+        return JS_FALSE;
+
+    jsval *vp;
+    va_list ap;
+
+    vp = *vpp;
+    VARARGS_ASSIGN(ap, *app);
+
+    nsXPTType type;
+    const nsIID* iid;
+    void* p;
+
+    NS_ASSERTION(format[0] == '%' && format[1] == 'i', "bad format!");
+    char which = format[2];
+
+    if(fromJS)
+    {
+        switch(which)
+        {
+            case 'p':
+                type = nsXPTType((uint8)(TD_INTERFACE_TYPE | XPT_TDP_POINTER));                
+                iid = &NS_GET_IID(nsISupports);
+                break;
+            case 'v':
+                type = nsXPTType((uint8)(TD_INTERFACE_TYPE | XPT_TDP_POINTER));                
+                iid = &NS_GET_IID(nsIVariant);
+                break;
+            case 's':
+                type = nsXPTType((uint8)(TD_DOMSTRING | XPT_TDP_POINTER));                
+                iid = nsnull;
+                p = va_arg(ap, void *);
+                break;
+            default:
+                NS_ERROR("bad format!");
+                return JS_FALSE;
+        }
+
+        if(!XPCConvert::JSData2Native(ccx, &p, vp[0], type, JS_FALSE,
+                                      iid, nsnull))
+            return JS_FALSE;
+        
+        if(which != 's')
+            *va_arg(ap, void **) = p;
+    }
+    else
+    {
+        switch(which)
+        {
+            case 'p':
+                type = nsXPTType((uint8)(TD_INTERFACE_TYPE | XPT_TDP_POINTER));                
+                iid  = va_arg(ap, const nsIID*);
+                break;
+            case 'v':
+                type = nsXPTType((uint8)(TD_INTERFACE_TYPE | XPT_TDP_POINTER));                
+                iid = &NS_GET_IID(nsIVariant);
+                break;
+            case 's':
+                type = nsXPTType((uint8)(TD_DOMSTRING | XPT_TDP_POINTER));                
+                iid = nsnull;
+                break;
+            default:
+                NS_ERROR("bad format!");
+                return JS_FALSE;
+        }
+
+        // NOTE: MUST be retrieved *after* the iid in the 'p' case above.
+        p = va_arg(ap, void *);
+
+        ccx.SetScopeForNewJSObjects(JS_GetGlobalForScopeChain(cx));
+        if(!XPCConvert::NativeData2JS(ccx, &vp[0], &p, type, iid, nsnull))
+            return JS_FALSE;
+    }
+    *vpp = vp + 1;
+    VARARGS_ASSIGN(*app, ap);
+    return JS_TRUE;
+}
+
 /***************************************************************************/
 
 // array fun...
 
 #ifdef POPULATE
 #undef POPULATE
 #endif
 
@@ -1914,17 +2045,18 @@ failure:
 
 #undef POPULATE
 }
 
 // static
 JSBool
 XPCConvert::JSArray2Native(XPCCallContext& ccx, void** d, jsval s,
                            JSUint32 count, JSUint32 capacity,
-                           const nsXPTType& type, const nsID* iid,
+                           const nsXPTType& type,
+                           JSBool useAllocator, const nsID* iid,
                            uintN* pErr)
 {
     NS_PRECONDITION(d, "bad param");
 
     JSContext* cx = ccx.GetJSContext();
 
     // No Action, FRee memory, RElease object
     enum CleanupMode {na, fr, re};
@@ -1994,17 +2126,17 @@ XPCConvert::JSArray2Native(XPCCallContex
             if(pErr)                                                         \
                 *pErr = NS_ERROR_OUT_OF_MEMORY;                              \
             goto failure;                                                    \
         }                                                                    \
         for(initedCount = 0; initedCount < count; initedCount++)             \
         {                                                                    \
             if(!JS_GetElement(cx, jsarray, initedCount, &current) ||         \
                !JSData2Native(ccx, ((_t*)array)+initedCount, current, type,  \
-                              JS_TRUE, iid, pErr))                           \
+                              useAllocator, iid, pErr))                      \
                 goto failure;                                                \
         }                                                                    \
     PR_END_MACRO
 
 
     // XXX check IsPtr - esp. to handle array of nsID (as opposed to nsID*)
 
     // XXX make extra space at end of char* and wchar* and null termintate
@@ -2051,17 +2183,17 @@ failure:
         {
             nsISupports** a = (nsISupports**) array;
             for(PRUint32 i = 0; i < initedCount; i++)
             {
                 nsISupports* p = a[i];
                 NS_IF_RELEASE(p);
             }
         }
-        else if(cleanupMode == fr)
+        else if(cleanupMode == fr && useAllocator)
         {
             void** a = (void**) array;
             for(PRUint32 i = 0; i < initedCount; i++)
             {
                 void* p = a[i];
                 if(p) nsMemory::Free(p);
             }
         }
@@ -2123,16 +2255,17 @@ XPCConvert::NativeStringWithSize2JS(JSCo
     return JS_TRUE;
 }
 
 // static
 JSBool
 XPCConvert::JSStringWithSize2Native(XPCCallContext& ccx, void* d, jsval s,
                                     JSUint32 count, JSUint32 capacity,
                                     const nsXPTType& type,
+                                    JSBool useAllocator,
                                     uintN* pErr)
 {
     NS_PRECONDITION(!JSVAL_IS_NULL(s), "bad param");
     NS_PRECONDITION(d, "bad param");
 
     JSContext* cx = ccx.GetJSContext();
 
     JSUint32 len;
@@ -2151,16 +2284,23 @@ XPCConvert::JSStringWithSize2Native(XPCC
     {
         XPC_LOG_ERROR(("XPCConvert::JSStringWithSize2Native : unsupported type"));
         return JS_FALSE;
     }
     switch(type.TagPart())
     {
         case nsXPTType::T_PSTRING_SIZE_IS:
         {
+            NS_ASSERTION(useAllocator,"cannot convert a JSString to char * without allocator");
+            if(!useAllocator)
+            {
+                XPC_LOG_ERROR(("XPCConvert::JSStringWithSize2Native : unsupported type"));
+                return JS_FALSE;
+            }
+
             if(JSVAL_IS_VOID(s) || JSVAL_IS_NULL(s))
             {
                 if(0 != count)
                 {
                     if(pErr)
                         *pErr = NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING;
                     return JS_FALSE;
                 }
@@ -2234,17 +2374,17 @@ XPCConvert::JSStringWithSize2Native(XPCC
                 }
                 if(type.IsReference())
                 {
                     if(pErr)
                         *pErr = NS_ERROR_XPC_BAD_CONVERT_JS_NULL_REF;
                     return JS_FALSE;
                 }
 
-                if(0 != capacity)
+                if(useAllocator && 0 != capacity)
                 {
                     len = (capacity + 1) * sizeof(jschar);
                     if(!(*((void**)d) = nsMemory::Alloc(len)))
                         return JS_FALSE;
                     return JS_TRUE;
                 }
 
                 // else ...
@@ -2262,28 +2402,39 @@ XPCConvert::JSStringWithSize2Native(XPCC
             {
                 if(pErr)
                     *pErr = NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING;
                 return JS_FALSE;
             }
             if(len < capacity)
                 len = capacity;
 
-            if(!(chars = JS_GetStringCharsZ(cx, str)))
+            if(useAllocator)
             {
-                return JS_FALSE;
+                if(!(chars = JS_GetStringCharsZ(cx, str)))
+                {
+                    return JS_FALSE;
+                }
+                JSUint32 alloc_len = (len + 1) * sizeof(jschar);
+                if(!(*((void**)d) = nsMemory::Alloc(alloc_len)))
+                {
+                    // XXX should report error
+                    return JS_FALSE;
+                }
+                memcpy(*((jschar**)d), chars, alloc_len);
+                (*((jschar**)d))[count] = 0;
             }
-            JSUint32 alloc_len = (len + 1) * sizeof(jschar);
-            if(!(*((void**)d) = nsMemory::Alloc(alloc_len)))
+            else
             {
-                // XXX should report error
-                return JS_FALSE;
+                if(!(chars = JS_GetStringCharsZ(cx, str)))
+                {
+                    return JS_FALSE;
+                }
+                *((const jschar**)d) = chars;
             }
-            memcpy(*((jschar**)d), chars, alloc_len);
-            (*((jschar**)d))[count] = 0;
 
             return JS_TRUE;
         }
         default:
             XPC_LOG_ERROR(("XPCConvert::JSStringWithSize2Native : unsupported type"));
             return JS_FALSE;
     }
 }
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -218,16 +218,17 @@ void DEBUG_CheckWrapperThreadSafety(cons
 #define XPC_NATIVE_SET_MAP_SIZE             64
 #define XPC_NATIVE_JSCLASS_MAP_SIZE         32
 #define XPC_THIS_TRANSLATOR_MAP_SIZE         8
 #define XPC_NATIVE_WRAPPER_MAP_SIZE         16
 #define XPC_WRAPPER_MAP_SIZE                16
 
 /***************************************************************************/
 // data declarations...
+extern const char* XPC_ARG_FORMATTER_FORMAT_STRINGS[]; // format strings
 extern const char XPC_CONTEXT_STACK_CONTRACTID[];
 extern const char XPC_RUNTIME_CONTRACTID[];
 extern const char XPC_EXCEPTION_CONTRACTID[];
 extern const char XPC_CONSOLE_CONTRACTID[];
 extern const char XPC_SCRIPT_ERROR_CONTRACTID[];
 extern const char XPC_ID_CONTRACTID[];
 extern const char XPC_XPCONNECT_CONTRACTID[];
 
@@ -3296,28 +3297,31 @@ public:
      */    
     static JSBool NativeArray2JS(XPCLazyCallContext& ccx,
                                  jsval* d, const void** s,
                                  const nsXPTType& type, const nsID* iid,
                                  JSUint32 count, nsresult* pErr);
 
     static JSBool JSArray2Native(XPCCallContext& ccx, void** d, jsval s,
                                  JSUint32 count, JSUint32 capacity,
-                                 const nsXPTType& type, const nsID* iid,
+                                 const nsXPTType& type,
+                                 JSBool useAllocator, const nsID* iid,
                                  uintN* pErr);
 
     static JSBool NativeStringWithSize2JS(JSContext* cx,
                                           jsval* d, const void* s,
                                           const nsXPTType& type,
                                           JSUint32 count,
                                           nsresult* pErr);
 
     static JSBool JSStringWithSize2Native(XPCCallContext& ccx, void* d, jsval s,
                                           JSUint32 count, JSUint32 capacity,
-                                          const nsXPTType& type, uintN* pErr);
+                                          const nsXPTType& type,
+                                          JSBool useAllocator,
+                                          uintN* pErr);
 
     static nsresult JSValToXPCException(XPCCallContext& ccx,
                                         jsval s,
                                         const char* ifaceName,
                                         const char* methodName,
                                         nsIException** exception);
 
     static nsresult JSErrorToXPCException(XPCCallContext& ccx,
@@ -3356,16 +3360,21 @@ public:
                                  nsStringBuffer** sharedBuffer);
 
     static void ShutdownDOMStringFinalizer();
 
 private:
     XPCStringConvert();         // not implemented
 };
 
+extern JSBool
+XPC_JSArgumentFormatter(JSContext *cx, const char *format,
+                        JSBool fromJS, jsval **vpp, va_list *app);
+
+
 /***************************************************************************/
 // code for throwing exceptions into JS
 
 class XPCThrower
 {
 public:
     static void Throw(nsresult rv, JSContext* cx);
     static void Throw(nsresult rv, XPCCallContext& ccx);
--- a/js/src/xpconnect/src/xpcvariant.cpp
+++ b/js/src/xpconnect/src/xpcvariant.cpp
@@ -383,17 +383,18 @@ JSBool XPCVariant::InitializeData(XPCCal
         nsXPTType type;
         nsID id;
 
         if(!XPCArrayHomogenizer::GetTypeForArray(ccx, jsobj, len, &type, &id))
             return JS_FALSE; 
 
         if(!XPCConvert::JSArray2Native(ccx, &mData.u.array.mArrayValue, 
                                        val, len, len,
-                                       type, &id, nsnull))
+                                       type, type.IsPointer(),
+                                       &id, nsnull))
             return JS_FALSE;
 
         mData.mType = nsIDataType::VTYPE_ARRAY;
         if(type.IsInterfacePointer())
             mData.u.array.mArrayInterfaceID = id;
         mData.u.array.mArrayCount = len;
         mData.u.array.mArrayType = type.TagPart();
         
@@ -549,51 +550,51 @@ XPCVariant::VariantDataToJS(XPCLazyCallC
                 return JS_FALSE;
             xpctvar.type = (uint8)(TD_UTF8STRING | XPT_TDP_POINTER);
             xpctvar.val.p = &utf8String;
             break;       
         case nsIDataType::VTYPE_CHAR_STR:       
             if(NS_FAILED(variant->GetAsString((char**)&xpctvar.val.p)))
                 return JS_FALSE;
             xpctvar.type = (uint8)(TD_PSTRING | XPT_TDP_POINTER);
-            xpctvar.SetValNeedsCleanup();
+            xpctvar.SetValIsAllocated();
             break;
         case nsIDataType::VTYPE_STRING_SIZE_IS:
             if(NS_FAILED(variant->GetAsStringWithSize(&size, 
                                                       (char**)&xpctvar.val.p)))
                 return JS_FALSE;
             xpctvar.type = (uint8)(TD_PSTRING_SIZE_IS | XPT_TDP_POINTER);
-            xpctvar.SetValNeedsCleanup();
+            xpctvar.SetValIsAllocated();
             break;
         case nsIDataType::VTYPE_WCHAR_STR:        
             if(NS_FAILED(variant->GetAsWString((PRUnichar**)&xpctvar.val.p)))
                 return JS_FALSE;
             xpctvar.type = (uint8)(TD_PWSTRING | XPT_TDP_POINTER);
-            xpctvar.SetValNeedsCleanup();
+            xpctvar.SetValIsAllocated();
             break;
         case nsIDataType::VTYPE_WSTRING_SIZE_IS:        
             if(NS_FAILED(variant->GetAsWStringWithSize(&size, 
                                                       (PRUnichar**)&xpctvar.val.p)))
                 return JS_FALSE;
             xpctvar.type = (uint8)(TD_PWSTRING_SIZE_IS | XPT_TDP_POINTER);
-            xpctvar.SetValNeedsCleanup();
+            xpctvar.SetValIsAllocated();
             break;
         case nsIDataType::VTYPE_INTERFACE:        
         case nsIDataType::VTYPE_INTERFACE_IS:        
         {
             nsID* piid;
             if(NS_FAILED(variant->GetAsInterface(&piid, &xpctvar.val.p)))
                 return JS_FALSE;
 
             iid = *piid;
             nsMemory::Free((char*)piid);
 
             xpctvar.type = (uint8)(TD_INTERFACE_IS_TYPE | XPT_TDP_POINTER);
             if(xpctvar.val.p)
-                xpctvar.SetValNeedsCleanup();
+                xpctvar.SetValIsInterface();
             break;
         }
         case nsIDataType::VTYPE_ARRAY:
         {
             nsDiscriminatedUnion du;
             nsVariant::Initialize(&du);
             nsresult rv;
 
@@ -704,25 +705,20 @@ VARIANT_DONE:
     else
     {
         success = XPCConvert::NativeData2JS(lccx, pJSVal,
                                             (const void*)&xpctvar.val,
                                             xpctvar.type,
                                             &iid, pErr);
     }
 
-    // We may have done something in the above code that requires cleanup.
-    if (xpctvar.DoesValNeedCleanup())
-    {
-        if (type == nsIDataType::VTYPE_INTERFACE ||
-            type == nsIDataType::VTYPE_INTERFACE_IS)
-            ((nsISupports*)xpctvar.val.p)->Release();
-        else
-            nsMemory::Free((char*)xpctvar.val.p);
-    }
+    if(xpctvar.IsValAllocated())
+        nsMemory::Free((char*)xpctvar.val.p);
+    else if(xpctvar.IsValInterface())
+        ((nsISupports*)xpctvar.val.p)->Release();
 
     return success;
 }
 
 /***************************************************************************/
 /***************************************************************************/
 // XXX These default implementations need to be improved to allow for
 // some more interesting conversions.
--- a/js/src/xpconnect/src/xpcwrappedjsclass.cpp
+++ b/js/src/xpconnect/src/xpcwrappedjsclass.cpp
@@ -384,20 +384,17 @@ GetNamedPropertyAsVariantRaw(XPCCallCont
                              jsid aName, 
                              nsIVariant** aResult,
                              nsresult* pErr)
 {
     nsXPTType type = nsXPTType((uint8)(TD_INTERFACE_TYPE | XPT_TDP_POINTER));
     jsval val;
 
     return JS_GetPropertyById(ccx, aJSObj, aName, &val) &&
-           // Note that this always takes the T_INTERFACE path through
-           // JSData2Native, so the value passed for useAllocator
-           // doesn't really matter. We pass true for consistency.
-           XPCConvert::JSData2Native(ccx, aResult, val, type, JS_TRUE,
+           XPCConvert::JSData2Native(ccx, aResult, val, type, JS_FALSE, 
                                      &NS_GET_IID(nsIVariant), pErr);
 }
 
 // static
 nsresult
 nsXPCWrappedJSClass::GetNamedPropertyAsVariant(XPCCallContext& ccx, 
                                                JSObject* aJSObj,
                                                jsval aName, 
@@ -930,17 +927,17 @@ nsXPCWrappedJSClass::GetArraySizeFromPar
 
     const nsXPTParamInfo& arg_param = method->params[argnum];
     const nsXPTType& arg_type = arg_param.GetType();
 
     // The xpidl compiler ensures this. We reaffirm it for safety.
     if(arg_type.IsPointer() || arg_type.TagPart() != nsXPTType::T_U32)
         return JS_FALSE;
 
-    if(arg_param.IsIndirect())
+    if(arg_param.IsOut())
         *result = *(JSUint32*)nativeParams[argnum].val.p;
     else
         *result = nativeParams[argnum].val.u32;
 
     return JS_TRUE;
 }
 
 JSBool
@@ -971,17 +968,17 @@ nsXPCWrappedJSClass::GetInterfaceTypeFro
         if(NS_FAILED(rv))
             return JS_FALSE;
 
         const nsXPTParamInfo& arg_param = method->params[argnum];
         const nsXPTType& arg_type = arg_param.GetType();
         if(arg_type.IsPointer() &&
            arg_type.TagPart() == nsXPTType::T_IID)
         {
-            if(arg_param.IsIndirect())
+            if(arg_param.IsOut())
             {
                 nsID** p = (nsID**) nativeParams[argnum].val.p;
                 if(!p || !*p)
                     return JS_FALSE;
                 *result = **p;
             }
             else
             {
@@ -1507,17 +1504,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
         }
         else
             datum_type = type;
 
         if(param.IsIn())
         {
             nsXPTCMiniVariant* pv;
 
-            if(param.IsIndirect())
+            if(param.IsOut())
                 pv = (nsXPTCMiniVariant*) nativeParams[i].val.p;
             else
                 pv = &nativeParams[i];
 
             if(datum_type.IsInterfacePointer() &&
                !GetInterfaceTypeFromParam(cx, info, param, methodIndex,
                                           datum_type, nativeParams,
                                           &param_iid))
@@ -1706,29 +1703,29 @@ pre_call_clean_up:
     // When we later convert the dependent params (if any) we will know that
     // the params upon which they depend will have already been converted -
     // regardless of ordering.
 
     foundDependentParam = JS_FALSE;
     for(i = 0; i < paramCount; i++)
     {
         const nsXPTParamInfo& param = info->params[i];
-        NS_ABORT_IF_FALSE(!param.IsShared(), "[shared] implies [noscript]!");
         if(!param.IsOut() && !param.IsDipper())
             continue;
 
         const nsXPTType& type = param.GetType();
         if(type.IsDependent())
         {
             foundDependentParam = JS_TRUE;
             continue;
         }
 
         jsval val;
         uint8 type_tag = type.TagPart();
+        JSBool useAllocator = JS_FALSE;
         nsXPTCMiniVariant* pv;
 
         if(param.IsDipper())
             pv = (nsXPTCMiniVariant*) &nativeParams[i].val.p;
         else
             pv = (nsXPTCMiniVariant*) nativeParams[i].val.p;
 
         if(param.IsRetval())
@@ -1743,19 +1740,21 @@ pre_call_clean_up:
 
         if(type_tag == nsXPTType::T_INTERFACE)
         {
             if(NS_FAILED(GetInterfaceInfo()->
                             GetIIDForParamNoAlloc(methodIndex, &param,
                                                   &param_iid)))
                 break;
         }
+        else if(type.IsPointer() && !param.IsShared() && !param.IsDipper())
+            useAllocator = JS_TRUE;
 
         if(!XPCConvert::JSData2Native(ccx, &pv->val, val, type,
-                                      !param.IsDipper(), &param_iid, nsnull))
+                                      useAllocator, &param_iid, nsnull))
             break;
     }
 
     // if any params were dependent, then we must iterate again to convert them.
     if(foundDependentParam && i == paramCount)
     {
         for(i = 0; i < paramCount; i++)
         {
@@ -1765,16 +1764,17 @@ pre_call_clean_up:
 
             const nsXPTType& type = param.GetType();
             if(!type.IsDependent())
                 continue;
 
             jsval val;
             nsXPTCMiniVariant* pv;
             nsXPTType datum_type;
+            JSBool useAllocator = JS_FALSE;
             JSUint32 array_count;
             PRBool isArray = type.IsArray();
             PRBool isSizedString = isArray ?
                     JS_FALSE :
                     type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
                     type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
 
             pv = (nsXPTCMiniVariant*) nativeParams[i].val.p;
@@ -1799,46 +1799,50 @@ pre_call_clean_up:
 
             if(datum_type.IsInterfacePointer())
             {
                if(!GetInterfaceTypeFromParam(cx, info, param, methodIndex,
                                              datum_type, nativeParams,
                                              &param_iid))
                    break;
             }
+            else if(type.IsPointer() && !param.IsShared())
+                useAllocator = JS_TRUE;
 
             if(isArray || isSizedString)
             {
                 if(!GetArraySizeFromParam(cx, info, param, methodIndex,
                                           i, GET_LENGTH, nativeParams,
                                           &array_count))
                     break;
             }
 
             if(isArray)
             {
                 if(array_count &&
                    !XPCConvert::JSArray2Native(ccx, (void**)&pv->val, val,
                                                array_count, array_count,
-                                               datum_type, &param_iid,
+                                               datum_type,
+                                               useAllocator, &param_iid,
                                                nsnull))
                     break;
             }
             else if(isSizedString)
             {
                 if(!XPCConvert::JSStringWithSize2Native(ccx,
                                                    (void*)&pv->val, val,
                                                    array_count, array_count,
-                                                   datum_type, nsnull))
+                                                   datum_type, useAllocator,
+                                                   nsnull))
                     break;
             }
             else
             {
                 if(!XPCConvert::JSData2Native(ccx, &pv->val, val, type,
-                                              JS_TRUE, &param_iid,
+                                              useAllocator, &param_iid,
                                               nsnull))
                     break;
             }
         }
     }
 
     if(i != paramCount)
     {
--- a/js/src/xpconnect/src/xpcwrappednative.cpp
+++ b/js/src/xpconnect/src/xpcwrappednative.cpp
@@ -2176,16 +2176,22 @@ class CallMethodHelper
     nsISupports* const mCallee;
     const uint16 mVTableIndex;
     const jsid mIdxValueId;
 
     nsAutoTArray<nsXPTCVariant, 8> mDispatchParams;
     uint8 mJSContextIndex; // TODO make const
     uint8 mOptArgcIndex; // TODO make const
 
+    // Reserve space for one nsAutoString. We don't want the string itself
+    // to be declared as that would make the ctor and dtors run for each
+    // CallMethodHelper instantiation, and they're only needed in a
+    // fraction of all the calls that come through here.
+    js::Maybe<nsAutoString> mAutoString;
+
     jsval* const mArgv;
     const PRUint32 mArgc;
 
     enum SizeMode {
         eGetSize,
         eGetLength
     };
 
@@ -2232,24 +2238,18 @@ class CallMethodHelper
     GetDispatchParam(uint8 paramIndex) const
     {
         return const_cast<CallMethodHelper*>(this)->GetDispatchParam(paramIndex);
     }
 
     JS_ALWAYS_INLINE JSBool InitializeDispatchParams();
 
     JS_ALWAYS_INLINE JSBool ConvertIndependentParams(JSBool* foundDependentParam);
-    JS_ALWAYS_INLINE JSBool ConvertIndependentParam(uint8 i);
     JS_ALWAYS_INLINE JSBool ConvertDependentParams();
 
-    JS_ALWAYS_INLINE void CleanupParam(nsXPTCMiniVariant& param, nsXPTType& type);
-
-    JS_ALWAYS_INLINE JSBool HandleDipperParam(nsXPTCVariant* dp,
-                                              const nsXPTParamInfo& paramInfo);
-
     JS_ALWAYS_INLINE nsresult Invoke();
 
 public:
 
     CallMethodHelper(XPCCallContext& ccx)
         : mCallContext(ccx)
         , mIFaceInfo(ccx.GetInterface()->GetInterfaceInfo())
         , mMethodInfo(nsnull)
@@ -2388,59 +2388,79 @@ CallMethodHelper::Call()
 CallMethodHelper::~CallMethodHelper()
 {
     uint8 paramCount = mMethodInfo->GetParamCount();
     if (mDispatchParams.Length())
     {
         for(uint8 i = 0; i < paramCount; i++)
         {
             nsXPTCVariant* dp = GetDispatchParam(i);
-            const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i);
-
-            if(paramInfo.GetType().IsArray())
+
+            if(dp->IsValArray())
             {
                 void* p = dp->val.p;
                 if(!p)
                     continue;
 
-                // Clean up the array contents if necessary.
-                if(dp->DoesValNeedCleanup())
+                // going to have to cleanup the array and perhaps its contents
+                if(dp->IsValAllocated() || dp->IsValInterface())
                 {
-                    // We need some basic information to properly destroy the array.
+                    // we need to figure out how many elements are present.
                     JSUint32 array_count;
-                    nsXPTType datum_type;
-                    if(!GetArraySizeFromParam(i, &array_count) ||
-                       !NS_SUCCEEDED(mIFaceInfo->GetTypeForParam(mVTableIndex,
-                                                                 &paramInfo,
-                                                                 1, &datum_type)))
+
+                    if(!GetArraySizeFromParam(i, &array_count))
                     {
-                        // XXXbholley - I'm not convinced that the above calls will
-                        // ever fail.
-                        NS_ERROR("failed to get array information, we'll leak here");
+                        NS_ERROR("failed to get array length, we'll leak here");
                         continue;
                     }
-
-                    // Loop over the array contents. For each one, we create a
-                    // dummy 'val' and pass it to the cleanup helper.
-                    for(JSUint32 k = 0; k < array_count; k++)
+                    if(dp->IsValAllocated())
                     {
-                        nsXPTCMiniVariant v;
-                        v.val.p = static_cast<void**>(p)[k];
-                        CleanupParam(v, datum_type);
+                        void** a = (void**)p;
+                        for(JSUint32 k = 0; k < array_count; k++)
+                        {
+                            void* o = a[k];
+                            if(o) nsMemory::Free(o);
+                        }
+                    }
+                    else // if(dp->IsValInterface())
+                    {
+                        nsISupports** a = (nsISupports**)p;
+                        for(JSUint32 k = 0; k < array_count; k++)
+                        {
+                            nsISupports* o = a[k];
+                            NS_IF_RELEASE(o);
+                        }
                     }
                 }
-
                 // always free the array itself
                 nsMemory::Free(p);
             }
             else
             {
-                // Clean up single parameters (if requested).
-                if (dp->DoesValNeedCleanup())
-                    CleanupParam(*dp, dp->type);
+                if(dp->IsValJSRoot())
+                {
+                    NS_ASSERTION(!dp->IsValAllocated() && !dp->IsValInterface(),
+                                 "jsvals are their own class of values");
+                    JS_RemoveValueRoot(mCallContext, (jsval*)dp->ptr);
+                    continue;
+                }
+
+                void* p = dp->val.p;
+                if(!p)
+                    continue;
+                if(dp->IsValAllocated())
+                    nsMemory::Free(p);
+                else if(dp->IsValInterface())
+                    ((nsISupports*)p)->Release();
+                else if(dp->IsValDOMString())
+                    mCallContext.DeleteString((nsAString*)p);
+                else if(dp->IsValUTF8String())
+                    delete (nsCString*) p;
+                else if(dp->IsValCString())
+                    delete (nsCString*) p;
             }
         }
     }
 
 }
 
 JSBool
 CallMethodHelper::GetArrayInfoFromParam(uint8 paramIndex, SizeMode mode,
@@ -2781,132 +2801,173 @@ CallMethodHelper::InitializeDispatchPara
 }
 
 JSBool
 CallMethodHelper::ConvertIndependentParams(JSBool* foundDependentParam)
 {
     const uint8 paramCount = mMethodInfo->GetParamCount();
     for(uint8 i = 0; i < paramCount; i++)
     {
+        JSBool useAllocator = JS_FALSE;
         const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i);
-
-        if(paramInfo.GetType().IsDependent())
+        const nsXPTType& type = paramInfo.GetType();
+        uint8 type_tag = type.TagPart();
+
+        if(type.IsDependent())
+        {
             *foundDependentParam = JS_TRUE;
-        else if(!ConvertIndependentParam(i))
+            continue;
+        }
+
+        nsXPTCVariant* dp = GetDispatchParam(i);
+        dp->type = type;
+
+        if(type_tag == nsXPTType::T_INTERFACE)
+        {
+            dp->SetValIsInterface();
+        }
+
+        jsval src;
+
+        if (!GetOutParamSource(i, &src))
             return JS_FALSE;
 
-    }
-
-    return JS_TRUE;
-}
-
-JSBool
-CallMethodHelper::ConvertIndependentParam(uint8 i)
-{
-    const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i);
-    const nsXPTType& type = paramInfo.GetType();
-    uint8 type_tag = type.TagPart();
-    nsXPTCVariant* dp = GetDispatchParam(i);
-    dp->type = type;
-    NS_ABORT_IF_FALSE(!paramInfo.IsShared(), "[shared] implies [noscript]!");
-
-    // Handle dipper types separately.
-    if(paramInfo.IsDipper())
-        return HandleDipperParam(dp, paramInfo);
-
-    // Specify the correct storage/calling semantics.
-    if(paramInfo.IsIndirect())
-        dp->SetIndirect();
-
-    if(type_tag == nsXPTType::T_INTERFACE)
-    {
-        dp->SetValNeedsCleanup();
-    }
-
-    jsval src;
-
-    if (!GetOutParamSource(i, &src))
-        return JS_FALSE;
-
-    // The JSVal proper is always stored within the 'val' union and passed
-    // indirectly, regardless of in/out-ness.
-    if(type_tag == nsXPTType::T_JSVAL)
-    {
-        // Root the value.
-        dp->val.j = JSVAL_VOID;
-        if (!JS_AddValueRoot(mCallContext, &dp->val.j))
-            return JS_FALSE;
-        dp->SetValNeedsCleanup();
-    }
-
-    if(paramInfo.IsOut())
-    {
-        if(type.IsPointer() &&
-           type_tag != nsXPTType::T_INTERFACE)
+        if(paramInfo.IsOut())
         {
-            dp->SetValNeedsCleanup();
+            dp->SetPtrIsData();
+            dp->ptr = &dp->val;
+
+            if (type_tag == nsXPTType::T_JSVAL)
+            {
+                JS_STATIC_ASSERT(sizeof(jsval) <= sizeof(uint64));
+                jsval *rootp = (jsval *)&dp->val.u64;
+                dp->ptr = rootp;
+                *rootp = JSVAL_VOID;
+                if (!JS_AddValueRoot(mCallContext, rootp))
+                    return JS_FALSE;
+                dp->SetValIsJSRoot();
+            }
+
+            if(type.IsPointer() &&
+               type_tag != nsXPTType::T_INTERFACE &&
+               !paramInfo.IsShared())
+            {
+                useAllocator = JS_TRUE;
+                dp->SetValIsAllocated();
+            }
+
+            if(!paramInfo.IsIn())
+                continue;
         }
-
-        if(!paramInfo.IsIn())
-            return JS_TRUE;
-    }
-    else
-    {
-        if(type.IsPointer())
+        else
         {
-            switch(type_tag)
+            if(type.IsPointer())
             {
-            case nsXPTType::T_IID:
-                dp->SetValNeedsCleanup();
-                break;
-            case nsXPTType::T_CHAR_STR:
-                dp->SetValNeedsCleanup();
-                break;
-            case nsXPTType::T_ASTRING:
-                // Fall through to the T_DOMSTRING case
-
-            case nsXPTType::T_DOMSTRING:
-                dp->SetValNeedsCleanup();
-                break;
-
-            case nsXPTType::T_UTF8STRING:
-                // Fall through to the C string case for now...
-            case nsXPTType::T_CSTRING:
-                dp->SetValNeedsCleanup();
-                break;
+                switch(type_tag)
+                {
+                case nsXPTType::T_IID:
+                    dp->SetValIsAllocated();
+                    useAllocator = JS_TRUE;
+                    break;
+                case nsXPTType::T_CHAR_STR:
+                    dp->SetValIsAllocated();
+                    useAllocator = JS_TRUE;
+                    break;
+                case nsXPTType::T_ASTRING:
+                    // Fall through to the T_DOMSTRING case
+
+                case nsXPTType::T_DOMSTRING:
+                    if(paramInfo.IsDipper())
+                    {
+                        // Is an 'out' DOMString. Make a new nsAString
+                        // now and then continue in order to skip the call to
+                        // JSData2Native
+
+                        if(mAutoString.empty())
+                        {
+                            mAutoString.construct();
+                            // Don't call SetValIsDOMString because we don't
+                            // want to delete this pointer.
+                            dp->val.p = mAutoString.addr();
+                            continue;
+                        }
+
+                        dp->SetValIsDOMString();
+                        if(!(dp->val.p = new nsAutoString()))
+                        {
+                            JS_ReportOutOfMemory(mCallContext);
+                            return JS_FALSE;
+                        }
+                        continue;
+                    }
+                    // else...
+
+                    // Is an 'in' DOMString. Set 'useAllocator' to indicate
+                    // that JSData2Native should allocate a new
+                    // nsAString.
+                    dp->SetValIsDOMString();
+                    useAllocator = JS_TRUE;
+                    break;
+
+                case nsXPTType::T_UTF8STRING:
+                    // Fall through to the C string case for now...
+                case nsXPTType::T_CSTRING:
+                    dp->SetValIsCString();
+                    if(paramInfo.IsDipper())
+                    {
+                        // Is an 'out' CString.
+                        if(!(dp->val.p = new nsCString()))
+                        {
+                            JS_ReportOutOfMemory(mCallContext);
+                            return JS_FALSE;
+                        }
+                        continue;
+                    }
+                    // else ...
+                    // Is an 'in' CString.
+                    useAllocator = JS_TRUE;
+                    break;
+                }
             }
+            else {
+                if(type_tag == nsXPTType::T_JSVAL) {
+                    dp->SetValIsAllocated();
+                    useAllocator = JS_TRUE;
+                }
+            }
+
+            // Do this *after* the above because in the case where we have a
+            // "T_DOMSTRING && IsDipper()" then arg might be null since this
+            // is really an 'out' param masquerading as an 'in' param.
+            NS_ASSERTION(i < mArgc || paramInfo.IsOptional(),
+                         "Expected either enough arguments or an optional argument");
+            if(i < mArgc)
+                src = mArgv[i];
+            else if(type_tag == nsXPTType::T_JSVAL)
+                src = JSVAL_VOID;
+            else
+                src = JSVAL_NULL;
         }
 
-        // Do this *after* the above because in the case where we have a
-        // "T_DOMSTRING && IsDipper()" then arg might be null since this
-        // is really an 'out' param masquerading as an 'in' param.
-        NS_ASSERTION(i < mArgc || paramInfo.IsOptional(),
-                     "Expected either enough arguments or an optional argument");
-        if(i < mArgc)
-            src = mArgv[i];
-        else if(type_tag == nsXPTType::T_JSVAL)
-            src = JSVAL_VOID;
-        else
-            src = JSVAL_NULL;
-    }
-
-    nsID param_iid;
-    if(type_tag == nsXPTType::T_INTERFACE &&
-       NS_FAILED(mIFaceInfo->GetIIDForParamNoAlloc(mVTableIndex, &paramInfo,
-                                                   &param_iid)))
-    {
-        ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, i, mCallContext);
-        return JS_FALSE;
-    }
-
-    uintN err;
-    if(!XPCConvert::JSData2Native(mCallContext, &dp->val, src, type,
-                                  JS_TRUE, &param_iid, &err)) {
-        ThrowBadParam(err, i, mCallContext);
-        return JS_FALSE;
+        nsID param_iid;
+        if(type_tag == nsXPTType::T_INTERFACE &&
+           NS_FAILED(mIFaceInfo->GetIIDForParamNoAlloc(mVTableIndex, &paramInfo,
+                                                       &param_iid)))
+        {
+            ThrowBadParam(NS_ERROR_XPC_CANT_GET_PARAM_IFACE_INFO, i, mCallContext);
+            return JS_FALSE;
+        }
+
+        uintN err;
+        if(!XPCConvert::JSData2Native(mCallContext, &dp->val, src, type,
+                                      useAllocator, &param_iid, &err))
+        {
+            ThrowBadParam(err, i, mCallContext);
+            return JS_FALSE;
+        }
     }
 
     return JS_TRUE;
 }
 
 JSBool
 CallMethodHelper::ConvertDependentParams()
 {
@@ -2917,77 +2978,80 @@ CallMethodHelper::ConvertDependentParams
         const nsXPTType& type = paramInfo.GetType();
 
         if(!type.IsDependent())
             continue;
 
         nsXPTType datum_type;
         JSUint32 array_count;
         JSUint32 array_capacity;
+        JSBool useAllocator = JS_FALSE;
         PRBool isArray = type.IsArray();
 
         PRBool isSizedString = isArray ?
             JS_FALSE :
             type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
             type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
 
         nsXPTCVariant* dp = GetDispatchParam(i);
         dp->type = type;
 
-        // Specify the correct storage/calling semantics.
-        if(paramInfo.IsIndirect())
-            dp->SetIndirect();
-
         if(isArray)
         {
+            dp->SetValIsArray();
+
             if(NS_FAILED(mIFaceInfo->GetTypeForParam(mVTableIndex, &paramInfo, 1,
                                                      &datum_type)))
             {
                 Throw(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, mCallContext);
                 return JS_FALSE;
             }
         }
         else
             datum_type = type;
 
         if(datum_type.IsInterfacePointer())
         {
-            dp->SetValNeedsCleanup();
+            dp->SetValIsInterface();
         }
 
         jsval src;
 
         if (!GetOutParamSource(i, &src))
             return JS_FALSE;
 
         if(paramInfo.IsOut())
         {
+            dp->SetPtrIsData();
+            dp->ptr = &dp->val;
+
             if(datum_type.IsPointer() &&
                !datum_type.IsInterfacePointer() &&
-               isArray)
+               (isArray || !paramInfo.IsShared()))
             {
-                dp->SetValNeedsCleanup();
+                useAllocator = JS_TRUE;
+                dp->SetValIsAllocated();
             }
 
             if(!paramInfo.IsIn())
                 continue;
         }
         else
         {
             NS_ASSERTION(i < mArgc || paramInfo.IsOptional(),
                          "Expected either enough arguments or an optional argument");
             src = i < mArgc ? mArgv[i] : JSVAL_NULL;
 
             if((datum_type.IsPointer() &&
                 (datum_type.TagPart() == nsXPTType::T_IID ||
-                 datum_type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS) ||
-                 datum_type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS) ||
+                 datum_type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS)) ||
                (isArray && datum_type.TagPart() == nsXPTType::T_CHAR_STR))
             {
-                dp->SetValNeedsCleanup();
+                useAllocator = JS_TRUE;
+                dp->SetValIsAllocated();
             }
         }
 
         nsID param_iid;
         if(datum_type.IsInterfacePointer() &&
            !GetInterfaceTypeFromParam(i, datum_type, &param_iid))
             return JS_FALSE;
 
@@ -3000,148 +3064,53 @@ CallMethodHelper::ConvertDependentParams
                 return JS_FALSE;
 
             if(isArray)
             {
                 if(array_count &&
                    !XPCConvert::JSArray2Native(mCallContext, (void**)&dp->val, src,
                                                array_count, array_capacity,
                                                datum_type,
+                                               useAllocator,
                                                &param_iid, &err))
                 {
                     // XXX need exception scheme for arrays to indicate bad element
                     ThrowBadParam(err, i, mCallContext);
                     return JS_FALSE;
                 }
             }
             else // if(isSizedString)
             {
                 if(!XPCConvert::JSStringWithSize2Native(mCallContext,
                                                         (void*)&dp->val,
                                                         src,
                                                         array_count, array_capacity,
-                                                        datum_type, &err))
+                                                        datum_type, useAllocator,
+                                                        &err))
                 {
                     ThrowBadParam(err, i, mCallContext);
                     return JS_FALSE;
                 }
             }
         }
         else
         {
             if(!XPCConvert::JSData2Native(mCallContext, &dp->val, src, type,
-                                          JS_TRUE, &param_iid, &err))
+                                          useAllocator, &param_iid,
+                                          &err))
             {
                 ThrowBadParam(err, i, mCallContext);
                 return JS_FALSE;
             }
         }
     }
 
     return JS_TRUE;
 }
 
-// Performs all necessary teardown on a parameter after method invocation.
-//
-// This method should only be called if the value in question was flagged
-// for cleanup (ie, if dp->DoesValNeedCleanup()).
-void
-CallMethodHelper::CleanupParam(nsXPTCMiniVariant& param, nsXPTType& type)
-{
-    // We handle array elements, but not the arrays themselves.
-    NS_ABORT_IF_FALSE(type.TagPart() != nsXPTType::T_ARRAY, "Can't handle arrays.");
-
-    // Pointers may sometimes be null even if cleanup was requested. Combine
-    // the null checking for all the different types into one check here.
-    if (type.TagPart() != nsXPTType::T_JSVAL && param.val.p == nsnull)
-        return;
-
-    switch(type.TagPart())
-    {
-        case nsXPTType::T_JSVAL:
-            JS_RemoveValueRoot(mCallContext, (jsval*)&param.val);
-            break;
-        case nsXPTType::T_INTERFACE:
-        case nsXPTType::T_INTERFACE_IS:
-            ((nsISupports*)param.val.p)->Release();
-            break;
-        case nsXPTType::T_ASTRING:
-        case nsXPTType::T_DOMSTRING:
-            mCallContext.DeleteString((nsAString*)param.val.p);
-            break;
-        case nsXPTType::T_UTF8STRING:
-        case nsXPTType::T_CSTRING:
-            delete (nsCString*) param.val.p;
-            break;
-        default:
-            NS_ABORT_IF_FALSE(type.IsPointer(), "Cleanup requested on unexpected type.");
-            nsMemory::Free(param.val.p);
-            break;
-    }
-}
-
-// Handle parameters with dipper types.
-//
-// Dipper types are one of the more inscrutable aspects of xpidl. In a
-// nutshell, dippers are empty container objects, created and passed by
-// the caller, and filled by the callee. The callee receives a
-// fully-formed object, and thus does not have to construct anything. But
-// the object is functionally empty, and the callee is responsible for
-// putting something useful inside of it.
-//
-// XPIDL decides which types to make dippers. The list of these types
-// is given in the isDipperType() function in typelib.py, and is currently
-// limited to 4 string types.
-//
-// When a dipper type is declared as an 'out' parameter, xpidl internally
-// converts it to an 'in', and sets the XPT_PD_DIPPER flag on it. For this
-// reason, dipper types are sometimes referred to as 'out parameters
-// masquerading as in'. The burden of maintaining this illusion falls mostly
-// on XPConnect - we create the empty containers, and harvest the results
-// after the call.
-//
-// This method creates these empty containers.
-JSBool
-CallMethodHelper::HandleDipperParam(nsXPTCVariant* dp,
-                                    const nsXPTParamInfo& paramInfo)
-{
-    // Get something we can make comparisons with.
-    uint8 type_tag = paramInfo.GetType().TagPart();
-
-    // Dippers always have the 'in' and 'dipper' flags set. Never 'out'.
-    NS_ABORT_IF_FALSE(!paramInfo.IsOut(), "Dipper has unexpected flags.");
-
-    // xpidl.h specifies that dipper types will be used in exactly four
-    // cases, all strings. Verify that here.
-    NS_ABORT_IF_FALSE(type_tag == nsXPTType::T_ASTRING ||
-                      type_tag == nsXPTType::T_DOMSTRING ||
-                      type_tag == nsXPTType::T_UTF8STRING ||
-                      type_tag == nsXPTType::T_CSTRING,
-                      "Unexpected dipper type!");
-
-    // ASTRING and DOMSTRING are very similar, and both use nsAutoString.
-    // UTF8_STRING and CSTRING are also quite similar, and both use nsCString.
-    if(type_tag == nsXPTType::T_ASTRING || type_tag == nsXPTType::T_DOMSTRING)
-        dp->val.p = new nsAutoString();
-    else
-        dp->val.p = new nsCString();
-
-    // Check for OOM, in either case.
-    if(!dp->val.p)
-    {
-        JS_ReportOutOfMemory(mCallContext);
-        return JS_FALSE;
-    }
-
-    // We allocated, so we need to deallocate after the method call completes.
-    dp->SetValNeedsCleanup();
-
-    return JS_TRUE;
-}
-
 nsresult
 CallMethodHelper::Invoke()
 {
     PRUint32 argc = mDispatchParams.Length();
     nsXPTCVariant* argv = mDispatchParams.Elements();
 
     if(XPCPerThreadData::IsMainThread(mCallContext))
         return NS_InvokeByIndex(mCallee, mVTableIndex, argc, argv);
--- a/js/src/xpconnect/tests/Makefile.in
+++ b/js/src/xpconnect/tests/Makefile.in
@@ -31,28 +31,40 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH = ../../../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
+DEPTH		= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
 relativesrcdir = js/src/xpconnect/tests
 
 include $(DEPTH)/config/autoconf.mk
 
-DIRS = idl mochitest chrome components/native components/js
+MODULE		= TestXPC
+SIMPLE_PROGRAMS = TestXPC$(BIN_SUFFIX)
+
+
+DIRS		= idl mochitest chrome
+
+# XXX Doesn't work in libxul builds.
+#DIRS += components
+#
 
 XPCSHELL_TESTS = unit
 
-LIBS = \
-  $(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
-  $(LIBS_DIR) \
-  $(MOZ_JS_LIBS) \
-  $(MOZ_COMPONENT_LIBS) \
-  $(NULL)
+CPPSRCS		= TestXPC.cpp
+
+LIBS		= \
+		$(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
+		$(LIBS_DIR) \
+		$(MOZ_JS_LIBS) \
+		$(MOZ_COMPONENT_LIBS) \
+		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
+
+DEFINES		+= -DJS_THREADSAFE -DJSFILE
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/TestXPC.cpp
@@ -0,0 +1,867 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   IBM Corp.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* API tests for XPConnect - use xpcshell for JS tests. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#include "jsapi.h"
+#include "jscntxt.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIXPConnect.h"
+#include "nsIScriptError.h"
+#include "nsIServiceManager.h"
+#include "nsIComponentManager.h"
+#include "nsIComponentRegistrar.h"
+#include "nsIJSContextStack.h"
+#include "nsIJSRuntimeService.h"
+#include "nsMemory.h"
+#include "nsIXPCSecurityManager.h"
+#include "nsICategoryManager.h"
+#include "nsIVariant.h"
+#include "nsStringAPI.h"
+#include "nsEmbedString.h"
+
+#include "xpctest.h"
+
+/***************************************************************************/
+// host support for jsengine
+
+FILE *gOutFile = NULL;
+FILE *gErrFile = NULL;
+
+static JSBool
+Print(JSContext *cx, uintN argc, jsval *vp)
+{
+    uintN i, n;
+    JSString *str;
+
+    jsval *argv = JS_ARGV(cx, vp);
+    for (i = n = 0; i < argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
+        if (!str)
+            return false;
+        JSAutoByteString bytes(cx, str);
+        if (!bytes)
+            return false;
+        fprintf(gOutFile, "%s%s", i ? " " : "", bytes.ptr());
+    }
+    n++;
+    if (n)
+        fputc('\n', gOutFile);
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return true;
+}
+
+static JSBool
+Load(JSContext *cx, uintN argc, jsval *vp)
+{
+    uintN i;
+    JSString *str;
+    jsval result;
+
+    JSObject *obj = JS_THIS_OBJECT(cx, vp);
+    if (!obj)
+        return JS_FALSE;
+
+    jsval *argv = JS_ARGV(cx, vp);
+    for (i = 0; i < argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
+        if (!str)
+            return JS_FALSE;
+        argv[i] = STRING_TO_JSVAL(str);
+        JSAutoByteString filename(cx, str);
+        if (!filename)
+            return false;
+        JSScript *script = JS_CompileFile(cx, obj, filename.ptr());
+        if (!script || !JS_ExecuteScript(cx, obj, script, &result))
+            return false;
+    }
+    JS_SET_RVAL(cx, vp, JSVAL_VOID);
+    return JS_TRUE;
+}
+
+static JSFunctionSpec glob_functions[] = {
+    {"print",           Print,          0,0},
+    {"load",            Load,           1,0},
+    {nsnull,nsnull,0,0}
+};
+
+static JSClass global_class = {
+    "global", JSCLASS_GLOBAL_FLAGS,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_StrictPropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   nsnull
+};
+
+static void
+my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
+{
+    fputs(message, stdout);
+}
+
+/***************************************************************************/
+// Foo class for used with some of the tests
+
+class nsTestXPCFoo : public nsITestXPCFoo2
+{
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSITESTXPCFOO
+
+    nsTestXPCFoo();
+    virtual ~nsTestXPCFoo();
+    char* mFoo;
+};
+
+NS_IMETHODIMP nsTestXPCFoo::Test(int p1, int p2, int* retval)
+{
+//    printf("nsTestXPCFoo::Test called with p1 = %d and p2 = %d\n", p1, p2);
+    *retval = p1+p2;
+    return NS_OK;
+}
+NS_IMETHODIMP nsTestXPCFoo::Test2()
+{
+//    printf("nsTestXPCFoo::Test2 called ");
+    return NS_OK;
+}
+
+NS_IMETHODIMP nsTestXPCFoo::GetFoo(char * *aFoo)
+{
+//    printf("nsTestXPCFoo::Get called ");
+    if(!aFoo)
+        return NS_ERROR_NULL_POINTER;
+    if(mFoo)
+        *aFoo = (char*) nsMemory::Clone(mFoo, strlen(mFoo)+1);
+    else
+        *aFoo = NULL;
+    return NS_OK;
+}
+
+NS_IMETHODIMP nsTestXPCFoo::SetFoo(const char * aFoo)
+{
+//    printf("nsTestXPCFoo::Set called ");
+    if(mFoo)
+    {
+        nsMemory::Free(mFoo);
+        mFoo = NULL;
+    }
+    if(aFoo)
+        mFoo = (char*) nsMemory::Clone(aFoo, strlen(aFoo)+1);
+    return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS2(nsTestXPCFoo, nsITestXPCFoo, nsITestXPCFoo2)
+
+nsTestXPCFoo::nsTestXPCFoo()
+    : mFoo(NULL)
+{
+    NS_ADDREF_THIS();
+}
+
+nsTestXPCFoo::~nsTestXPCFoo()
+{
+    if(mFoo)
+        nsMemory::Free(mFoo);
+}
+
+/***************************************************************************/
+// test for nsIXPCSecurityManager
+
+class MySecMan : public nsIXPCSecurityManager
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIXPCSECURITYMANAGER
+
+  enum Mode { OK_ALL    ,
+              VETO_ALL
+            };
+
+  void SetMode(Mode mode) {mMode = mode;}
+
+  MySecMan();
+
+private:
+  Mode mMode;
+};
+
+NS_IMPL_ISUPPORTS1(MySecMan, nsIXPCSecurityManager)
+
+MySecMan::MySecMan()
+    : mMode(OK_ALL)
+{
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP
+MySecMan::CanCreateWrapper(JSContext * aJSContext, const nsIID & aIID, nsISupports *aObj, nsIClassInfo *aClassInfo, void * *aPolicy)
+{
+    switch(mMode)
+    {
+        case OK_ALL:
+            return NS_OK;
+        case VETO_ALL:
+            JS_SetPendingException(aJSContext,
+                STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
+                    "security exception")));
+            return NS_ERROR_FAILURE;
+        default:
+            NS_ERROR("bad case");
+            return NS_OK;
+    }
+}
+
+NS_IMETHODIMP
+MySecMan::CanCreateInstance(JSContext * aJSContext, const nsCID & aCID)
+{
+    switch(mMode)
+    {
+        case OK_ALL:
+            return NS_OK;
+        case VETO_ALL:
+            JS_SetPendingException(aJSContext,
+                STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
+                    "security exception")));
+            return NS_ERROR_FAILURE;
+        default:
+            NS_ERROR("bad case");
+            return NS_OK;
+    }
+}
+
+NS_IMETHODIMP
+MySecMan::CanGetService(JSContext * aJSContext, const nsCID & aCID)
+{
+    switch(mMode)
+    {
+        case OK_ALL:
+            return NS_OK;
+        case VETO_ALL:
+            JS_SetPendingException(aJSContext,
+                STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
+                    "security exception")));
+            return NS_ERROR_FAILURE;
+        default:
+            NS_ERROR("bad case");
+            return NS_OK;
+    }
+}
+
+/* void CanAccess (in PRUint32 aAction, in nsIXPCNativeCallContext aCallContext, in JSContextPtr aJSContext, in JSObjectPtr aJSObject, in nsISupports aObj, in nsIClassInfo aClassInfo, in jsid aName, inout voidPtr aPolicy); */
+NS_IMETHODIMP 
+MySecMan::CanAccess(PRUint32 aAction, nsAXPCNativeCallContext *aCallContext, JSContext * aJSContext, JSObject * aJSObject, nsISupports *aObj, nsIClassInfo *aClassInfo, jsid aName, void * *aPolicy)
+{
+    switch(mMode)
+    {
+        case OK_ALL:
+            return NS_OK;
+        case VETO_ALL:
+            JS_SetPendingException(aJSContext,
+                STRING_TO_JSVAL(JS_NewStringCopyZ(aJSContext,
+                    "security exception")));
+            return NS_ERROR_FAILURE;
+        default:
+            NS_ERROR("bad case");
+            return NS_OK;
+    }
+}
+
+/**********************************************/
+static void
+EvaluateScript(JSContext* jscontext, JSObject* glob, MySecMan* sm, MySecMan::Mode mode, const char* msg, const char* t, jsval &rval)
+{
+    sm->SetMode(mode);
+    fputs(msg, stdout);
+    JSAutoRequest ar(jscontext);
+    JS_EvaluateScript(jscontext, glob, t, strlen(t), "builtin", 1, &rval);
+}
+
+static void
+TestSecurityManager(JSContext* jscontext, JSObject* glob, nsIXPConnect* xpc)
+{
+    jsval rval;
+    JSBool success = JS_TRUE;
+    MySecMan* sm = new MySecMan();
+    nsTestXPCFoo* foo = new nsTestXPCFoo();
+
+    if(!sm || ! foo)
+    {
+        success = JS_FALSE;
+        printf("FAILED to create object!\n");
+        goto sm_test_done;
+    }
+
+    rval = JSVAL_FALSE;
+    {
+        JSAutoRequest ar(jscontext);
+        JS_SetProperty(jscontext, glob, "failed", &rval);
+    }
+    printf("Individual SecurityManager tests...\n");
+    if(NS_FAILED(xpc->SetSecurityManagerForJSContext(jscontext, sm,
+                                        nsIXPCSecurityManager::HOOK_ALL)))
+    {
+        success = JS_FALSE;
+        printf("SetSecurityManagerForJSContext FAILED!\n");
+        goto sm_test_done;
+    }
+
+    printf("  build wrapper with veto: TEST NOT RUN\n");
+/*
+    // This test is broken because xpconnect now detects that this is a
+    // call from native code and lets it succeed without calling the security manager
+
+    sm->SetMode(MySecMan::VETO_ALL);
+    printf("  build wrapper with veto: ");
+    if(NS_SUCCEEDED(xpc->WrapNative(jscontext, glob, foo, NS_GET_IID(nsITestXPCFoo2), &wrapper)))
+    {
+        success = JS_FALSE;
+        printf("FAILED\n");
+        NS_RELEASE(wrapper);
+    }
+    else
+    {
+        printf("passed\n");
+    }
+*/
+    sm->SetMode(MySecMan::OK_ALL);
+    printf("  build wrapper no veto: ");
+    nsIXPConnectJSObjectHolder* holder;
+    if(NS_SUCCEEDED(xpc->WrapNative(jscontext, glob, foo, 
+                    NS_GET_IID(nsITestXPCFoo2), &holder)))
+    {
+        printf("passed\n");
+        JSObject* obj;
+        if(NS_SUCCEEDED(holder->GetJSObject(&obj)))
+        {
+            rval = OBJECT_TO_JSVAL(obj);
+            JSAutoRequest ar(jscontext);
+            JS_SetProperty(jscontext, glob, "foo", &rval);
+        }
+            
+        NS_RELEASE(holder);
+    }
+    else
+    {
+        success = JS_FALSE;
+        printf("FAILED\n");
+    }
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::OK_ALL,
+                   "  getService no veto: ",
+                   "try{Components.classes['@mozilla.org/js/xpc/XPConnect;1'].getService(); print('passed');}catch(e){failed = true; print('FAILED');}",
+                   rval);
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::VETO_ALL,
+                   "  getService with veto: ",
+                   "try{Components.classes['@mozilla.org/js/xpc/XPConnect;1'].getService(); failed = true; print('FAILED');}catch(e){print('passed');}",
+                   rval);
+
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::OK_ALL,
+                   "  createInstance no veto: ",
+                   "try{Components.classes['@mozilla.org/js/xpc/ID;1'].createInstance(Components.interfaces.nsIJSID); print('passed');}catch(e){failed = true; print('FAILED');}",
+                   rval);
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::VETO_ALL,
+                   "  getService with veto: ",
+                   "try{Components.classes['@mozilla.org/js/xpc/ID;1'].createInstance(Components.interfaces.nsIJSID); failed = true; print('FAILED');}catch(e){print('passed');}",
+                   rval);
+
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::OK_ALL,
+                   "  call method no veto: ",
+                   "try{foo.Test2(); print(' : passed');}catch(e){failed = true; print(' : FAILED');}",
+                   rval);
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::VETO_ALL,
+                   "  call method with veto: ",
+                   "try{foo.Test2(); failed = true; print(' : FAILED');}catch(e){print(' : passed');}",
+                   rval);
+
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::OK_ALL,
+                   "  get attribute no veto: ",
+                   "try{foo.Foo; print(' : passed');}catch(e){failed = true; print(' : FAILED');}",
+                   rval);
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::VETO_ALL,
+                   "  get attribute with veto: ",
+                   "try{foo.Foo; failed = true; print(' : FAILED');}catch(e){print(' : passed');}",
+                   rval);
+
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::OK_ALL,
+                   "  set attribute no veto: ",
+                   "try{foo.Foo = 0; print(' : passed');}catch(e){failed = true; print(' : FAILED');}",
+                   rval);
+
+    EvaluateScript(jscontext, glob, sm, MySecMan::VETO_ALL,
+                   "  set attribute with veto: ",
+                   "try{foo.Foo = 0; failed = true; print(' : FAILED');}catch(e){print(' : passed');}",
+                   rval);
+
+sm_test_done:
+    {
+        JSAutoRequest ar(jscontext);
+        success = success && JS_GetProperty(jscontext, glob, "failed", &rval) && JSVAL_TRUE != rval;
+    }
+    printf("SecurityManager tests : %s\n", success ? "passed" : "FAILED");
+    NS_IF_RELEASE(foo);
+    xpc->SetSecurityManagerForJSContext(jscontext, nsnull, 0);
+}
+
+
+/***************************************************************************/
+// arg formatter test...
+
+// A bit of history: JS_PushArguments/JS_PushArgumentsVA used to be part of the
+// JS public (friend, really) API using js_AllocStack to obtain the rooted
+// output array. js_AllocStack was removed and, to preserve the ability to test
+// JS_ConvertArguments, these functions were moved here and hacked down to
+// size.
+
+#ifdef HAVE_VA_LIST_AS_ARRAY
+#define JS_ADDRESSOF_VA_LIST(ap) ((va_list *)(ap))
+#else
+#define JS_ADDRESSOF_VA_LIST(ap) (&(ap))
+#endif
+
+static JSBool
+TryArgumentFormatter(JSContext *cx, const char **formatp, JSBool fromJS,
+                     jsval **vpp, va_list *app)
+{
+    const char *format;
+    JSArgumentFormatMap *map;
+
+    format = *formatp;
+    for (map = cx->argumentFormatMap; map; map = map->next) {
+        if (!strncmp(format, map->format, map->length)) {
+            *formatp = format + map->length;
+            return map->formatter(cx, format, fromJS, vpp, app);
+        }
+    }
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_CHAR, format);
+    return JS_FALSE;
+}
+
+static bool
+PushArgumentsVA(JSContext *cx, uintN argc, jsval *argv, const char *format, va_list ap)
+{
+    char c;
+    JSString *str;
+
+    jsval *sp = argv;
+
+    while ((c = *format++) != '\0') {
+        if (isspace(c) || c == '*')
+            continue;
+        switch (c) {
+          case 's':
+            str = JS_NewStringCopyZ(cx, va_arg(ap, char *));
+            if (!str)
+                return false;
+            *sp = STRING_TO_JSVAL(str);
+            break;
+          default:
+            format--;
+            if (!TryArgumentFormatter(cx, &format, JS_FALSE, &sp, JS_ADDRESSOF_VA_LIST(ap)))
+                return false;
+            /* NB: the formatter already updated sp, so we continue here. */
+            continue;
+        }
+        sp++;
+    }
+
+    return true;
+}
+
+static bool
+PushArguments(JSContext *cx, uintN argc, jsval *argv, const char *format, ...)
+{
+    va_list ap;
+    va_start(ap, format);
+    bool ret = PushArgumentsVA(cx, argc, argv, format, ap);
+    va_end(ap);
+    return ret;
+}
+
+#define TAF_CHECK(cond, msg) \
+    if (!cond) {       \
+        printf(msg);   \
+        ok = JS_FALSE; \
+        break;         \
+    }
+
+static void
+TestArgFormatter(JSContext* jscontext, JSObject* glob, nsIXPConnect* xpc)
+{
+    JSBool ok = JS_TRUE;
+
+    const char*                  a_in = "some string";
+    nsCOMPtr<nsITestXPCFoo>      b_in = new nsTestXPCFoo();
+    nsCOMPtr<nsIWritableVariant> c_in = do_CreateInstance("@mozilla.org/variant;1"); 
+    static NS_NAMED_LITERAL_STRING(d_in, "foo bar");
+    const char*                  e_in = "another meaningless chunck of text";
+    
+
+    JSBool                  a_match;
+    nsCOMPtr<nsISupports>   b_out;
+    nsCOMPtr<nsIVariant>    c_out;
+    nsAutoString            d_out;
+    JSBool                  e_match;
+
+    nsCOMPtr<nsITestXPCFoo> specified;
+    PRInt32                 val;
+
+    printf("ArgumentFormatter test: ");
+
+    if(!b_in || !c_in || NS_FAILED(c_in->SetAsInt32(5)))
+    {
+        printf(" failed to construct test objects -- FAILED!\n");
+        return;
+    }
+
+    do {
+        JSAutoRequest ar(jscontext);
+
+        // Prepare an array of arguments for JS_ConvertArguments
+        jsval argv[5];
+        js::AutoArrayRooter tvr(jscontext, JS_ARRAY_LENGTH(argv), argv);
+
+        if (!PushArguments(jscontext, 5, argv,
+                           "s %ip %iv %is s",
+                           a_in,
+                           &NS_GET_IID(nsITestXPCFoo2), b_in.get(),
+                           c_in.get(),
+                           static_cast<const nsAString*>(&d_in),
+                           e_in))
+        {
+            printf(" could not convert from native to JS -- FAILED!\n");
+            return;
+        }
+
+        JSString *a_out, *e_out;
+        ok = JS_ConvertArguments(jscontext, 5, argv, "S %ip %iv %is S",
+                                &a_out, 
+                                static_cast<nsISupports**>(getter_AddRefs(b_out)), 
+                                static_cast<nsIVariant**>(getter_AddRefs(c_out)),
+                                static_cast<nsAString*>(&d_out), 
+                                 &e_out);
+        TAF_CHECK(ok, " could not convert from JS to native -- FAILED!\n");
+        TAF_CHECK(b_out, " JS to native for %%ip returned NULL -- FAILED!\n");
+    
+        specified = do_QueryInterface(b_out);
+        TAF_CHECK(specified, " could not QI value JS to native returned -- FAILED!\n");
+        ok = specified.get() == b_in.get();
+        TAF_CHECK(ok, " JS to native returned wrong value -- FAILED!\n");
+        TAF_CHECK(c_out, " JS to native for %%iv returned NULL -- FAILED!\n");
+        TAF_CHECK(NS_SUCCEEDED(c_out->GetAsInt32(&val)) && val == 5, " JS to native for %%iv holds wrong value -- FAILED!\n");
+        TAF_CHECK(d_in.Equals(d_out), " JS to native for %%is returned the wrong value -- FAILED!\n");
+        TAF_CHECK(JS_StringEqualsAscii(jscontext, a_out, a_in, &a_match), " oom -- FAILED!\n");
+        TAF_CHECK(JS_StringEqualsAscii(jscontext, e_out, e_in, &e_match), " oom -- FAILED!\n");
+    } while (0);
+    if (!ok)
+        return;
+
+    if(a_match && e_match)
+        printf("passed\n");
+    else
+        printf(" conversion OK, but surrounding was mangled -- FAILED!\n");
+}
+
+/***************************************************************************/
+// ThreadJSContextStack test
+
+static void
+TestThreadJSContextStack(JSContext* jscontext)
+{
+
+    printf("ThreadJSContextStack tests...\n");
+
+    nsresult rv;
+    nsCOMPtr<nsIJSContextStack> stack = 
+             do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
+
+    if(NS_SUCCEEDED(rv))
+    {
+        PRInt32 count;
+        PRInt32 base_count;
+
+        if(NS_SUCCEEDED(stack->GetCount(&base_count)))
+            printf("\tstack->GetCount() : passed\n");
+        else
+            printf("\tstack->GetCount() FAILED!\n");
+
+        if(NS_FAILED(stack->Push(jscontext)))
+            printf("\tstack->Push() FAILED!\n");
+        else
+            printf("\tstack->Push() passed\n");
+
+        if(NS_SUCCEEDED(stack->GetCount(&count)))
+            printf("\tstack->GetCount() : %s\n",
+                    count == base_count+1 ? "passed" : "FAILED!");
+        else
+            printf("\tstack->GetCount() FAILED!\n");
+
+        JSContext* testCX;
+        if(NS_FAILED(stack->Peek(&testCX)))
+            printf("\tstack->Peek() FAILED!\n");
+
+        if(jscontext == testCX)
+            printf("\tstack->Push/Peek : passed\n");
+        else
+            printf("\tstack->Push/Peek : FAILED\n");
+
+        if(NS_FAILED(stack->Pop(&testCX)))
+            printf("\tstack->Pop() FAILED!\n");
+
+        if(jscontext == testCX)
+            printf("\tstack->Push/Pop : passed\n");
+        else
+            printf("\tstack->Push/Pop : FAILED\n");
+
+        if(NS_SUCCEEDED(stack->GetCount(&count)))
+            printf("\tstack->GetCount() : %s\n",
+                    count == base_count ? "passed" : "FAILED!");
+        else
+            printf("\tstack->GetCount() FAILED!\n");
+    }
+    else
+        printf("\tFAILED to get nsThreadJSContextStack service!\n");
+}
+
+/***************************************************************************/
+
+static void ShowXPCException()
+{
+    nsresult rv;
+    nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
+    if(NS_SUCCEEDED(rv) && xpc)
+    {
+        nsCOMPtr<nsIException> e;
+        xpc->GetPendingException(getter_AddRefs(e));
+        if(e)
+        {
+            char* str;
+            rv = e->ToString(&str);
+            if(NS_SUCCEEDED(rv) && str)
+            {
+                printf("%s\n", str);
+                nsMemory::Free(str);
+
+                nsresult res;
+                e->GetResult(&res);
+                if(res == NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS)
+                {
+                    nsCOMPtr<nsISupports> data;
+                    e->GetData(getter_AddRefs(data));
+                    if(data)
+                    {
+                        nsCOMPtr<nsIScriptError> report = do_QueryInterface(data);
+                        if(report)
+                        {
+                            nsCAutoString str2;
+                            rv = report->ToString(str2);
+                            if(NS_SUCCEEDED(rv))
+                            {
+                                printf("%s\n", str2.get());
+                            }                            
+                        }                            
+                    }                            
+                    else        
+                        printf("can't get data for pending XPC exception\n");    
+                }
+            }
+            else        
+                printf("can't get string for pending XPC exception\n");    
+        }
+        else        
+            printf("no pending XPC exception\n");    
+    }
+    else
+        printf("can't get xpconnect\n");    
+}
+
+static void TestCategoryManmager()
+{
+    printf("\n");    
+
+    nsresult rv;
+    nsCOMPtr<nsICategoryManager> catman = 
+             do_GetService("@mozilla.org/categorymanager;1", &rv);
+    if(NS_SUCCEEDED(rv) && catman)
+    {
+        printf("got category manager\n");    
+ 
+        nsCOMPtr<nsISimpleEnumerator> e;
+        rv = catman->EnumerateCategory("foo", getter_AddRefs(e));
+        if(NS_SUCCEEDED(rv) && e)
+        {
+            printf("got enumerator\n");
+
+            nsCOMPtr<nsISupports> el;
+            rv = e->GetNext(getter_AddRefs(el));
+            if(NS_SUCCEEDED(rv) && el)
+            {
+                printf("e.GetNext() succeeded\n");
+            }
+            else
+            {
+                printf("e.GetNext() FAILED with result %0x\n", (int)rv);        
+                ShowXPCException();
+            }
+                        
+        }
+        else
+            printf("get of enumerator FAILED with result %0x\n", (int)rv);        
+    }
+    else
+        printf("!!! can't get category manager\n");    
+
+
+    printf("\n");    
+}
+
+
+/***************************************************************************/
+/***************************************************************************/
+// our main...
+
+#define DIE(_msg) \
+    PR_BEGIN_MACRO  \
+        printf(_msg); \
+        printf("\n"); \
+        return 1; \
+    PR_END_MACRO
+
+int main()
+{
+    JSRuntime *rt;
+    JSContext *jscontext;
+    JSObject *glob;
+    nsresult rv;
+
+    gErrFile = stderr;
+    gOutFile = stdout;
+    {
+        nsCOMPtr<nsIServiceManager> servMan;
+        NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
+    
+        // get the JSRuntime from the runtime svc, if possible
+        nsCOMPtr<nsIJSRuntimeService> rtsvc =
+                 do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv);
+        if(NS_FAILED(rv) || NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt)
+            DIE("FAILED to get a JSRuntime");
+
+        jscontext = JS_NewContext(rt, 8192);
+        if(!jscontext)
+            DIE("FAILED to create a JSContext");
+
+        JS_SetErrorReporter(jscontext, my_ErrorReporter);
+
+        nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
+        if(!xpc)
+            DIE("FAILED to get xpconnect service\n");
+
+        nsCOMPtr<nsIJSContextStack> cxstack =
+                 do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
+        if(NS_FAILED(rv))
+            DIE("FAILED to get the nsThreadJSContextStack service!\n");
+
+        if(NS_FAILED(cxstack->Push(jscontext)))
+            DIE("FAILED to push the current jscontext on the nsThreadJSContextStack service!\n");
+
+        // XXX I'd like to replace this with code that uses a wrapped xpcom object
+        // as the global object. The old TextXPC did this. The support for this
+        // is not working now in the new xpconnect code.
+
+        {
+            JSAutoRequest ar(jscontext);
+            glob = JS_NewCompartmentAndGlobalObject(jscontext, &global_class, NULL);
+            if (!glob)
+                DIE("FAILED to create global object");
+
+            JSAutoEnterCompartment ac;
+            if (!ac.enter(jscontext, glob))
+                DIE("FAILED to enter compartment");
+
+            if (!JS_InitStandardClasses(jscontext, glob))
+                DIE("FAILED to init standard classes");
+            if (!JS_DefineFunctions(jscontext, glob, glob_functions))
+                DIE("FAILED to define global functions");
+            if (NS_FAILED(xpc->InitClasses(jscontext, glob)))
+                DIE("FAILED to init xpconnect classes");
+        }
+
+        /**********************************************/
+        // run the tests...
+
+        TestCategoryManmager();
+        TestSecurityManager(jscontext, glob, xpc);
+        TestArgFormatter(jscontext, glob, xpc);
+        TestThreadJSContextStack(jscontext);
+
+        /**********************************************/
+
+        if(NS_FAILED(cxstack->Pop(nsnull)))
+            DIE("FAILED to pop the current jscontext from the nsThreadJSContextStack service!\n");
+
+        {
+            JSAutoRequest ar(jscontext);
+            JS_ClearScope(jscontext, glob);
+            JS_GC(jscontext);
+            JS_GC(jscontext);
+        }
+        JS_DestroyContext(jscontext);
+        xpc->DebugDump(4);
+
+        cxstack = nsnull;   // release service held by nsCOMPtr
+        xpc     = nsnull;   // release service held by nsCOMPtr
+        rtsvc   = nsnull;   // release service held by nsCOMPtr
+    }
+    rv = NS_ShutdownXPCOM( NULL );
+    NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM FAILED");
+
+    return 0;
+}
+
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/Makefile.in
@@ -0,0 +1,79 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Communicator client code, released
+# March 31, 1998.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   John Bandhauer <jband@netscape.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= xpctest
+LIBRARY_NAME	= xpctest
+EXPORT_LIBRARY = 1
+IS_COMPONENT	= 1
+MODULE_NAME	= xpconnect_test
+MOZILLA_INTERNAL_API = 1
+
+
+CPPSRCS		= \
+		xpctest_array.cpp \
+		xpctest_echo.cpp \
+		xpctest_child.cpp \
+		xpctest_noisy.cpp \
+		xpctest_overloaded.cpp \
+		xpctest_string.cpp \
+		xpctest_module.cpp \
+		xpctest_attributes.cpp \
+		xpctest_calljs.cpp \
+		xpctest_const.cpp \
+		xpctest_in.cpp \
+		xpctest_inout.cpp \
+		xpctest_multiple.cpp \
+		xpctest_out.cpp \
+		xpctest_domstring.cpp \
+		xpctest_variant.cpp \
+		$(NULL)
+
+EXTRA_DSO_LDOPTS += \
+		$(MOZ_COMPONENT_LIBS) \
+		$(MOZ_JS_LIBS) \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/js/Makefile.in
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is XPConnect Test Code.
-#
-# The Initial Developer of the Original Code is
-# Portions created by the Initial Developer are Copyright (C) 2011
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Bobby Holley <bobbyholley@gmail.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH = ../../../../../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = xpctest
-LIBRARY_NAME = xpctest
-IS_COMPONENT = 1
-MODULE_NAME = xpconnect_test
-NO_DIST_INSTALL = 1
-
-JS_FILES = \
-  xpctest_attributes.js \
-  xpctest_params.js \
-  $(NULL)
-
-include $(topsrcdir)/config/config.mk
-
-MANIFEST_FILE = xpctest.manifest
-
-include $(topsrcdir)/config/rules.mk
-
-componentdir = js/src/xpconnect/tests/components/js
-
-libs:: $(JS_FILES)
-	$(INSTALL) $^ $(testxpcobjdir)/$(componentdir)
-
-libs:: $(MANIFEST_FILE)
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $< > $(testxpcobjdir)/$(componentdir)/$(<F)
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/js/xpctest.manifest
+++ /dev/null
@@ -1,10 +0,0 @@
-component {8ff41d9c-66e9-4453-924a-7d8de0a5e966} xpctest_attributes.js
-contract @mozilla.org/js/xpc/test/js/ObjectReadWrite;1 {8ff41d9c-66e9-4453-924a-7d8de0a5e966}
-
-component {916c4247-253d-4ed0-a425-adfedf53ecc8} xpctest_attributes.js
-contract @mozilla.org/js/xpc/test/js/ObjectReadOnly;1 {916c4247-253d-4ed0-a425-adfedf53ecc8}
-
-component {e3b86f4e-49c0-487c-a2b0-3a986720a044} xpctest_params.js
-contract @mozilla.org/js/xpc/test/js/Params;1 {e3b86f4e-49c0-487c-a2b0-3a986720a044}
-
-interfaces ../xpctest.xpt
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/js/xpctest_attributes.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is XPConnect Test Code.
- *
- * The Initial Developer of the Original Code is The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Bobby Holley <bobbyholley@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-Components.utils.import("resource:///modules/XPCOMUtils.jsm");
-
-function TestObjectReadWrite() {}
-TestObjectReadWrite.prototype = {
-
-  /* Boilerplate */
-  QueryInterface: XPCOMUtils.generateQI([Components.interfaces["nsIXPCTestObjectReadWrite"]]),
-  contractID: "@mozilla.org/js/xpc/test/js/ObjectReadWrite;1",
-  classID: Components.ID("{8ff41d9c-66e9-4453-924a-7d8de0a5e966}"),
-
-  /* nsIXPCTestObjectReadWrite */
-  stringProperty: "XPConnect Read-Writable String",
-  booleanProperty: true,
-  shortProperty: 32767,
-  longProperty: 2147483647,
-  floatProperty: 5.5,
-  charProperty: "X"
-};
-
-
-function TestObjectReadOnly() {}
-TestObjectReadOnly.prototype = {
-
-  /* Boilerplate */
-  QueryInterface: XPCOMUtils.generateQI([Components.interfaces["nsIXPCTestObjectReadOnly"]]),
-  contractID: "@mozilla.org/js/xpc/test/js/ObjectReadOnly;1",
-  classID: Components.ID("{916c4247-253d-4ed0-a425-adfedf53ecc8}"),
-
-  /* nsIXPCTestObjectReadOnly */
-  strReadOnly: "XPConnect Read-Only String",
-  boolReadOnly: true,
-  shortReadOnly: 32767,
-  longReadOnly: 2147483647,
-  floatReadOnly: 5.5,
-  charReadOnly: "X"
-};
-
-
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([TestObjectReadWrite, TestObjectReadOnly]);
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/js/xpctest_params.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is XPConnect Test Code.
- *
- * The Initial Developer of the Original Code is The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Bobby Holley <bobbyholley@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-Components.utils.import("resource:///modules/XPCOMUtils.jsm");
-
-function TestParams() {
-}
-
-/* For once I'm happy that JS is weakly typed. */
-function f(a, b) {
-    var rv = b.value;
-    b.value = a;
-    return rv;
-};
-
-TestParams.prototype = {
-
-  /* Boilerplate */
-  QueryInterface: XPCOMUtils.generateQI([Components.interfaces["nsIXPCTestParams"]]),
-  contractID: "@mozilla.org/js/xpc/test/js/Params;1",
-  classID: Components.ID("{e3b86f4e-49c0-487c-a2b0-3a986720a044}"),
-
-  /* nsIXPCTestParams */
-  testBoolean: f,
-  testOctet: f,
-  testShort: f,
-  testLong: f,
-  testLongLong: f,
-  testUnsignedShort: f,
-  testUnsignedLong: f,
-  testUnsignedLongLong: f,
-  testFloat: f,
-  testDouble: f,
-  testChar: f,
-  testString: f,
-  testWchar: f,
-  testWstring: f,
-  testDOMString: f,
-  testAString: f,
-  testAUTF8String: f,
-  testACString: f,
-  testJsval: f
-};
-
-var NSGetFactory = XPCOMUtils.generateNSGetFactory([TestParams]);
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/native/Makefile.in
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is Mozilla Communicator client code, released
-# March 31, 1998.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   John Bandhauer <jband@netscape.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of the GNU General Public License Version 2 or later (the "GPL"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH = ../../../../../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = xpctest
-LIBRARY_NAME = xpctest
-IS_COMPONENT = 1
-MODULE_NAME = xpconnect_test
-NO_DIST_INSTALL = 1
-FORCE_SHARED_LIB = 1
-
-CPPSRCS = \
-  xpctest_module.cpp \
-  xpctest_attributes.cpp \
-  xpctest_params.cpp \
-  $(NULL)
-
-include $(topsrcdir)/config/config.mk
-
-MANIFEST_FILE = xpctest.manifest
-
-EXTRA_DSO_LDOPTS += \
-  $(XPCOM_GLUE_LDOPTS) \
-  $(MOZ_COMPONENT_LIBS) \
-  $(MOZ_JS_LIBS) \
-  $(NULL)
-
-include $(topsrcdir)/config/rules.mk
-
-
-DEFINES += -DLIBRARY_FILENAME="$(SHARED_LIBRARY)"
-
-componentdir = js/src/xpconnect/tests/components/native
-
-libs:: $(SHARED_LIBRARY)
-	$(INSTALL) $^ $(testxpcobjdir)/$(componentdir)
-
-libs:: $(MANIFEST_FILE)
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $< > $(testxpcobjdir)/$(componentdir)/$(<F)
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/native/xpctest.manifest
+++ /dev/null
@@ -1,3 +0,0 @@
-#filter substitution
-binary-component @LIBRARY_FILENAME@
-interfaces ../xpctest.xpt
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/native/xpctest_attributes.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   John Bandhauer <jband@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "xpctest_private.h"
-
-NS_IMPL_ISUPPORTS1(xpcTestObjectReadOnly, nsIXPCTestObjectReadOnly)
-
-xpcTestObjectReadOnly :: xpcTestObjectReadOnly() {
-    boolProperty = PR_TRUE;
-    shortProperty = 32767;
-    longProperty =  2147483647;
-    floatProperty = 5.5f;
-    charProperty = 'X';
-}
-
-NS_IMETHODIMP xpcTestObjectReadOnly :: GetStrReadOnly(char * *aStrReadOnly){
-    char aString[] = "XPConnect Read-Only String";
-
-    if(!aStrReadOnly)
-        return NS_ERROR_NULL_POINTER;
-    *aStrReadOnly = (char*) nsMemory::Clone(aString,
-                                            sizeof(char)*(strlen(aString)+1));
-    return *aStrReadOnly ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
-}
-
-NS_IMETHODIMP xpcTestObjectReadOnly :: GetBoolReadOnly(PRBool *aBoolReadOnly) {
-    *aBoolReadOnly = boolProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadOnly :: GetShortReadOnly(PRInt16 *aShortReadOnly){
-    *aShortReadOnly = shortProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadOnly :: GetLongReadOnly(PRInt32 *aLongReadOnly){
-    *aLongReadOnly = longProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadOnly :: GetFloatReadOnly(float *aFloatReadOnly){
-    *aFloatReadOnly = floatProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadOnly :: GetCharReadOnly(char *aCharReadOnly){
-    *aCharReadOnly = charProperty;
-    return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS1(xpcTestObjectReadWrite, nsIXPCTestObjectReadWrite)
-
-xpcTestObjectReadWrite :: xpcTestObjectReadWrite() {
-    const char s[] = "XPConnect Read-Writable String";
-    stringProperty = (char*) nsMemory::Clone(s, sizeof(char)*(strlen(s)+1));
-    boolProperty = PR_TRUE;
-    shortProperty = 32767;
-    longProperty =  2147483647;
-    floatProperty = 5.5f;
-    charProperty = 'X';
-}
-
-xpcTestObjectReadWrite :: ~xpcTestObjectReadWrite()
-{
-    nsMemory::Free(stringProperty);
-}
-
-NS_IMETHODIMP xpcTestObjectReadWrite :: GetStringProperty(char * *aStringProperty) {
-    if(!aStringProperty)
-        return NS_ERROR_NULL_POINTER;
-    *aStringProperty = (char*) nsMemory::Clone(stringProperty, 
-                                               sizeof(char)*(strlen(stringProperty)+1));
-    return *aStringProperty ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
-
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: SetStringProperty(const char * aStringProperty) {
-    nsMemory::Free(stringProperty);
-    stringProperty = (char*) nsMemory::Clone(aStringProperty,
-                                             sizeof(char)*(strlen(aStringProperty)+1));
-    return NS_OK;
-}
-
-NS_IMETHODIMP xpcTestObjectReadWrite :: GetBooleanProperty(PRBool *aBooleanProperty) {
-    *aBooleanProperty = boolProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: SetBooleanProperty(PRBool aBooleanProperty) {
-    NS_ENSURE_TRUE(aBooleanProperty == PR_TRUE || aBooleanProperty == PR_FALSE,
-                   NS_ERROR_INVALID_ARG);
-    boolProperty = aBooleanProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: GetShortProperty(PRInt16 *aShortProperty) {
-    *aShortProperty = shortProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: SetShortProperty(PRInt16 aShortProperty) {
-    shortProperty = aShortProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: GetLongProperty(PRInt32 *aLongProperty) {
-    *aLongProperty = longProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: SetLongProperty(PRInt32 aLongProperty) {
-    longProperty = aLongProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: GetFloatProperty(float *aFloatProperty) {
-    *aFloatProperty = floatProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: SetFloatProperty(float aFloatProperty) {
-    floatProperty = aFloatProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: GetCharProperty(char *aCharProperty) {
-    *aCharProperty = charProperty;
-    return NS_OK;
-}
-NS_IMETHODIMP xpcTestObjectReadWrite :: SetCharProperty(char aCharProperty) {
-    charProperty = aCharProperty;
-    return NS_OK;
-}
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/native/xpctest_module.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   John Bandhauer <jband@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* module registration and factory code. */
-
-#include "nsCOMPtr.h"
-#include "nsIModule.h"
-#include "mozilla/ModuleUtils.h"
-#include "nsCRT.h"
-#include "nsIClassInfoImpl.h"
-#include "xpctest_private.h"
-
-#define NS_XPCTESTOBJECTREADONLY_CID \
-{ 0x492609a7, 0x2582, 0x436b, \
-   { 0xb0, 0xef, 0x92, 0xe2, 0x9b, 0xb9, 0xe1, 0x43 } }
-
-#define NS_XPCTESTOBJECTREADWRITE_CID \
-{ 0x8f37f760, 0x3686, 0x4dbb, \
-   { 0xb1, 0x21, 0x96, 0x93, 0xba, 0x81, 0x3f, 0x8f } }
-
-#define NS_XPCTESTPARAMS_CID \
-{ 0x1f11076a, 0x0fa2, 0x4f07, \
-    { 0xb4, 0x7a, 0xa1, 0x54, 0x31, 0xf2, 0xce, 0xf7 } }
-
-NS_GENERIC_FACTORY_CONSTRUCTOR(xpcTestObjectReadOnly);
-NS_GENERIC_FACTORY_CONSTRUCTOR(xpcTestObjectReadWrite);
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPCTestParams);
-NS_DEFINE_NAMED_CID(NS_XPCTESTOBJECTREADONLY_CID);
-NS_DEFINE_NAMED_CID(NS_XPCTESTOBJECTREADWRITE_CID);
-NS_DEFINE_NAMED_CID(NS_XPCTESTPARAMS_CID);
-
-static const mozilla::Module::CIDEntry kXPCTestCIDs[] = {
-    { &kNS_XPCTESTOBJECTREADONLY_CID, false, NULL, xpcTestObjectReadOnlyConstructor },
-    { &kNS_XPCTESTOBJECTREADWRITE_CID, false, NULL, xpcTestObjectReadWriteConstructor },
-    { &kNS_XPCTESTPARAMS_CID, false, NULL, nsXPCTestParamsConstructor },
-    { NULL }
-};
-
-static const mozilla::Module::ContractIDEntry kXPCTestContracts[] = {
-    { "@mozilla.org/js/xpc/test/native/ObjectReadOnly;1", &kNS_XPCTESTOBJECTREADONLY_CID },
-    { "@mozilla.org/js/xpc/test/native/ObjectReadWrite;1", &kNS_XPCTESTOBJECTREADWRITE_CID },
-    { "@mozilla.org/js/xpc/test/native/Params;1", &kNS_XPCTESTPARAMS_CID },
-    { NULL }
-};
-
-static const mozilla::Module kXPCTestModule = {
-    mozilla::Module::kVersion,
-    kXPCTestCIDs,
-    kXPCTestContracts
-};
-
-NSMODULE_DEFN(xpconnect_test) = &kXPCTestModule;
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/native/xpctest_params.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is XPConnect Test Code.
- *
- * The Initial Developer of the Original Code is The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Bobby Holley <bobbyholley@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "xpctest_private.h"
-
-NS_IMPL_ISUPPORTS1(nsXPCTestParams, nsIXPCTestParams)
-
-nsXPCTestParams::nsXPCTestParams()
-{
-}
-
-nsXPCTestParams::~nsXPCTestParams()
-{
-}
-
-#define GENERIC_METHOD_IMPL { \
-    *_retval = *b; \
-    *b = a; \
-    return NS_OK; \
-}
-
-#define STRING_METHOD_IMPL { \
-    _retval.Assign(b); \
-    b.Assign(a); \
-    return NS_OK; \
-}
-
-/* boolean testBoolean (in boolean a, inout boolean b); */
-NS_IMETHODIMP nsXPCTestParams::TestBoolean(PRBool a, PRBool *b NS_INOUTPARAM, PRBool *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* octet testOctet (in octet a, inout octet b); */
-NS_IMETHODIMP nsXPCTestParams::TestOctet(PRUint8 a, PRUint8 *b NS_INOUTPARAM, PRUint8 *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* short testShort (in short a, inout short b); */
-NS_IMETHODIMP nsXPCTestParams::TestShort(PRInt16 a, PRInt16 *b NS_INOUTPARAM, PRInt16 *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* long testLong (in long a, inout long b); */
-NS_IMETHODIMP nsXPCTestParams::TestLong(PRInt32 a, PRInt32 *b NS_INOUTPARAM, PRInt32 *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* long long testLongLong (in long long a, inout long long b); */
-NS_IMETHODIMP nsXPCTestParams::TestLongLong(PRInt64 a, PRInt64 *b NS_INOUTPARAM, PRInt64 *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* unsigned short testUnsignedShort (in unsigned short a, inout unsigned short b); */
-NS_IMETHODIMP nsXPCTestParams::TestUnsignedShort(PRUint16 a, PRUint16 *b NS_INOUTPARAM, PRUint16 *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* unsigned long testUnsignedLong (in unsigned long a, inout unsigned long b); */
-NS_IMETHODIMP nsXPCTestParams::TestUnsignedLong(PRUint32 a, PRUint32 *b NS_INOUTPARAM, PRUint32 *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* unsigned long long testUnsignedLongLong (in unsigned long long a, inout unsigned long long b); */
-NS_IMETHODIMP nsXPCTestParams::TestUnsignedLongLong(PRUint64 a, PRUint64 *b NS_INOUTPARAM, PRUint64 *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* float testFloat (in float a, inout float b); */
-NS_IMETHODIMP nsXPCTestParams::TestFloat(float a, float *b NS_INOUTPARAM, float *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* double testDouble (in double a, inout float b); */
-NS_IMETHODIMP nsXPCTestParams::TestDouble(double a, float *b NS_INOUTPARAM, double *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* char testChar (in char a, inout char b); */
-NS_IMETHODIMP nsXPCTestParams::TestChar(char a, char *b NS_INOUTPARAM, char *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* string testString (in string a, inout string b); */
-NS_IMETHODIMP nsXPCTestParams::TestString(const char * a, char * *b NS_INOUTPARAM, char * *_retval NS_OUTPARAM)
-{
-    nsDependentCString aprime(a);
-    nsDependentCString bprime(*b);
-    *_retval = ToNewCString(bprime);
-    *b = ToNewCString(aprime);
-    return NS_OK;
-}
-
-/* wchar testWchar (in wchar a, inout wchar b); */
-NS_IMETHODIMP nsXPCTestParams::TestWchar(PRUnichar a, PRUnichar *b NS_INOUTPARAM, PRUnichar *_retval NS_OUTPARAM)
-{
-    GENERIC_METHOD_IMPL;
-}
-
-/* wstring testWstring (in wstring a, inout wstring b); */
-NS_IMETHODIMP nsXPCTestParams::TestWstring(const PRUnichar * a, PRUnichar * *b NS_INOUTPARAM, PRUnichar * *_retval NS_OUTPARAM)
-{
-    nsDependentString aprime(a);
-    nsDependentString bprime(*b);
-    *_retval = ToNewUnicode(bprime);
-    *b = ToNewUnicode(aprime);
-    return NS_OK;
-}
-
-/* DOMString testDOMString (in DOMString a, inout DOMString b); */
-NS_IMETHODIMP nsXPCTestParams::TestDOMString(const nsAString & a, nsAString & b NS_INOUTPARAM, nsAString & _retval NS_OUTPARAM)
-{
-    STRING_METHOD_IMPL;
-}
-
-
-/* AString testAString (in AString a, inout AString b); */
-NS_IMETHODIMP nsXPCTestParams::TestAString(const nsAString & a, nsAString & b NS_INOUTPARAM, nsAString & _retval NS_OUTPARAM)
-{
-    STRING_METHOD_IMPL;
-}
-
-/* AUTF8String testAUTF8String (in AUTF8String a, inout AUTF8String b); */
-NS_IMETHODIMP nsXPCTestParams::TestAUTF8String(const nsACString & a, nsACString & b NS_INOUTPARAM, nsACString & _retval NS_OUTPARAM)
-{
-    STRING_METHOD_IMPL;
-}
-
-/* ACString testACString (in ACString a, inout ACString b); */
-NS_IMETHODIMP nsXPCTestParams::TestACString(const nsACString & a, nsACString & b NS_INOUTPARAM, nsACString & _retval NS_OUTPARAM)
-{
-    STRING_METHOD_IMPL;
-}
-
-/* jsval testJsval (in jsval a, inout jsval b); */
-NS_IMETHODIMP nsXPCTestParams::TestJsval(const jsval & a, jsval & b NS_INOUTPARAM, jsval *_retval NS_OUTPARAM)
-{
-    *_retval = b;
-    b = a;
-    return NS_OK;
-}
deleted file mode 100644
--- a/js/src/xpconnect/tests/components/native/xpctest_private.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   John Bandhauer <jband@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* local header for xpconnect tests components */
-
-#ifndef xpctest_private_h___
-#define xpctest_private_h___
-
-#include "nsISupports.h"
-#include "nsMemory.h"
-#include "jsapi.h"
-#include "nsStringGlue.h"
-#include "xpctest_attributes.h"
-#include "xpctest_params.h"
-
-class xpcTestObjectReadOnly : public nsIXPCTestObjectReadOnly {
- public: 
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIXPCTESTOBJECTREADONLY
-  xpcTestObjectReadOnly();
-   
- private:
-    PRBool  boolProperty;
-    PRInt16 shortProperty;
-    PRInt32 longProperty;
-    float   floatProperty;
-    char    charProperty;
-};
-
-class xpcTestObjectReadWrite : public nsIXPCTestObjectReadWrite {
-  public: 
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIXPCTESTOBJECTREADWRITE
-
-  xpcTestObjectReadWrite();
-  ~xpcTestObjectReadWrite();
-
- private:
-     PRBool boolProperty;
-     PRInt16 shortProperty;
-     PRInt32 longProperty;
-     float floatProperty;
-     char charProperty;
-     char *stringProperty;
-};
-
-class nsXPCTestParams : public nsIXPCTestParams
-{
-public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIXPCTESTPARAMS
-
-    nsXPCTestParams();
-
-private:
-    ~nsXPCTestParams();
-};
-
-#endif /* xpctest_private_h___ */
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_array.cpp
@@ -0,0 +1,388 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* implement nsIXPCTestString for testing. */
+
+#include "xpctest_private.h"
+
+class xpcarraytest : public nsIXPCTestArray
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTARRAY
+
+    xpcarraytest();
+    virtual ~xpcarraytest();
+private:
+    nsIXPCTestArray* mReceiver;
+};
+
+xpcarraytest::xpcarraytest()
+    : mReceiver(NULL)
+{
+    NS_ADDREF_THIS();
+}
+
+xpcarraytest::~xpcarraytest()
+{
+    NS_IF_RELEASE(mReceiver);
+}
+
+NS_IMPL_ISUPPORTS1(xpcarraytest, nsIXPCTestArray)
+
+NS_IMETHODIMP xpcarraytest::SetReceiver(nsIXPCTestArray* aReceiver)
+{
+    NS_IF_ADDREF(aReceiver);
+    NS_IF_RELEASE(mReceiver);
+    mReceiver = aReceiver;
+
+    // a test that forces a QI to some other arbitrary type.
+    if(mReceiver)
+    {
+        nsCOMPtr<nsIEcho> echo = do_QueryInterface(mReceiver);
+    }
+
+    return NS_OK;
+}
+
+
+/* void PrintIntegerArray (in PRUint32 count, [array, size_is (count)] in PRInt32 valueArray); */
+NS_IMETHODIMP
+xpcarraytest::PrintIntegerArray(PRUint32 count, PRInt32 *valueArray)
+{
+    if(mReceiver)
+        return mReceiver->PrintIntegerArray(count, valueArray);
+    if(valueArray && count)
+    {
+        for(PRUint32 i = 0; i < count; i++)
+            printf("%d%s", valueArray[i], i == count -1 ? "\n" : ",");
+    }
+    else
+        printf("empty array\n");
+
+    return NS_OK;
+}
+
+/* void PrintStringArray (in PRUint32 count, [array, size_is (count)] in string valueArray); */
+NS_IMETHODIMP
+xpcarraytest::PrintStringArray(PRUint32 count, const char **valueArray)
+{
+    if(mReceiver)
+        return mReceiver->PrintStringArray(count, valueArray);
+    if(valueArray && count)
+    {
+        for(PRUint32 i = 0; i < count; i++)
+            printf("\"%s\"%s", valueArray[i], i == count -1 ? "\n" : ",");
+    }
+    else
+        printf("empty array\n");
+
+    return NS_OK;
+}
+
+/* void MultiplyEachItemInIntegerArray (in PRInt32 val, in PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
+NS_IMETHODIMP
+xpcarraytest::MultiplyEachItemInIntegerArray(PRInt32 val, PRUint32 count, PRInt32 **valueArray)
+{
+    if(mReceiver)
+        return mReceiver->MultiplyEachItemInIntegerArray(val, count, valueArray);
+    PRInt32* a;
+    if(valueArray && count && nsnull != (a = *valueArray))
+    {
+        for(PRUint32 i = 0; i < count; i++)
+            a[i] *= val;
+        return NS_OK;
+    }
+    return NS_ERROR_FAILURE;
+}        
+
+/* void MultiplyEachItemInIntegerArrayAndAppend (in PRInt32 val, inout PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
+NS_IMETHODIMP
+xpcarraytest::MultiplyEachItemInIntegerArrayAndAppend(PRInt32 val, PRUint32 *count, PRInt32 **valueArray)
+{
+    if(mReceiver)
+        return mReceiver->MultiplyEachItemInIntegerArrayAndAppend(val, count, valueArray);
+    PRInt32* in;
+    PRUint32 in_count;
+    if(valueArray && count && 0 != (in_count = *count) && nsnull != (in = *valueArray))
+    {
+        PRInt32* out = 
+            (PRInt32*) nsMemory::Alloc(in_count * 2 * sizeof(PRUint32));
+
+        if(!out)
+            return NS_ERROR_OUT_OF_MEMORY;
+
+        for(PRUint32 i = 0; i < in_count; i++)
+        {
+            out[i*2]   = in[i];
+            out[i*2+1] = in[i] * val;
+        }
+        nsMemory::Free(in);
+        *valueArray = out;
+        *count = in_count * 2;
+        return NS_OK;
+    }
+    return NS_ERROR_FAILURE;
+}        
+
+/* void CallEchoMethodOnEachInArray (inout nsIIDPtr uuid, inout PRUint32 count, [array, size_is (count), iid_is (uuid)] inout nsQIResult result); */
+NS_IMETHODIMP
+xpcarraytest::CallEchoMethodOnEachInArray(nsIID * *uuid, PRUint32 *count, void * **result)
+{
+    NS_ENSURE_ARG_POINTER(uuid);
+    NS_ENSURE_ARG_POINTER(count);
+    NS_ENSURE_ARG_POINTER(result);
+
+    if(mReceiver)
+        return mReceiver->CallEchoMethodOnEachInArray(uuid, count, result);
+
+    // check that this is the expected type
+    if(!(*uuid)->Equals(NS_GET_IID(nsIEcho)))
+        return NS_ERROR_FAILURE;
+
+    // call each and release
+    nsIEcho** ifaceArray = (nsIEcho**) *result;
+    for(PRUint32 i = 0; i < *count; i++)
+    {
+        ifaceArray[i]->SendOneString("print this from C++");
+        NS_RELEASE(ifaceArray[i]);
+    }
+
+    // cleanup
+    nsMemory::Free(*uuid);
+    nsMemory::Free(*result);
+
+    // set up to hand over array of 'this'
+
+    *uuid = (nsIID*) nsMemory::Clone(&NS_GET_IID(nsIXPCTestArray), 
+                                        sizeof(nsIID));
+    NS_ENSURE_TRUE(*uuid, NS_ERROR_OUT_OF_MEMORY);
+
+    nsISupports** outArray = (nsISupports**) 
+            nsMemory::Alloc(2 * sizeof(nsISupports*));
+    if (!outArray) {
+      nsMemory::Free(*uuid);
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    outArray[0] = outArray[1] = this;    
+    NS_ADDREF(this);
+    NS_ADDREF(this);
+    *result = (void**) outArray;
+
+    *count = 2;
+
+    return NS_OK;
+}        
+
+/* void CallEchoMethodOnEachInArray2 (inout PRUint32 count, [array, size_is (count)] inout nsIEcho result); */
+NS_IMETHODIMP
+xpcarraytest::CallEchoMethodOnEachInArray2(PRUint32 *count, nsIEcho ***result)
+{
+    NS_ENSURE_ARG_POINTER(count);
+    NS_ENSURE_ARG_POINTER(result);
+
+    if(mReceiver)
+        return mReceiver->CallEchoMethodOnEachInArray2(count, result);
+
+    // call each and release
+    nsIEcho** ifaceArray =  *result;
+    for(PRUint32 i = 0; i < *count; i++)
+    {
+        ifaceArray[i]->SendOneString("print this from C++");
+        NS_RELEASE(ifaceArray[i]);
+    }
+
+    // cleanup
+    nsMemory::Free(*result);
+
+    // setup return
+    *count = 0;
+    *result = nsnull;
+    return NS_OK;
+}        
+
+
+
+/* void DoubleStringArray (inout PRUint32 count, [array, size_is (count)] inout string valueArray); */
+NS_IMETHODIMP
+xpcarraytest::DoubleStringArray(PRUint32 *count, char ***valueArray)
+{
+    NS_ENSURE_ARG_POINTER(valueArray);
+    if(mReceiver)
+        return mReceiver->DoubleStringArray(count, valueArray);
+    if(!count || !*count)
+        return NS_OK;
+
+    char** outArray = (char**) nsMemory::Alloc(*count * 2 * sizeof(char*));
+    if(!outArray)
+        return NS_ERROR_OUT_OF_MEMORY;
+    
+    char** p = *valueArray;
+    for(PRUint32 i = 0; i < *count; i++)
+    {
+        int len = strlen(p[i]);
+        outArray[i*2] = (char*)nsMemory::Alloc(((len * 2)+1) * sizeof(char));                        
+        outArray[(i*2)+1] = (char*)nsMemory::Alloc(((len * 2)+1) * sizeof(char));                        
+
+        for(int k = 0; k < len; k++)
+        {
+            outArray[i*2][k*2] = outArray[i*2][(k*2)+1] =
+            outArray[(i*2)+1][k*2] = outArray[(i*2)+1][(k*2)+1] = p[i][k];
+        }
+        outArray[i*2][len*2] = outArray[(i*2)+1][len*2] = '\0';
+        nsMemory::Free(p[i]);
+    }
+
+    nsMemory::Free(p);
+    *valueArray = outArray; 
+    *count = *count * 2;
+    return NS_OK;
+}        
+
+/* void ReverseStringArray (in PRUint32 count, [array, size_is (count)] inout string valueArray); */
+NS_IMETHODIMP
+xpcarraytest::ReverseStringArray(PRUint32 count, char ***valueArray)
+{
+    NS_ENSURE_ARG_POINTER(valueArray);
+    if(mReceiver)
+        return mReceiver->ReverseStringArray(count, valueArray);
+    if(!count)
+        return NS_OK;
+
+    char** p = *valueArray;
+    for(PRUint32 i = 0; i < count/2; i++)
+    {
+        char* temp = p[i];
+        p[i] = p[count-1-i];
+        p[count-1-i] = temp;
+    }
+    return NS_OK;
+}
+
+/* void PrintStringWithSize (in PRUint32 count, [size_is (count)] in string str); */
+NS_IMETHODIMP
+xpcarraytest::PrintStringWithSize(PRUint32 count, const char *str)
+{
+    if(mReceiver)
+        return mReceiver->PrintStringWithSize(count, str);
+    printf("\"%s\" : %d\n", str, count);
+    return NS_OK;
+}        
+
+/* void DoubleString (inout PRUint32 count, [size_is (count)] inout string str); */
+NS_IMETHODIMP
+xpcarraytest::DoubleString(PRUint32 *count, char **str)
+{
+    NS_ENSURE_ARG_POINTER(str);
+    if(mReceiver)
+        return mReceiver->DoubleString(count, str);
+    if(!count || !*count)
+        return NS_OK;
+
+    char* out = (char*) nsMemory::Alloc(((*count * 2)+1) * sizeof(char));                        
+    if(!out)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    PRUint32 k;
+    for(k = 0; k < *count; k++)
+        out[k*2] = out[(k*2)+1] = (*str)[k];
+    out[k*2] = '\0';
+    nsMemory::Free(*str);
+    *str = out; 
+    *count = *count * 2;
+    return NS_OK;
+}        
+
+/* void GetStrings (out PRUint32 count, [array, size_is (count), retval] out string str); */
+NS_IMETHODIMP 
+xpcarraytest::GetStrings(PRUint32 *count, char ***str)
+{
+    const static char *strings[] = {"one", "two", "three", "four"};
+    const static PRUint32 scount = sizeof(strings)/sizeof(strings[0]);
+
+    if(mReceiver)
+        return mReceiver->GetStrings(count, str);
+
+    char** out = (char**) nsMemory::Alloc(scount * sizeof(char*));
+    if(!out)
+        return NS_ERROR_OUT_OF_MEMORY;
+    for(PRUint32 i = 0; i < scount; ++i)
+    {
+        out[i] = (char*) nsMemory::Clone(strings[i], strlen(strings[i])+1);
+        // failure unlikely, leakage foolishly tolerated in this test case
+        if(!out[i])
+            return NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    *count = scount;
+    *str = out;
+    return NS_OK;
+}
+
+/***************************************************************************/
+
+// static
+nsresult
+xpctest::ConstructArrayTest(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcarraytest* obj = new xpcarraytest();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
+/***************************************************************************/
+
+
+
+
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_attributes.cpp
@@ -0,0 +1,305 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "xpctest_attributes.h"
+#include "nsISupports.h"
+#include "xpctest_private.h"
+
+#define NS_IXPCTESTOBJECTREADONLY_IID \
+  {0x1364941e, 0x4462, 0x11d3, \
+    { 0x82, 0xee, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+class xpcTestObjectReadOnly : public nsIXPCTestObjectReadOnly {
+ public: 
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIXPCTESTOBJECTREADONLY
+  xpcTestObjectReadOnly();
+   
+ private:
+    PRBool  boolProperty;
+    PRInt16 shortProperty;
+    PRInt32 longProperty;
+    float   floatProperty;
+    char    charProperty;
+    char    *stringID;
+};
+
+NS_IMPL_ISUPPORTS1(xpcTestObjectReadOnly, nsIXPCTestObjectReadOnly)
+
+xpcTestObjectReadOnly :: xpcTestObjectReadOnly() {
+    NS_ADDREF_THIS();
+
+    boolProperty = PR_TRUE;
+    shortProperty = 32767;
+    longProperty =  2147483647;
+    charProperty = 'X';
+
+    const char _id[] = "a68cc6a6-6552-11d3-82ef-0060b0eb596f";
+    stringID = (char*) nsMemory::Clone(_id, sizeof(char)*(strlen(_id)+1));
+}
+
+NS_IMETHODIMP xpcTestObjectReadOnly :: GetID(char **_retval) {
+    *_retval= (char*) nsMemory::Clone(stringID, 
+                                         sizeof(char)*(strlen(stringID)+1));
+    return *_retval? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+NS_IMETHODIMP xpcTestObjectReadOnly :: GetStrReadOnly(char * *aStrReadOnly){
+    char aString[] = "XPConnect Read-Only String";
+
+    if(!aStrReadOnly)
+        return NS_ERROR_NULL_POINTER;
+    *aStrReadOnly = (char*) nsMemory::Clone(aStrReadOnly, 
+                                               sizeof(char)*(strlen(aString)+1));
+    return *aStrReadOnly ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+NS_IMETHODIMP xpcTestObjectReadOnly :: GetBoolReadOnly(PRBool *aBoolReadOnly) {
+    *aBoolReadOnly = boolProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadOnly :: GetShortReadOnly(PRInt16 *aShortReadOnly){
+    *aShortReadOnly = shortProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadOnly :: GetLongReadOnly(PRInt32 *aLongReadOnly){
+    *aLongReadOnly = longProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadOnly :: GetFloatReadOnly(float *aFloatReadOnly){
+    *aFloatReadOnly = floatProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadOnly :: GetCharReadOnly(char *aCharReadOnly){
+    *aCharReadOnly = charProperty;
+    return NS_OK;
+}
+nsresult
+xpctest::ConstructXPCTestObjectReadOnly(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestObjectReadOnly *obj = new xpcTestObjectReadOnly();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
+/****************************************************************************/
+/* starting interface:    nsIXPCTestObjectReadWrite */
+/* {3b9b1d38-491a-11d3-82ef-0060b0eb596f} */
+/*
+
+#define NS_IXPCTESTOBJECTREADWRITE_IID_STR "3b9b1d38-491a-11d3-82ef-0060b0eb596f"
+*/
+#define NS_IXPCTESTOBJECTREADWRITE_IID \
+  {0x3b9b1d38, 0x491a, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+class xpcTestObjectReadWrite : public nsIXPCTestObjectReadWrite {
+  public: 
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIXPCTESTOBJECTREADWRITE
+  
+  xpcTestObjectReadWrite();
+
+ private:
+     PRBool boolProperty;
+     PRInt16 shortProperty;
+     PRInt32 longProperty;
+     float floatProperty;
+     char charProperty;
+     const char *stringProperty;
+};
+
+NS_IMPL_ISUPPORTS1(xpcTestObjectReadWrite, nsIXPCTestObjectReadWrite)
+
+xpcTestObjectReadWrite :: xpcTestObjectReadWrite() {
+    NS_ADDREF_THIS();
+
+
+    boolProperty = PR_TRUE;
+    shortProperty = 32767;
+    longProperty =  2147483647;
+    charProperty = 'X';
+
+    const char s[] = "XPConnect Read-Writable String";
+    stringProperty = (char*) nsMemory::Clone(s, 
+                                                sizeof(char)*(strlen(s)+1));
+}
+
+NS_IMETHODIMP xpcTestObjectReadWrite :: GetStringProperty(char * *aStringProperty) {
+    if(!aStringProperty)
+        return NS_ERROR_NULL_POINTER;
+    *aStringProperty = (char*) nsMemory::Clone(stringProperty, 
+                                               sizeof(char)*(strlen(stringProperty)+1));
+    return *aStringProperty ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: SetStringProperty(const char * aStringProperty) {
+    stringProperty = aStringProperty;
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpcTestObjectReadWrite :: GetBooleanProperty(PRBool *aBooleanProperty) {
+    *aBooleanProperty = boolProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: SetBooleanProperty(PRBool aBooleanProperty) {
+    boolProperty = aBooleanProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: GetShortProperty(PRInt16 *aShortProperty) {
+    *aShortProperty = shortProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: SetShortProperty(PRInt16 aShortProperty) {
+    shortProperty = aShortProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: GetLongProperty(PRInt32 *aLongProperty) {
+    *aLongProperty = longProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: SetLongProperty(PRInt32 aLongProperty) {
+    longProperty = aLongProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: GetFloatProperty(float *aFloatProperty) {
+    *aFloatProperty = floatProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: SetFloatProperty(float aFloatProperty) {
+    floatProperty = aFloatProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: GetCharProperty(char *aCharProperty) {
+    *aCharProperty = charProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestObjectReadWrite :: SetCharProperty(char aCharProperty) {
+    charProperty = aCharProperty;
+    return NS_OK;
+}
+nsresult
+xpctest::ConstructXPCTestObjectReadWrite(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestObjectReadWrite *obj = new xpcTestObjectReadWrite();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+    return rv;
+}
+
+
+/****************************************************************************/
+/*
+class xpcTestAttributes : public nsIXPCTestObjectReadWrite, 
+    public nsIXPCTestObjectReadOnly
+{
+public: 
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIXPCTESTOBJECTREADONLY
+  NS_DECL_NSIXPCTESTOBJECTREADWRITE
+
+  NS_IMETHOD GetName(char * *aString);
+  NS_IMETHOD SetName(char * aString );
+
+private:
+    char *name;
+};
+  
+NS_IMPL_ISUPPORTS2(xpcTestAttributes, nsIXPCTestObjectReadWrite, nsIXPCTestObjectReadOnly)
+
+NS_IMETHODIMP xpcTestAttributes ::GetName(char * *aString) {
+    if(!aString)
+        return NS_ERROR_NULL_POINTER;
+    *aString = (char*) nsMemory::Clone(name, 
+                sizeof(char)*(strlen(name)+1));
+    return *aString ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+
+}
+NS_IMETHODIMP xpcTestAttributes ::SetName(char * aString) {
+    name = aString;
+    return NS_OK;
+}
+
+nsresult
+xpctest::ConstructXPCTestAttributes(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestAttributes *obj = new xpcTestAttributes();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+    return rv;
+}
+*/
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_calljs.cpp
@@ -0,0 +1,136 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "xpctest_private.h"
+#include "nsIXPCScriptable.h"
+#include "xpctest_calljs.h"
+#include "nsISupports.h"
+#include "nsIClassInfoImpl.h"
+
+class xpcTestCallJS : public nsIXPCTestCallJS, public nsIXPCScriptable {
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTCALLJS
+    NS_DECL_NSIXPCSCRIPTABLE
+    xpcTestCallJS();
+    virtual ~xpcTestCallJS();
+
+private:
+    nsIXPCTestCallJS* jsobject;
+};
+
+
+NS_IMPL_CLASSINFO(xpcTestCallJS, NULL, 0, NS_XPCTESTCALLJS_CID)
+NS_IMPL_ISUPPORTS2_CI(xpcTestCallJS, nsIXPCTestCallJS, nsIXPCScriptable)
+
+// The nsIXPCScriptable map declaration that will generate stubs for us...
+#define XPC_MAP_CLASSNAME           xpcTestCallJS
+#define XPC_MAP_QUOTED_CLASSNAME   "xpcTestCallJS"
+#define XPC_MAP_FLAGS               0
+#include "xpc_map_end.h" /* This will #undef the above */
+
+xpcTestCallJS :: xpcTestCallJS() {
+    NS_ADDREF_THIS();
+}
+
+xpcTestCallJS :: ~xpcTestCallJS() {
+
+}
+
+NS_IMETHODIMP xpcTestCallJS :: SetJSObject( nsIXPCTestCallJS* o ) {
+    //if (jsobject)
+    //  NS_RELEASE( jsobject );
+    jsobject = o;
+    if ( jsobject ) 
+        NS_ADDREF( jsobject );
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpcTestCallJS :: CallMethodNoArgs(PRBool *_retval) {
+    *_retval = PR_TRUE;
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpcTestCallJS :: Evaluate ( const char *s ) {
+    if (jsobject)
+        return jsobject->Evaluate(s);
+    return NS_OK;
+}
+
+NS_IMETHODIMP 
+xpcTestCallJS :: EvaluateAndReturnError(nsresult in, nsresult *_retval){
+    if (jsobject) {
+        jsobject->EvaluateAndReturnError(in, _retval);
+    } else {
+        *_retval = in;
+    }
+    return *_retval;
+}
+
+NS_IMETHODIMP xpcTestCallJS :: EvaluateAndEatErrors(const char *s) {
+    if ( jsobject ) 
+        jsobject->Evaluate(s);
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpcTestCallJS :: UnscriptableMethod() {
+    return NS_OK;
+}
+
+nsresult
+xpctest::ConstructXPCTestCallJS(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestCallJS *obj = new xpcTestCallJS();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+    return rv;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_child.cpp
@@ -0,0 +1,225 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *   Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* implement nsIChild for testing. */
+
+#include "xpctest_private.h"
+
+#define USE_MI 0
+
+#if USE_MI
+/***************************************************************************/
+
+class xpctestOther : public nsIXPCTestOther
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTOTHER
+
+    xpctestOther();
+};
+
+class xpctestChild : public nsIXPCTestChild, public xpctestOther
+{
+public:
+    NS_DECL_ISUPPORTS_INHERITED
+    NS_DECL_NSIXPCTESTPARENT
+    NS_DECL_NSIXPCTESTCHILD
+
+    xpctestChild();
+};
+
+NS_IMPL_ISUPPORTS1(xpctestOther, nsIXPCTestOther)
+
+xpctestOther::xpctestOther()
+{
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP xpctestOther::Method3(PRInt16 i, PRInt16 j, PRInt16 k)
+{
+    printf("Method3 called on inherited other\n");
+    return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS_INHERITED1(xpctestChild, xpctestOther, nsIXPCTestChild)
+
+xpctestChild::xpctestChild()
+{
+}
+
+NS_IMETHODIMP xpctestChild::Method1(PRInt16 i)
+{
+    printf("Method1 called on child\n");
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpctestChild::Method1a(nsIXPCTestParent *foo)
+{
+    printf("Method1a called on child\n");
+    return NS_OK;
+}
+
+
+NS_IMETHODIMP xpctestChild::Method2(PRInt16 i, PRInt16 j)
+{
+    printf("Method2 called on child\n");
+    return NS_OK;
+}
+
+#if 0
+class xpctestParent : public nsIXPCTestParent
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTPARENT
+
+    xpctestParent();
+};
+
+
+class xpctestChild : public xpctestParent, public nsIXPCTestChild
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTCHILD
+
+    xpctestChild();
+};
+
+NS_IMETHODIMP xpctestParent::Method1(PRInt16 i)
+{
+    printf("Method1 called on parent via child\n");
+    return NS_OK;
+}
+NS_IMETHODIMP xpctestParent::Method1a(nsIXPCTestParent *foo)
+{
+    printf("Method1a called on parent via child\n");
+    return NS_OK;
+}
+
+#endif
+
+/***************************************************************************/
+#else
+/***************************************************************************/
+class xpctestChild : public nsIXPCTestChild
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTPARENT
+    NS_DECL_NSIXPCTESTCHILD
+
+    xpctestChild();
+};
+
+NS_IMPL_ADDREF(xpctestChild)
+NS_IMPL_RELEASE(xpctestChild)
+
+NS_IMETHODIMP
+xpctestChild::QueryInterface(REFNSIID iid, void** result)
+{
+    if (! result)
+        return NS_ERROR_NULL_POINTER;
+
+    if (iid.Equals(NS_GET_IID(nsIXPCTestChild)) ||
+        iid.Equals(NS_GET_IID(nsIXPCTestParent)) ||
+        iid.Equals(NS_GET_IID(nsISupports))) {
+        *result = static_cast<nsIXPCTestChild*>(this);
+        NS_ADDREF(this);
+        return NS_OK;
+    }
+    else {
+        *result = nsnull;
+        return NS_NOINTERFACE;
+    }
+}
+
+xpctestChild::xpctestChild()
+{
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP xpctestChild::Method1(PRInt16 i)
+{
+    printf("Method1 called on child\n");
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpctestChild::Method1a(nsIXPCTestParent *foo)
+{
+    printf("Method1a called on child\n");
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpctestChild::Method2(PRInt16 i, PRInt16 j)
+{
+    printf("Method2 called on child\n");
+    return NS_OK;
+}
+#endif
+/***************************************************************************/
+
+// static
+nsresult
+xpctest::ConstructChild(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpctestChild* obj = new xpctestChild();
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+    return rv;
+}
+/***************************************************************************/
+
+
+
+
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_const.cpp
@@ -0,0 +1,76 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.h"
+#include "xpctest_const.h"
+#include "xpctest_private.h"
+
+class xpcTestConst : public nsIXPCTestConst {
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIXPCTESTCONST
+  xpcTestConst();
+};
+
+NS_IMPL_ISUPPORTS1(xpcTestConst, nsIXPCTestConst)
+
+xpcTestConst :: xpcTestConst() {
+    NS_ADDREF_THIS();
+}
+
+nsresult
+xpctest::ConstructXPCTestConst(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestConst *obj = new xpcTestConst();
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+    return rv;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_domstring.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mike Shaver <shaver@mozilla.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.h"
+#include "nsString.h"
+#include "xpctest_domstring.h"
+#include "xpctest_private.h"
+
+class xpcTestDOMString : public nsIXPCTestDOMString {
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTDOMSTRING
+    xpcTestDOMString();
+    virtual ~xpcTestDOMString();
+private:
+    nsString mStr;
+};
+
+NS_IMPL_ISUPPORTS1(xpcTestDOMString, nsIXPCTestDOMString)
+
+xpcTestDOMString::xpcTestDOMString()
+{
+    NS_ADDREF_THIS();
+}
+
+xpcTestDOMString::~xpcTestDOMString()
+{
+}
+
+NS_IMETHODIMP
+xpcTestDOMString::HereHaveADOMString(const nsAString &str)
+{
+    // assignment will share buffer if possible
+    mStr = str;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcTestDOMString::DontKeepThisOne(const nsAString &str)
+{
+    nsCString c; c.AssignWithConversion(str);
+    fprintf(stderr, "xpcTestDOMString::DontKeepThisOne: \"%s\"\n", c.get());
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcTestDOMString::GiveDOMStringTo(nsIXPCTestDOMString *recv)
+{
+    NS_NAMED_LITERAL_STRING(myString, "A DOM String, Just For You");
+    return recv->HereHaveADOMString(myString);
+}
+
+NS_IMETHODIMP
+xpcTestDOMString::PassDOMStringThroughTo(const nsAString &str,
+                                         nsIXPCTestDOMString *recv)
+{
+    return recv->HereHaveADOMString(str);
+}
+
+
+nsresult
+xpctest::ConstructXPCTestDOMString(nsISupports *aOuter, REFNSIID aIID,
+                                   void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(!aOuter, "no aggregation");
+    xpcTestDOMString *obj = new xpcTestDOMString();
+    if (obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+    return rv;
+}
+
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_echo.cpp
@@ -0,0 +1,616 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* implement nsIEcho for testing. */
+
+#include "xpctest_private.h"
+
+#ifdef WIN32
+#define IMPLEMENT_TIMER_STUFF 1
+#endif
+
+class xpctestEcho : public nsIEcho
+#ifdef IMPLEMENT_TIMER_STUFF
+, public nsITimerCallback
+#endif // IMPLEMENT_TIMER_STUFF
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIECHO
+
+#ifdef IMPLEMENT_TIMER_STUFF
+    NS_DECL_NSITIMERCALLBACK
+#endif // IMPLEMENT_TIMER_STUFF
+
+    xpctestEcho();
+    virtual ~xpctestEcho();
+private:
+    nsIEcho* mReceiver;
+    char*    mString;
+    PRInt32  mSomeValue;
+};
+
+/***************************************************************************/
+
+#ifdef IMPLEMENT_TIMER_STUFF
+NS_IMPL_ISUPPORTS2(xpctestEcho, nsIEcho, nsITimerCallback)
+#else
+NS_IMPL_ISUPPORTS1(xpctestEcho, nsIEcho)
+#endif // IMPLEMENT_TIMER_STUFF
+
+xpctestEcho::xpctestEcho()
+    : mReceiver(nsnull), mString(nsnull), mSomeValue(0)
+{
+    NS_ADDREF_THIS();
+}
+
+xpctestEcho::~xpctestEcho()
+{
+    NS_IF_RELEASE(mReceiver);
+    if(mString)
+        nsMemory::Free(mString);
+}
+
+NS_IMETHODIMP xpctestEcho::SetReceiver(nsIEcho* aReceiver)
+{
+    NS_IF_ADDREF(aReceiver);
+    NS_IF_RELEASE(mReceiver);
+    mReceiver = aReceiver;
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpctestEcho::SendOneString(const char* str)
+{
+    if(mReceiver)
+        return mReceiver->SendOneString(str);
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpctestEcho::In2OutOneInt(int input, int* output)
+{
+    *output = input;
+    return NS_OK;
+}
+
+/* DOMString In2OutOneDOMString (in DOMString input); */
+NS_IMETHODIMP xpctestEcho::In2OutOneDOMString(const nsAString & input, 
+                                              nsAString & _retval)
+{
+    _retval.Assign(input);
+    return NS_OK;
+}
+
+/* DOMString EchoIn2OutOneDOMString (in DOMString input); */
+NS_IMETHODIMP xpctestEcho::EchoIn2OutOneDOMString(const nsAString & input, nsAString & _retval)
+{
+    if(mReceiver)
+        return mReceiver->EchoIn2OutOneDOMString(input, _retval);
+    return NS_OK;
+}
+
+/* AString In2OutOneAString (in AString input); */
+NS_IMETHODIMP xpctestEcho::In2OutOneAString(const nsAString & input, 
+                                              nsAString & _retval)
+{
+    _retval.Assign(input);
+    return NS_OK;
+}
+
+/* AString EchoIn2OutOneAString (in AString input); */
+NS_IMETHODIMP xpctestEcho::EchoIn2OutOneAString(const nsAString & input, nsAString & _retval)
+{
+    if(mReceiver)
+        return mReceiver->EchoIn2OutOneAString(input, _retval);
+    return NS_OK;
+}
+
+
+/* UTF8String In2OutOneUTF8String (in UTF8String input); */
+NS_IMETHODIMP xpctestEcho::In2OutOneUTF8String(const nsACString & input, 
+                                              nsACString & _retval)
+{
+    _retval.Assign(input);
+    return NS_OK;
+}
+
+/* UTF8String EchoIn2OutOneUTF8String (in UTF8String input); */
+NS_IMETHODIMP xpctestEcho::EchoIn2OutOneUTF8String(const nsACString & input, 
+                                                   nsACString & _retval)
+{
+    if(mReceiver)
+        return mReceiver->EchoIn2OutOneUTF8String(input, _retval);
+    return NS_OK;
+}
+
+/* CString In2OutOneCString (in CString input); */
+NS_IMETHODIMP xpctestEcho::In2OutOneCString(const nsACString & input, 
+                                            nsACString & _retval)
+{
+    _retval.Assign(input);
+    return NS_OK;
+}
+
+/* CString EchoIn2OutOneCString (in CString input); */
+NS_IMETHODIMP xpctestEcho::EchoIn2OutOneCString(const nsACString & input, 
+                                                nsACString & _retval)
+{
+    if(mReceiver)
+        return mReceiver->EchoIn2OutOneCString(input, _retval);
+    return NS_OK;
+}
+
+
+NS_IMETHODIMP xpctestEcho::In2OutAddTwoInts(int input1,
+                                       int input2,
+                                       int* output1,
+                                       int* output2,
+                                       int* result)
+{
+    *output1 = input1;
+    *output2 = input2;
+    *result = input1+input2;
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpctestEcho::In2OutOneString(const char* input, char** output)
+{
+    char* p;
+    int len;
+    if(input && output &&
+       (nsnull != (p = (char*)nsMemory::Alloc(len=strlen(input)+1))))
+    {
+        memcpy(p, input, len);
+        *output = p;
+        return NS_OK;
+    }
+    if(output)
+        *output = nsnull;
+    return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP xpctestEcho::SimpleCallNoEcho()
+{
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpctestEcho::SendManyTypes(PRUint8              p1,
+                      PRInt16             p2,
+                      PRInt32             p3,
+                      PRInt64             p4,
+                      PRUint8              p5,
+                      PRUint16            p6,
+                      PRUint32            p7,
+                      PRUint64            p8,
+                      float             p9,
+                      double            p10,
+                      PRBool            p11,
+                      char              p12,
+                      PRUnichar            p13,
+                      const nsID*       p14,
+                      const char*       p15,
+                      const PRUnichar*  p16)
+{
+    if(mReceiver)
+        return mReceiver->SendManyTypes(p1, p2, p3, p4, p5, p6, p7, p8, p9,
+                                        p10, p11, p12, p13, p14, p15, p16);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpctestEcho::SendInOutManyTypes(PRUint8*    p1,
+                           PRInt16*   p2,
+                           PRInt32*   p3,
+                           PRInt64*   p4,
+                           PRUint8*    p5,
+                           PRUint16*  p6,
+                           PRUint32*  p7,
+                           PRUint64*  p8,
+                           float*   p9,
+                           double*  p10,
+                           PRBool*  p11,
+                           char*    p12,
+                           PRUnichar*  p13,
+                           nsID**   p14,
+                           char**   p15,
+                           PRUnichar** p16)
+{
+    if(mReceiver)
+        return mReceiver->SendInOutManyTypes(p1, p2, p3, p4, p5, p6, p7, p8, p9,
+                                             p10, p11, p12, p13, p14, p15, p16);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpctestEcho::MethodWithNative(int p1, void* p2)
+{
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpctestEcho::ReturnCode(int code)
+{
+    return (nsresult) code;
+}
+
+NS_IMETHODIMP
+xpctestEcho::FailInJSTest(int fail)
+{
+    if(mReceiver)
+        return mReceiver->FailInJSTest(fail);
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpctestEcho::SharedString(const char **str)
+{
+    *str = "a static string";
+/*
+    // to do non-shared we clone the string:
+    char buf[] = "a static string";
+    int len;
+    *str = (char*)nsMemory::Alloc(len=strlen(buf)+1);
+    memcpy(*str, buf, len);
+*/
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpctestEcho::ReturnCode_NS_OK()
+{return NS_OK;}
+
+NS_IMETHODIMP
+xpctestEcho::ReturnCode_NS_ERROR_NULL_POINTER()
+{return NS_ERROR_NULL_POINTER;}
+
+NS_IMETHODIMP
+xpctestEcho::ReturnCode_NS_ERROR_UNEXPECTED()
+{return NS_ERROR_UNEXPECTED;}
+
+NS_IMETHODIMP
+xpctestEcho::ReturnCode_NS_ERROR_OUT_OF_MEMORY()
+{return NS_ERROR_OUT_OF_MEMORY;}
+
+NS_IMETHODIMP
+xpctestEcho::ReturnInterface(nsISupports *obj, nsISupports **_retval)
+{
+    if(!_retval)
+        return NS_ERROR_NULL_POINTER;
+    if(obj)
+        NS_ADDREF(obj);
+    *_retval = obj;
+    return NS_OK;
+}
+
+/* nsIStackFrame GetStack (); */
+NS_IMETHODIMP
+xpctestEcho::GetStack(nsIStackFrame **_retval)
+{
+    nsIStackFrame* stack = nsnull;
+    if(!_retval)
+        return NS_ERROR_NULL_POINTER;
+
+    nsresult rv;
+    nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
+    if(NS_SUCCEEDED(rv))
+    {
+        nsIStackFrame* jsstack;
+        if(NS_SUCCEEDED(xpc->GetCurrentJSStack(&jsstack)) && jsstack)
+        {
+            xpc->CreateStackFrameLocation(nsIProgrammingLanguage::CPLUSPLUS,
+                                          __FILE__,
+                                          "xpctestEcho::GetStack",
+                                          __LINE__,
+                                          jsstack,
+                                          &stack);
+            NS_RELEASE(jsstack);
+        }
+    }
+
+    if(stack)
+    {
+        *_retval = stack;
+        return NS_OK;
+    }
+    return NS_ERROR_FAILURE;
+}
+
+/* void SetReceiverReturnOldReceiver (inout nsIEcho aReceiver); */
+NS_IMETHODIMP
+xpctestEcho::SetReceiverReturnOldReceiver(nsIEcho **aReceiver)
+{
+    if(!aReceiver)
+        return NS_ERROR_NULL_POINTER;
+
+    nsIEcho* oldReceiver = mReceiver;
+    mReceiver = *aReceiver;
+    if(mReceiver)
+        NS_ADDREF(mReceiver);
+
+    /* don't release the reference, that is the caller's problem */
+    *aReceiver = oldReceiver;
+    return NS_OK;
+}
+
+/* void MethodWithForwardDeclaredParam (in nsITestXPCSomeUselessThing sut); */
+NS_IMETHODIMP
+xpctestEcho::MethodWithForwardDeclaredParam(nsITestXPCSomeUselessThing *sut)
+{
+    return NS_OK;
+}
+
+/* void PseudoQueryInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */
+NS_IMETHODIMP
+xpctestEcho::PseudoQueryInterface(const nsIID & uuid, void * *result)
+{
+    if(!result)
+        return NS_ERROR_NULL_POINTER;
+    if(mReceiver)
+        return mReceiver->PseudoQueryInterface(uuid, result);
+    return NS_OK;
+}        
+
+/* void DebugDumpJSStack (); */
+NS_IMETHODIMP
+xpctestEcho::DebugDumpJSStack()
+{
+    nsresult rv;
+    nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
+    if(NS_SUCCEEDED(rv))
+    {
+        rv = xpc->DebugDumpJSStack(JS_TRUE, JS_TRUE, JS_TRUE);
+    }
+    return rv;
+}        
+
+/* attribute string aString; */
+NS_IMETHODIMP 
+xpctestEcho::GetAString(char * *aAString)
+{
+    printf(">>>> xpctestEcho::GetAString called\n");
+    if(mString)
+        *aAString = (char*) nsMemory::Clone(mString, strlen(mString)+1);
+    else
+        *aAString = nsnull;
+    return NS_OK;
+}
+NS_IMETHODIMP 
+xpctestEcho::SetAString(const char * aAString)
+{
+    printf("<<<< xpctestEcho::SetAString called\n");
+    if(mString)
+        nsMemory::Free(mString);
+    if(aAString)
+        mString = (char*) nsMemory::Clone(aAString, strlen(aAString)+1);
+    else
+        mString = nsnull;
+    return NS_OK;
+}
+
+
+
+/***************************************************/
+
+// some tests of nsIXPCNativeCallContext
+
+#define GET_CALL_CONTEXT \
+  nsresult rv; \
+  nsAXPCNativeCallContext *cc = nsnull; \
+  nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); \
+  if(NS_SUCCEEDED(rv)) \
+    rv = xpc->GetCurrentNativeCallContext(&cc) /* no ';' */        
+
+/* void printArgTypes (); */
+NS_IMETHODIMP
+xpctestEcho::PrintArgTypes(void)
+{
+    GET_CALL_CONTEXT;
+    if(NS_FAILED(rv) || !cc)
+        return NS_ERROR_FAILURE;
+
+    nsCOMPtr<nsISupports> callee;
+    if(NS_FAILED(cc->GetCallee(getter_AddRefs(callee))) ||
+       callee != static_cast<nsIEcho*>(this))
+        return NS_ERROR_FAILURE;
+
+    PRUint32 argc;
+    if(NS_SUCCEEDED(cc->GetArgc(&argc)))
+        printf("argc = %d  ", (int)argc);
+    else
+        return NS_ERROR_FAILURE;
+
+    jsval* argv;
+    if(NS_FAILED(cc->GetArgvPtr(&argv)))
+        return NS_ERROR_FAILURE;
+
+    printf("argv types = [");
+
+    for(PRUint32 i = 0; i < argc; i++)
+    {
+        const char* type = "<unknown>";
+        if(JSVAL_IS_OBJECT(argv[i]))
+        {
+            if(JSVAL_IS_NULL(argv[i]))
+                type = "null";
+            else
+                type = "object";
+        }
+        else if (JSVAL_IS_BOOLEAN(argv[i]))
+            type = "boolean";
+        else if (JSVAL_IS_STRING(argv[i]))
+            type = "string";
+        else if (JSVAL_IS_DOUBLE(argv[i]))
+            type = "double";
+        else if (JSVAL_IS_INT(argv[i]))
+            type = "int";
+        else if (JSVAL_IS_VOID(argv[i]))
+            type = "void";
+
+        fputs(type, stdout);
+
+        if(i < argc-1)
+            printf(", ");
+    }
+    printf("]\n");
+    
+    return NS_OK;
+}
+
+/* void throwArg (); */
+NS_IMETHODIMP
+xpctestEcho::ThrowArg(void)
+{
+    GET_CALL_CONTEXT;
+    if(NS_FAILED(rv) || !cc)
+        return NS_ERROR_FAILURE;
+
+    nsCOMPtr<nsISupports> callee;
+    if(NS_FAILED(cc->GetCallee(getter_AddRefs(callee))) || 
+       callee != static_cast<nsIEcho*>(this))
+        return NS_ERROR_FAILURE;
+
+    PRUint32 argc;
+    if(NS_FAILED(cc->GetArgc(&argc)) || !argc)
+        return NS_OK;
+
+    jsval* argv;
+    JSContext* cx;
+    if(NS_FAILED(cc->GetArgvPtr(&argv)) ||
+       NS_FAILED(cc->GetJSContext(&cx)))
+        return NS_ERROR_FAILURE;
+
+    JS_SetPendingException(cx, argv[0]);
+    return NS_OK;
+}
+
+/* void callReceiverSometimeLater (); */
+NS_IMETHODIMP
+xpctestEcho::CallReceiverSometimeLater(void)
+{
+    // Mac does not even compile this code and Unix build systems
+    // have build order problems with linking to the static timer lib
+    // as it is built today. This is only test code and we can stand to 
+    // have it only work on Win32 for now.
+
+#ifdef IMPLEMENT_TIMER_STUFF
+    nsCOMPtr<nsITimer> timer;
+    nsresult rv;
+    timer = do_CreateInstance("@mozilla.org/timer;1", &rv);
+    if(NS_FAILED(rv))
+        return NS_ERROR_FAILURE;
+    timer->InitWithCallback(static_cast<nsITimerCallback*>(this), 2000,
+                            nsITimer::TYPE_ONE_SHOT);
+    return NS_OK;
+#else
+    return NS_ERROR_NOT_IMPLEMENTED;
+#endif // IMPLEMENT_TIMER_STUFF
+}
+
+#ifdef IMPLEMENT_TIMER_STUFF
+NS_IMETHODIMP
+xpctestEcho::Notify(nsITimer *timer)
+{
+    if(mReceiver)
+        mReceiver->CallReceiverSometimeLater();
+    NS_RELEASE(timer);
+    return NS_OK;
+}        
+#endif // IMPLEMENT_TIMER_STUFF
+
+/* readonly attribute short throwInGetter; */
+NS_IMETHODIMP
+xpctestEcho::GetThrowInGetter(PRInt16 *aThrowInGetter)
+{
+    return NS_ERROR_FAILURE;
+}        
+
+/* void callFunction (in nsITestXPCFunctionCallback callback, in string s); */
+NS_IMETHODIMP 
+xpctestEcho::CallFunction(nsITestXPCFunctionCallback *callback, const char *s)
+{
+    return callback->Call(s);
+}
+
+/* void callFunction (in nsITestXPCFunctionCallback callback, in string s); */
+NS_IMETHODIMP 
+xpctestEcho::CallFunctionWithThis(nsITestXPCFunctionCallback *callback, nsISupports* self, const char *s)
+{
+    return callback->CallWithThis(self, s);
+}
+
+/* attribute PRInt32 SomeValue; */
+NS_IMETHODIMP 
+xpctestEcho::GetSomeValue(PRInt32 *aSomeValue)
+{
+    *aSomeValue = mSomeValue;
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpctestEcho::SetSomeValue(PRInt32 aSomeValue)
+
+{
+    mSomeValue = aSomeValue;
+    return NS_OK;
+}
+
+/***************************************************************************/
+
+// static
+nsresult
+xpctest::ConstructEcho(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpctestEcho* obj = new xpctestEcho();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_in.cpp
@@ -0,0 +1,204 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "xpctest_private.h"
+#include "xpctest_in.h"
+#include "nsISupports.h"
+#define NS_IXPCTESTIN_IID \
+  {0xa3cab49d, 0xae83, 0x4e63, \
+    { 0xa7, 0x35, 0x00, 0x9b, 0x9a, 0x75, 0x92, 0x04 }}
+
+
+class xpcTestIn : public nsIXPCTestIn {
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIXPCTESTIN
+
+  xpcTestIn();
+};
+
+NS_IMPL_ISUPPORTS1(xpcTestIn, nsIXPCTestIn)
+
+xpcTestIn :: xpcTestIn() {
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP xpcTestIn :: EchoLong(PRInt32 l, PRInt32 *_retval) {
+    *_retval = l;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoShort(PRInt16 a, PRInt16 *_retval) {
+    *_retval = a;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoChar(char c, char *_retval) {
+    *_retval = c;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoBoolean(PRBool b, PRBool *_retval) {
+    *_retval = b;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoOctet(PRUint8 o, PRUint8 *_retval) {
+    *_retval = o;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoLongLong(PRInt64 ll, PRInt64 *_retval) {
+    *_retval = ll;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoUnsignedShort(PRUint16 us, PRUint16 *_retval) {
+    *_retval = us;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoUnsignedLong(PRUint32 ul, PRUint32 *_retval) {
+    *_retval = ul;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoFloat(float f, float *_retval) {
+    *_retval = f;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoDouble(double d, double *_retval) {
+    *_retval = d;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoWchar(PRUnichar wc, PRUnichar *_retval) {
+    *_retval = wc;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoString(const PRUnichar *ws, PRUnichar **_retval) {
+/*  const char s[] = *ws;
+    **_retval= (char*) nsMemory::Clone(s, 
+                                    sizeof(char)*(strlen(s)+1));
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+*/
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoPRBool(PRBool b, PRBool *_retval) {
+    *_retval = b;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoPRInt32(PRInt32 l, PRInt32 *_retval) {
+    *_retval = l;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoPRInt16(PRInt16 l, PRInt16 *_retval) {
+    *_retval = l;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoPRInt64(PRInt64 i, PRInt64 *_retval) {
+    *_retval = i;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoPRUint8(PRUint8 i, PRUint8 *_retval){
+    *_retval = i;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoPRUint16(PRUint16 i, PRUint16 *_retval){
+    *_retval = i;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoPRUint32(PRUint32 i, PRUint32 *_retval){
+    *_retval = i;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoPRUint64(PRUint64 i, PRUint64 *_retval) {
+    *_retval = i;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestIn :: EchoVoidPtr(void * vs, void * *_retval) {
+    *_retval = vs;
+    return NS_OK;
+} 
+
+NS_IMETHODIMP xpcTestIn :: EchoCharPtr(char * cs, char * *_retval) {
+    **_retval = *cs;
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpcTestIn :: EchoPRUint32_2(PRUint32 i, PRUint32 *_retval){
+    *_retval = i;
+    return NS_OK;
+}
+ /*
+NS_IMETHODIMP xpcTestIn :: EchoNsIDRef(const nsID & r, nsID & *_retval) {
+    &*_retval = r;
+}
+NS_IMETHODIMP xpcTestIn :: EchoNsCIDRef(const nsCID & r, nsCID & *_retval) {
+    &*_retval = r;
+}
+NS_IMETHODIMP xpcTestIn :: EchoNsIDPtr(const nsID * p, nsID * *_retval) {
+    **_retval = p;
+}
+NS_IMETHODIMP xpcTestIn :: EchoNsIIDPtr(const nsIID * p, nsIID * *_retval) {
+    *_retval = p;
+}
+NS_IMETHODIMP xpcTestIn :: EchoNsCIDPtr(const nsCID * p, nsCID * *_retval) {
+    *_retval = p;
+}
+NS_IMETHODIMP xpcTestIn :: EchoNsQIResult(void * r, void * *_retval) {
+    **_retval = r;
+}
+*/
+NS_IMETHODIMP xpcTestIn :: EchoVoid(void) {
+    return NS_OK;
+}
+
+nsresult
+xpctest::ConstructXPCTestIn(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestIn *obj = new xpcTestIn();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+    return rv;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_inout.cpp
@@ -0,0 +1,171 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.h"
+#include "xpctest_inout.h"
+#include "xpctest_private.h"
+
+class xpcTestInOut : public nsIXPCTestInOut {
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIXPCTESTINOUT
+
+  xpcTestInOut();
+};
+
+NS_IMPL_ISUPPORTS1(xpcTestInOut, nsIXPCTestInOut)
+
+xpcTestInOut :: xpcTestInOut() {
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP xpcTestInOut :: EchoLong(PRInt32 li, PRInt32 *lo){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoShort(PRInt16 si, PRInt16 *so){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoChar(char ci, char *co){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoBoolean(PRBool bi, PRBool *bo){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoOctet(PRUint8 oi, PRUint8 *oo){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoLongLong(PRInt64 lli, PRInt64 *llo){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoUnsignedShort(PRUint16 usi, PRUint16 *uso){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoUnsignedLong(PRUint32 uli, PRUint32 *ulo){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoFloat(float fi, float *fo){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoDouble(double di, double *dout){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoWchar(PRUnichar wci, PRUnichar *wco){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoString(const PRUnichar *wsi, PRUnichar **wso){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoPRBool(PRBool bi, PRBool *bo){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoPRInt32(PRInt32 li, PRInt32 *lo){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoPRInt16(PRInt16 li, PRInt16 *lo){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoPRInt64(PRInt64 ii, PRInt64 *io){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoPRUint8(PRUint8 ii, PRUint8 *io){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoPRUint16(PRUint16 ii, PRUint16 *io){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoPRUint32(PRUint32 ii, PRUint32 *io){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoPRUint32_2(PRUint32 ii, PRUint32 *io){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoPRUint64(PRUint64 ii, PRUint64 *io){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoVoidPtr(void * vsi, void * *vso){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoCharPtr(char * csi, char * *cso){ 
+    return NS_OK; 
+}
+/*
+NS_IMETHODIMP xpcTestInOut :: EchoNsIDRef(const nsID & ri, nsID & *ro){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoNsCIDRef(const nsCID & ri, nsCID & *ro){ 
+    return NS_OK; 
+}
+*/
+NS_IMETHODIMP xpcTestInOut :: EchoNsIDPtr(const nsID * pi, nsID * *po){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoNsIIDPtr(const nsIID * pi, nsIID * *po){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoNsCIDPtr(const nsCID * pi, nsCID * *po){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoNsQIResult(void * ri, void * *ro){ 
+    return NS_OK; 
+}
+NS_IMETHODIMP xpcTestInOut :: EchoVoid(void) {
+    return NS_OK;
+}
+
+nsresult
+xpctest::ConstructXPCTestInOut(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestInOut *obj = new xpcTestInOut();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+    return rv;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_module.cpp
@@ -0,0 +1,128 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* module registration and factory code. */
+
+#include "xpctest_private.h"
+#include "nsCOMPtr.h"
+#include "nsIModule.h"
+#include "mozilla/ModuleUtils.h"
+#include "nsCRT.h"
+#include "nsIClassInfoImpl.h"
+
+NS_DEFINE_NAMED_CID(NS_ECHO_CID);
+NS_DEFINE_NAMED_CID(NS_CHILD_CID);
+NS_DEFINE_NAMED_CID(NS_NOISY_CID);
+NS_DEFINE_NAMED_CID(NS_STRING_TEST_CID);
+NS_DEFINE_NAMED_CID(NS_OVERLOADED_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTOBJECTREADONLY_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTOBJECTREADWRITE_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTIN_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTOUT_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTINOUT_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTCONST_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTCALLJS_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTPARENTONE_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTPARENTTWO_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTCHILD2_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTCHILD3_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTCHILD4_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTCHILD5_CID);
+NS_DEFINE_NAMED_CID(NS_ARRAY_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTDOMSTRING_CID);
+NS_DEFINE_NAMED_CID(NS_XPCTESTVARIANT_CID);
+
+static const mozilla::Module::CIDEntry kXPCTestCIDs[] = {
+    { &kNS_ECHO_CID, false, NULL, xpctest::ConstructEcho },
+    { &kNS_CHILD_CID, false, NULL, xpctest::ConstructChild },
+    { &kNS_NOISY_CID, false, NULL, xpctest::ConstructNoisy },
+    { &kNS_STRING_TEST_CID, false, NULL, xpctest::ConstructStringTest },
+    { &kNS_OVERLOADED_CID, false, NULL, xpctest::ConstructOverloaded },
+    { &kNS_XPCTESTOBJECTREADONLY_CID, false, NULL, xpctest::ConstructXPCTestObjectReadOnly },
+    { &kNS_XPCTESTOBJECTREADWRITE_CID, false, NULL, xpctest::ConstructXPCTestObjectReadWrite },
+    { &kNS_XPCTESTIN_CID, false, NULL, xpctest::ConstructXPCTestIn },
+    { &kNS_XPCTESTOUT_CID, false, NULL, xpctest::ConstructXPCTestOut },
+    { &kNS_XPCTESTINOUT_CID, false, NULL, xpctest::ConstructXPCTestInOut },
+    { &kNS_XPCTESTCONST_CID, false, NULL, xpctest::ConstructXPCTestConst },
+    { &kNS_XPCTESTCALLJS_CID, false, NULL, xpctest::ConstructXPCTestCallJS },
+    { &kNS_XPCTESTPARENTONE_CID, false, NULL, xpctest::ConstructXPCTestParentOne },
+    { &kNS_XPCTESTPARENTTWO_CID, false, NULL, xpctest::ConstructXPCTestParentTwo },
+    { &kNS_XPCTESTCHILD2_CID, false, NULL, xpctest::ConstructXPCTestChild2 },
+    { &kNS_XPCTESTCHILD3_CID, false, NULL, xpctest::ConstructXPCTestChild3 },
+    { &kNS_XPCTESTCHILD4_CID, false, NULL, xpctest::ConstructXPCTestChild4 },
+    { &kNS_XPCTESTCHILD5_CID, false, NULL, xpctest::ConstructXPCTestChild5 },
+    { &kNS_ARRAY_CID, false, NULL, xpctest::ConstructArrayTest },
+    { &kNS_XPCTESTDOMSTRING_CID, false, NULL, xpctest::ConstructXPCTestDOMString },
+    { &kNS_XPCTESTVARIANT_CID, false, NULL, xpctest::ConstructXPCTestVariant },
+    { NULL }
+};
+
+static const mozilla::Module::ContractIDEntry kXPCTestContracts[] = {
+    { "@mozilla.org/js/xpc/test/Echo;1", &kNS_ECHO_CID },
+    { "@mozilla.org/js/xpc/test/Child;1", &kNS_CHILD_CID },
+    { "@mozilla.org/js/xpc/test/Noisy;1", &kNS_NOISY_CID },
+    { "@mozilla.org/js/xpc/test/StringTest;1", &kNS_STRING_TEST_CID },
+    { "@mozilla.org/js/xpc/test/Overloaded;1", &kNS_OVERLOADED_CID },
+    { "@mozilla.org/js/xpc/test/ObjectReadOnly;1", &kNS_XPCTESTOBJECTREADONLY_CID },
+    { "@mozilla.org/js/xpc/test/ObjectReadWrite;1", &kNS_XPCTESTOBJECTREADWRITE_CID },
+    { "@mozilla.org/js/xpc/test/In;1", &kNS_XPCTESTIN_CID },
+    { "@mozilla.org/js/xpc/test/Out;1", &kNS_XPCTESTOUT_CID },
+    { "@mozilla.org/js/xpc/test/InOut;1", &kNS_XPCTESTINOUT_CID },
+    { "@mozilla.org/js/xpc/test/Const;1", &kNS_XPCTESTCONST_CID },
+    { "@mozilla.org/js/xpc/test/CallJS;1", &kNS_XPCTESTCALLJS_CID },
+    { "@mozilla.org/js/xpc/test/ParentOne;1", &kNS_XPCTESTPARENTONE_CID },
+    { "@mozilla.org/js/xpc/test/ParentTwo;1", &kNS_XPCTESTPARENTTWO_CID },
+    { "@mozilla.org/js/xpc/test/Child2;1", &kNS_XPCTESTCHILD2_CID },
+    { "@mozilla.org/js/xpc/test/Child3;1", &kNS_XPCTESTCHILD3_CID },
+    { "@mozilla.org/js/xpc/test/Child4;1", &kNS_XPCTESTCHILD4_CID },
+    { "@mozilla.org/js/xpc/test/Child5;1", &kNS_XPCTESTCHILD5_CID },
+    { "@mozilla.org/js/xpc/test/ArrayTest;1", &kNS_ARRAY_CID },
+    { "@mozilla.org/js/xpc/test/DOMString;1", &kNS_XPCTESTDOMSTRING_CID },
+    { "@mozilla.org/js/xpc/test/TestVariant;1", &kNS_XPCTESTVARIANT_CID },
+    { NULL }
+};
+
+static const mozilla::Module kXPCTestModule = {
+    mozilla::Module::kVersion,
+    kXPCTestCIDs,
+    kXPCTestContracts
+};
+
+NSMODULE_DEFN(xpconnect_test) = &kXPCTestModule;
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_multiple.cpp
@@ -0,0 +1,555 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "xpctest_multiple.h"
+#include "nsISupports.h"
+#include "xpctest_private.h"
+#include "nsIClassInfoImpl.h"
+
+class xpcTestParentOne : public nsIXPCTestParentOne {
+public: 
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTPARENTONE
+    xpcTestParentOne();
+private: 
+    const char *name;
+};
+
+NS_IMPL_ISUPPORTS1(xpcTestParentOne, nsIXPCTestParentOne)
+
+xpcTestParentOne :: xpcTestParentOne() 
+{
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP xpcTestParentOne :: GetParentOneAttribute(char * *_retval) 
+{                                                             
+    char aString[] = "xpcTestParentOne attribute";     
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                                            
+
+NS_IMETHODIMP xpcTestParentOne :: SetParentOneAttribute(const char * aParentOneAttribute) 
+{                                                             
+    name = aParentOneAttribute;                               
+    return NS_OK;                                             
+}                                                                  
+
+NS_IMETHODIMP                                                 
+xpcTestParentOne :: ParentOneMethod(char * *_retval)                   
+{                                                             
+    char aString[] = "xpcTestParentOne method";  
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                                                   
+nsresult
+xpctest::ConstructXPCTestParentOne(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestParentOne *obj = new xpcTestParentOne();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}                                                                
+
+
+/*****************************************************************************/
+
+class xpcTestParentTwo : public nsIXPCTestParentTwo {
+public: 
+  NS_DECL_NSIXPCTESTPARENTTWO
+  NS_DECL_ISUPPORTS
+  xpcTestParentTwo();
+private:
+    const char *name;
+};
+
+NS_IMPL_ISUPPORTS1(xpcTestParentTwo, nsIXPCTestParentTwo)
+
+xpcTestParentTwo :: xpcTestParentTwo()
+{
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP                                                 
+xpcTestParentTwo :: GetParentTwoAttribute(char * *_retval)             
+{                                                             
+    char aString[] = "xpcTestParentTwo attribute";               
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                                        
+
+NS_IMETHODIMP                                                 
+xpcTestParentTwo :: SetParentTwoAttribute(const char * aParentTwoAttribute)  
+{                                                             
+    name = aParentTwoAttribute;                               
+    return NS_OK;                                             
+}                                                                   
+
+NS_IMETHODIMP                                                 
+xpcTestParentTwo :: ParentTwoMethod(char **_retval) 
+{                  
+    char aString[] = "xpcTestParentTwo method";  
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}
+  
+nsresult
+xpctest::ConstructXPCTestParentTwo(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestParentTwo *obj = new xpcTestParentTwo();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}                                                                
+/*****************************************************************************/
+
+/**
+ * nsIXPCTestChild2 inherits from nsISupports
+ */
+
+class xpcTestChild2 : public nsIXPCTestChild2, public nsIXPCTestParentOne, public nsIXPCTestParentTwo {
+public: 
+  NS_DECL_NSIXPCTESTCHILD2
+  NS_DECL_NSIXPCTESTPARENTONE
+  NS_DECL_NSIXPCTESTPARENTTWO
+  NS_DECL_ISUPPORTS
+  xpcTestChild2();
+private:
+    const char *name;
+};
+
+NS_IMPL_CLASSINFO(xpcTestChild2, NULL, 0, NS_XPCTESTCHILD2_CID)
+NS_IMPL_ISUPPORTS3_CI(xpcTestChild2,nsIXPCTestChild2,nsIXPCTestParentOne,nsIXPCTestParentTwo)
+
+xpcTestChild2 :: xpcTestChild2() 
+{
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP 
+xpcTestChild2:: GetChildAttribute(char * *_retval) 
+{
+    char aString[] = "xpcTestChild2 attribute";    
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}
+
+NS_IMETHODIMP 
+xpcTestChild2:: SetChildAttribute(const char * aChildAttribute) 
+{
+    name = aChildAttribute;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcTestChild2 ::ChildMethod(char **_retval) 
+{
+    char aString[] = "xpcTestChild2 method";  
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}
+
+
+NS_IMETHODIMP                                                 
+xpcTestChild2 :: GetParentOneAttribute(char * *_retval)     
+{                                                             
+    char aString[] = "xpcTestChild2 attribute";     
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                                            
+
+NS_IMETHODIMP                                                 
+xpcTestChild2:: SetParentOneAttribute(const char * aParentOneAttribute) 
+{                                                             
+    name = aParentOneAttribute;                               
+    return NS_OK;                                             
+}                                                                  
+
+NS_IMETHODIMP                                                 
+xpcTestChild2 :: ParentOneMethod(char * *_retval)                   
+{                                                             
+    char aString[] = "xpcTestChild2 method";  
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                  
+
+NS_IMETHODIMP                                                 
+xpcTestChild2 :: GetParentTwoAttribute(char * *_retval)             
+{                                                             
+    char aString[] = "xpcTestChild2 attribute";               
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                                            
+
+NS_IMETHODIMP                                                 
+xpcTestChild2 :: SetParentTwoAttribute(const char * aParentTwoAttribute)  
+{                                                             
+    name = aParentTwoAttribute;                               
+    return NS_OK;                                             
+}                                                                  
+
+NS_IMETHODIMP                                                 
+xpcTestChild2 :: ParentTwoMethod(char **_retval) {                  
+    char aString[] = "xpcTestChild2 method";  
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                 
+
+nsresult
+xpctest::ConstructXPCTestChild2(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestChild2 *obj = new xpcTestChild2();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
+
+/*****************************************************************************/
+
+/**
+ * xpcTestChild3 inherits from nsIXPCTestChild3, which inherits from 
+ * nsIXPCTestParentOne
+ */
+
+class xpcTestChild3 : public nsIXPCTestChild3 {
+public: 
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIXPCTESTCHILD3
+  NS_DECL_NSIXPCTESTPARENTONE
+  xpcTestChild3();
+private:
+    const char *name;
+};
+
+NS_IMPL_ISUPPORTS2(xpcTestChild3,nsIXPCTestChild3,nsIXPCTestParentOne)
+
+xpcTestChild3 :: xpcTestChild3() 
+{
+    NS_ADDREF_THIS();
+
+}
+
+NS_IMETHODIMP 
+xpcTestChild3:: GetChildAttribute(char * *_retval) 
+{
+    char aString[] = "xpcTestChild3 attribute";    
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}
+
+NS_IMETHODIMP 
+xpcTestChild3 :: SetChildAttribute(const char * aChildAttribute) 
+{
+    name = aChildAttribute;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcTestChild3 ::ChildMethod(char **_retval) 
+{
+    const char aString[] = "xpcTestChild3 method";
+    *_retval = (char*) nsMemory::Clone((const char *)aString,
+                sizeof(char)*(strlen((const char *)aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}
+
+
+NS_IMETHODIMP                                                 
+xpcTestChild3 :: GetParentOneAttribute(char * *_retval)     
+{                                                             
+    const char aString[] = "xpcTestChild3 attribute";     
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                                            
+
+NS_IMETHODIMP                                                 
+xpcTestChild3:: SetParentOneAttribute(const char * aParentOneAttribute) 
+{                                                             
+    name = aParentOneAttribute;                               
+    return NS_OK;                                             
+}                                                                  
+
+NS_IMETHODIMP                                                 
+xpcTestChild3 :: ParentOneMethod(char * *_retval)                   
+{                                                             
+    char aString[] = "xpcTestChild3 method";  
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                  
+
+nsresult
+xpctest::ConstructXPCTestChild3(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestChild3 *obj = new xpcTestChild3();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
+
+/*****************************************************************************/
+
+/**
+ * xpcTestChild4 - class which inherits from nsIXPCTestChild4 (which inherits
+ * directly from nsISupports) and two classes.
+ */
+
+class xpcTestChild4 : public nsIXPCTestChild4, public xpcTestParentOne, public xpcTestParentTwo {
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTCHILD4
+    xpcTestChild4();
+private:
+    const char *name;
+};
+
+NS_IMPL_ISUPPORTS3(xpcTestChild4,nsIXPCTestChild4,nsIXPCTestParentOne,nsIXPCTestParentTwo)
+
+xpcTestChild4 :: xpcTestChild4() 
+{
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP 
+xpcTestChild4:: GetChildAttribute(char * *_retval) 
+{
+    char aString[] = "xpcTestChild4 attribute";    
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}
+
+NS_IMETHODIMP 
+xpcTestChild4:: SetChildAttribute(const char * aChildAttribute) 
+{
+    name = aChildAttribute;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcTestChild4 ::ChildMethod(char **_retval) 
+{
+    char aString[] = "xpcTestChild4 method";  
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}
+
+nsresult
+xpctest::ConstructXPCTestChild4(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestChild4 *obj = new xpcTestChild4();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
+
+/*****************************************************************************/
+/**
+ * xpcTestChild5 - class which inherits from nsIXPCTestChild5 (which inherits
+ * from nsIXPCTestParentOne) and the class xpcTestParentTwo 
+ */
+
+class xpcTestChild5 : public nsIXPCTestChild5, public xpcTestParentTwo {
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTCHILD5
+    NS_DECL_NSIXPCTESTPARENTONE
+    xpcTestChild5();
+private:
+    const char *name;
+};
+
+NS_IMPL_ISUPPORTS3(xpcTestChild5,nsIXPCTestChild5,nsIXPCTestParentOne,nsIXPCTestParentTwo)
+
+xpcTestChild5 :: xpcTestChild5() 
+{
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP 
+xpcTestChild5:: GetChildAttribute(char * *_retval) 
+{
+    char aString[] = "xpcTestChild5 attribute";    
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}
+
+NS_IMETHODIMP 
+xpcTestChild5:: SetChildAttribute(const char * aChildAttribute) 
+{
+    name = aChildAttribute;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+xpcTestChild5 ::ChildMethod(char **_retval) 
+{
+    char aString[] = "xpcTestChild5 method";  
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}
+
+
+NS_IMETHODIMP                                                 
+xpcTestChild5 :: GetParentOneAttribute(char * *_retval)     
+{                                                             
+    char aString[] = "xpcTestChild5 attribute";     
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                                            
+
+NS_IMETHODIMP                                                 
+xpcTestChild5:: SetParentOneAttribute(const char * aParentOneAttribute) 
+{                                                             
+    name = aParentOneAttribute;                               
+    return NS_OK;                                             
+}                                                                  
+
+NS_IMETHODIMP                                                 
+xpcTestChild5 :: ParentOneMethod(char * *_retval)                   
+{                                                             
+    char aString[] = "xpcTestChild5 method";  
+    *_retval = (char*) nsMemory::Clone(aString,            
+                sizeof(char)*(strlen(aString)+1));            
+    return **_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;        
+}                                  
+
+nsresult
+xpctest::ConstructXPCTestChild5(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestChild5 *obj = new xpcTestChild5();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_noisy.cpp
@@ -0,0 +1,154 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *   Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* implement nsIXPCTestNoisy for testing. */
+
+#include "xpctest_private.h"
+
+class xpctestNoisy : public nsIXPCTestNoisy
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTNOISY
+
+    xpctestNoisy();
+    virtual ~xpctestNoisy();
+private:
+    static int sID;
+    static int sCount;
+    int        mID;
+};
+
+int xpctestNoisy::sID = 0;
+int xpctestNoisy::sCount = 0;
+
+
+NS_IMETHODIMP_(nsrefcnt) xpctestNoisy::AddRef(void)
+{
+  NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
+  ++mRefCnt;
+  NS_LOG_ADDREF(this, mRefCnt, "xpctestNoisy", sizeof(*this));
+  printf("Noisy %d - incremented refcount to %d\n", mID, mRefCnt.get());
+  return mRefCnt;
+}
+
+NS_IMETHODIMP_(nsrefcnt) xpctestNoisy::Release(void)
+{
+  NS_PRECONDITION(0 != mRefCnt, "dup release");
+  --mRefCnt;
+  printf("Noisy %d - decremented refcount to %d\n", mID, mRefCnt.get());
+  NS_LOG_RELEASE(this, mRefCnt, "xpctestNoisy");
+  if (mRefCnt == 0) {
+    delete this;
+    return 0;
+  }
+  return mRefCnt;
+}
+
+NS_IMETHODIMP
+xpctestNoisy::QueryInterface(REFNSIID iid, void** result)
+{
+    if (! result)
+        return NS_ERROR_NULL_POINTER;
+
+    if (iid.Equals(NS_GET_IID(nsIXPCTestNoisy)) ||
+        iid.Equals(NS_GET_IID(nsISupports))) {
+        *result = static_cast<nsIXPCTestNoisy*>(this);
+        printf("Noisy %d - QueryInterface called and succeeding\n", mID);
+        NS_ADDREF(this);
+        return NS_OK;
+    }
+    else {
+        *result = nsnull;
+        printf("Noisy %d - QueryInterface for interface I don't do\n", mID);
+        return NS_NOINTERFACE;
+    }
+}
+
+xpctestNoisy::xpctestNoisy()
+    : mID(++sID)
+{
+    sCount++;
+    printf("Noisy %d - Created, %d total\n", mID, sCount);
+    NS_ADDREF_THIS();
+}
+
+xpctestNoisy::~xpctestNoisy()
+{
+    sCount--;
+    printf("Noisy %d - Destroyed, %d total\n", mID, sCount);
+}
+
+NS_IMETHODIMP xpctestNoisy::Squawk()
+{
+    printf("Noisy %d - Squawk called\n", mID);
+    return NS_OK;
+}
+
+/***************************************************************************/
+
+// static
+nsresult
+xpctest::ConstructNoisy(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpctestNoisy* obj = new xpctestNoisy();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
+/***************************************************************************/
+
+
+
+
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_out.cpp
@@ -0,0 +1,335 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "xpctest_private.h"
+#include "xpctest_out.h"
+#include "nsISupports.h"
+
+#define NS_IXPCTESTOUT_IID \
+  {0x4105ae88, 0x5599, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+class xpcTestOut : public nsIXPCTestOut {
+public:
+NS_DECL_ISUPPORTS
+NS_DECL_NSIXPCTESTOUT
+xpcTestOut();
+
+private:
+    PRInt32   longProperty;
+    PRInt16  shortProperty;
+    char   charProperty;
+    float  floatProperty;
+    double doubleProperty;
+    PRUnichar * stringProperty;
+    PRBool booleanProperty;
+    PRUint8 octetProperty;
+    PRUint16 unsignedShortProperty;
+    PRUint32 unsignedLongProperty;
+    PRInt64 longLongProperty;
+    PRUnichar wcharProperty;
+//	PRUnichar *wsStringProperty;
+
+    PRBool PRBoolProperty;
+    PRInt32 PRInt32Property;
+    PRInt16 PRInt16Property;
+    PRInt64 PRInt64Property;
+    PRUint8 PRUint8Property;
+    PRUint16 PRUint16Property;
+    PRUint32 PRUint32Property;
+    PRUint64 PRUint64Property;
+};
+
+
+NS_IMPL_ISUPPORTS1(xpcTestOut, nsIXPCTestOut)
+
+xpcTestOut :: xpcTestOut() {
+    NS_ADDREF_THIS();
+}
+
+NS_IMETHODIMP xpcTestOut :: GetLong(PRInt32 *l){
+    *l = longProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetLong(PRInt32 l){
+    longProperty = l;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetShort(PRInt16 *s){
+    *s  = shortProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetShort(PRInt16 s){
+    shortProperty = s;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetChar(char c){
+    charProperty = c;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetChar(char *c){
+    *c = charProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetBoolean(PRBool *b){
+    *b = booleanProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetBoolean(PRBool b){
+    booleanProperty = b;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetOctet(PRUint8 *o){
+    *o = octetProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetOctet(PRUint8 o){
+    octetProperty = o;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetLongLong(PRInt64 *ll){
+    *ll = longLongProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetLongLong(PRInt64 ll){
+    longLongProperty = ll;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetUnsignedShort(PRUint16 *us){
+    *us = unsignedShortProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetUnsignedShort(PRUint16 us){
+    unsignedShortProperty = us;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetUnsignedLong(PRUint32 *ul){
+    *ul = unsignedLongProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetUnsignedLong(PRUint32 ul){
+    unsignedLongProperty = ul;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetFloat(float *f){
+    *f = floatProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetFloat(float f){
+    floatProperty = f;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetDouble(double *d){
+    *d = doubleProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetDouble(double d){
+    doubleProperty = d;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetWchar(PRUnichar *wc){
+    *wc = wcharProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetWchar(PRUnichar wc){
+    wcharProperty = wc;
+    return NS_OK;
+}
+/*
+NS_IMETHODIMP xpcTestOut :: GetString(PRUnichar **ws){
+    **ws = *stringProperty;
+
+    if(!stringProperty)
+        return NS_ERROR_NULL_POINTER;
+    *ws = (PRUnichar *) nsMemory::Clone(stringProperty, 
+                    sizeof(char) *(strlen(stringProperty)+1));
+    return **ws? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetString(const PRUnichar *ws){
+    //stringProperty = ws;
+    return NS_OK;
+}
+*/
+NS_IMETHODIMP xpcTestOut :: GetPRBool(PRBool *b){
+    *b = PRBoolProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetPRBool(PRBool b){
+    PRBoolProperty = b;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetPRInt32(PRInt32 *l){
+    *l = PRInt32Property;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetPRInt32(PRInt32 l){
+    PRInt32Property = l;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetPRInt16(PRInt16 *l){
+    *l = PRInt16Property;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetPRInt16(PRInt16 l){
+    PRInt16Property = l;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetPRInt64(PRInt64 *i){
+    *i = PRInt64Property;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetPRInt64(PRInt64 i){
+    PRInt64Property = i;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetPRUint8(PRUint8 *i){
+    *i = PRUint8Property;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetPRUint8(PRUint8 i){
+    PRUint8Property = i;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetPRUint16(PRUint16 *i){
+    *i = PRUint16Property;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetPRUint16(PRUint16 i){
+    PRUint16Property = i;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetPRUint32(PRUint32 *i){
+    *i = PRUint32Property;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetPRUint32(PRUint32 i){
+    PRUint32Property = i;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetPRUint64(PRUint64 *i){
+    *i = PRUint64Property;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetPRUint64(PRUint64 i){
+    PRUint64Property = i;
+    return NS_OK;
+}
+/*
+NS_IMETHODIMP xpcTestOut :: GetVoidStar(void * *vs){
+    **vs = voidStarProperty;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetVoidStar(void * vs){
+    voidStarProperty = vs;
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetCharStar(char * *cs){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetCharStar(char * cs){
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpcTestOut :: GetNsIDRef(nsID & *r){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetNsIDRef(const nsID & r){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetNsCIDRef(nsCID & *r){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetNsCIDRef(const nsCID & r){
+    return NS_OK;
+}
+
+NS_IMETHODIMP xpcTestOut :: GetNsIDPtr(nsID * *p){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetNsIDPtr(const nsID * p){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetNsIIDPtr(nsIID * *p){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetNsIIDPtr(const nsIID * p){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetNsCIDPtr(nsCID * *p){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetNsCIDPtr(const nsCID * p){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetNsQIResult(void * *r){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetNsQIResult(void * r){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: GetVoid(void){
+    return NS_OK;
+}
+NS_IMETHODIMP xpcTestOut :: SetVoid(void){
+    return NS_OK;
+}
+*/
+nsresult
+xpctest::ConstructXPCTestOut(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcTestOut *obj = new xpcTestOut();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+    return rv;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_overloaded.cpp
@@ -0,0 +1,250 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *   Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* implement nsIXPCTestOverloaded as an example. */
+
+#include "xpctest_private.h"
+#include "nsIXPCScriptable.h"
+
+/*
+* This is an example of one way to reflect an interface into JavaScript such
+* that one method name is overloaded to reflect multiple methods. This practice
+* is strongly discouraged. But, some legacy JavaScript interfaces require this
+* in order to support existing JavaScript code.
+*/
+
+/***************************************************************************/
+/* This is a JS example of calling the object implemented below. */
+
+/*
+* // to run this in the shell...
+* // put this in "foo.js" and the run "xpcshell foo.js"
+*
+*  var clazz = Components.classes.nsOverloaded;
+*  var iface = Components.interfaces.nsIXPCTestOverloaded;
+*
+*  foo = clazz.createInstance(iface);
+*
+*  try {
+*      print("foo.Foo1(1)...  ");  foo.Foo1(1)
+*      print("foo.Foo2(1,2)...");  foo.Foo2(1,2)
+*      print("foo.Foo(3)...   ");  foo.Foo(3)
+*      print("foo.Foo(3,4)... ");  foo.Foo(3,4)
+*      print("foo.Foo()...    ");  foo.Foo();
+*  } catch(e) {
+*      print("caught exception: "+e);
+*  }
+*
+*/
+
+/***************************************************************************/
+
+/*
+* This is the implementation of nsIXPCScriptable. This interface is used
+* by xpconnect in order to allow wrapped native objects to gain greater
+* control over how they are reflected into JavaScript. Most wrapped native
+* objects do not need to implement this interface. It is useful for dynamic
+* properties (those properties not explicitly mentioned in the .idl file).
+* Here we are using the nsIXPCScriptable as a way to bootstrap some JS code
+* to be run each time a wrapper is built around an instance of our object.
+*
+* xpconnect allows implementors of nsIXPCScriptable to bend the rules a bit...
+* implementations of nsIXPCScriptable are not required to follow QueryInterface
+* identity rules; i.e. doing a QI(NS_GET_IID(nsISupports)) on this interface is
+* not required to return the same pointer as doing so on the object that
+* presented this interface. Thus, it is allowable to implement only one
+* nsIXPCScriptable instance per class if desired.
+*/
+
+class xpcoverloaded : public nsIXPCTestOverloaded, public nsIXPCScriptable
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTOVERLOADED
+    NS_DECL_NSIXPCSCRIPTABLE
+
+    xpcoverloaded();
+    virtual ~xpcoverloaded();
+};
+
+xpcoverloaded::xpcoverloaded()
+{
+    NS_ADDREF_THIS();
+}
+
+xpcoverloaded::~xpcoverloaded()
+{
+    // empty
+}
+
+NS_IMPL_ISUPPORTS2(xpcoverloaded, nsIXPCTestOverloaded, nsIXPCScriptable)
+
+/* void Foo1 (in PRInt32 p1); */
+NS_IMETHODIMP
+xpcoverloaded::Foo1(PRInt32 p1)
+{
+    printf("xpcoverloaded::Foo1 called with p1 = %d\n", p1);
+    return NS_OK;
+}
+
+/* void Foo2 (in PRInt32 p1, in PRInt32 p2); */
+NS_IMETHODIMP
+xpcoverloaded::Foo2(PRInt32 p1, PRInt32 p2)
+{
+    printf("xpcoverloaded::Foo2 called with p1 = %d and p2 = %d\n", p1, p2);
+    return NS_OK;
+}
+
+// The nsIXPCScriptable map declaration that will generate stubs for us...
+#define XPC_MAP_CLASSNAME           xpcoverloaded
+#define XPC_MAP_QUOTED_CLASSNAME   "xpcoverloaded"
+#define                             XPC_MAP_WANT_CREATE
+#define XPC_MAP_FLAGS               0
+#include "xpc_map_end.h" /* This will #undef the above */
+
+// We implement this method ourselves
+
+
+/* void create (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
+NS_IMETHODIMP 
+xpcoverloaded::Create(nsIXPConnectWrappedNative *wrapper, 
+                      JSContext * cx, JSObject * obj)
+{
+/*
+* Here are two implementations...
+*
+* The first uses a shared prototype object to implement the forwarding
+* function.
+*
+* The second adds the forwarding function to each and every object
+*/
+#if 1
+/*
+* NOTE: in the future xpconnect is likely to build and maintain a
+* 'per CLSID' prototype object. When we have flattened interfaces code will
+* be able to ask the wrapper for the prototype object. The prototype object
+* will be shared by all wrapped objects with the given CLSID.
+*
+* *** If anyone uses the code below to make their own prototype objects they
+*     should be prepared to convert the code when the new scheme arrives. ***
+*/
+
+    static const char name[] = "__xpcoverloadedProto__";
+    static const char source[] =
+        "__xpcoverloadedProto__ = {"
+        "   Foo : function() {"
+        "     switch(arguments.length) {"
+        "     case 1: return this.Foo1(arguments[0]);"
+        "     case 2: return this.Foo2(arguments[0], arguments[1]);"
+        "     default: throw '1 or 2 arguments required';"
+        "     }"
+        "   }"
+        "};";
+
+    jsval proto;
+
+    if(!JS_GetProperty(cx, JS_GetGlobalObject(cx), name, &proto) ||
+       JSVAL_IS_PRIMITIVE(proto))
+    {
+       if(!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), source, strlen(source),
+                          "builtin", 1, &proto) ||
+          !JS_GetProperty(cx, JS_GetGlobalObject(cx), name, &proto)||
+          JSVAL_IS_PRIMITIVE(proto))
+            return NS_ERROR_UNEXPECTED;
+    }
+    if(!JS_SetPrototype(cx, obj, JSVAL_TO_OBJECT(proto)))
+        return NS_ERROR_UNEXPECTED;
+    return NS_OK;
+
+#else
+    // NOTE: this script is evaluated where the wrapped object is the current
+    // 'this'.
+
+    // here is a 'Foo' implementation that will forward to the appropriate
+    // non-overloaded method.
+    static const char source[] =
+        "this.Foo = function() {"
+        "  switch(arguments.length) {"
+        "  case 1: return this.Foo1(arguments[0]);"
+        "  case 2: return this.Foo2(arguments[0], arguments[1]);"
+        "  default: throw '1 or 2 arguments required';"
+        "  }"
+        "};";
+
+    jsval ignored;
+    JS_EvaluateScript(cx, obj, source, strlen(source), "builtin", 1, &ignored);
+    return NS_OK;
+#endif
+}
+
+/***************************************************************************/
+
+
+/***************************************************************************/
+// our standard generic factory helper.
+
+// static
+nsresult
+xpctest::ConstructOverloaded(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcoverloaded* obj = new xpcoverloaded();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
+/***************************************************************************/
+
+
+
+
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_private.h
@@ -0,0 +1,192 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* local header for xpconnect tests components */
+
+#ifndef xpctest_private_h___
+#define xpctest_private_h___
+
+#include "nsISupports.h"
+#include "nsIFactory.h"
+#include "nsMemory.h"
+#include "nsIXPConnect.h"
+#include "nsIServiceManager.h"
+#include "nsIComponentManager.h"
+#include "mozilla/ModuleUtils.h"
+#include "nscore.h"
+#include "nsCOMPtr.h"
+#include "nsAString.h"
+#include "nsVariant.h"
+#include <stdio.h>
+
+#include "xpctest.h"
+#include "jsapi.h"
+
+#ifdef WIN32
+#define IMPLEMENT_TIMER_STUFF 1
+#endif
+
+#ifdef IMPLEMENT_TIMER_STUFF
+#include "nsITimer.h"
+#endif // IMPLEMENT_TIMER_STUFF
+
+// {ED132C20-EED1-11d2-BAA4-00805F8A5DD7}
+#define NS_ECHO_CID \
+{ 0xed132c20, 0xeed1, 0x11d2, \
+    { 0xba, 0xa4, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
+
+// {0ECB3420-0D6F-11d3-BAB8-00805F8A5DD7}
+#define NS_CHILD_CID \
+{ 0xecb3420, 0xd6f, 0x11d3, \
+    { 0xba, 0xb8, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
+
+// {FD774840-237B-11d3-9879-006008962422}
+#define NS_NOISY_CID \
+{ 0xfd774840, 0x237b, 0x11d3, \
+    { 0x98, 0x79, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
+
+// {4DD7EC80-30D9-11d3-9885-006008962422}
+#define NS_STRING_TEST_CID \
+{ 0x4dd7ec80, 0x30d9, 0x11d3,\
+    { 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
+
+// {DC5FDE90-439D-11d3-988C-006008962422}
+#define NS_OVERLOADED_CID \
+{ 0xdc5fde90, 0x439d, 0x11d3, \
+    { 0x98, 0x8c, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
+
+#define NS_XPCTESTOBJECTREADONLY_CID \
+  {0x1364941e, 0x4462, 0x11d3, \
+    { 0x82, 0xee, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTOBJECTREADWRITE_CID \
+  {0x3b9b1d38, 0x491a, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTIN_CID \
+  {0xa3cab49d, 0xae83, 0x4e63, \
+    { 0xa7, 0x35, 0x00, 0x9b, 0x9a, 0x75, 0x92, 0x04 }}
+
+#define NS_XPCTESTOUT_CID \
+  {0x4105ae88, 0x5599, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTINOUT_CID \
+  { 0x70c54fa0, 0xc25e, 0x11d3, \
+    { 0x98, 0xc9, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
+
+#define NS_XPCTESTCONST_CID \
+  {0x83f57a56, 0x4f55, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTCALLJS_CID \
+  {0x38ba7d98, 0x5a54, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTPARENTONE_CID \
+  {0x5408fdcc, 0x60a3, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTPARENTTWO_CID \
+  {0x63137392, 0x60a3, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTCHILD2_CID \
+  {0x66bed216, 0x60a3, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTCHILD3_CID \
+  {0x62353978, 0x614e, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTCHILD4_CID \
+  {0xa6d22202, 0x622b, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+#define NS_XPCTESTCHILD5_CID \
+  {0xba3eef4e, 0x6250, 0x11d3, \
+    { 0x82, 0xef, 0x00, 0x60, 0xb0, 0xeb, 0x59, 0x6f }}
+
+// {5B9AF380-6569-11d3-989E-006008962422}
+#define NS_ARRAY_CID \
+{ 0x5b9af380, 0x6569, 0x11d3, \
+    { 0x98, 0x9e, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
+
+// {DB569F7E-16FB-4BCB-A86C-E08AA7F97666}
+#define NS_XPCTESTDOMSTRING_CID \
+  {0xdb569f7e, 0x16fb, 0x1bcb, \
+    { 0xa8, 0x6c, 0xe0, 0x8a, 0xa7, 0xf9, 0x76, 0x66 }}
+
+// {DC932D30-95B0-11d5-90FC-0010A4E73D9A}
+#define NS_XPCTESTVARIANT_CID \
+  {0xdc932d30, 0x95b0, 0x11d5, \
+    { 0x90, 0xfc, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a }}
+
+// 'namespace' class
+class xpctest
+{
+public:
+  static nsresult ConstructEcho(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructChild(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructNoisy(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructStringTest(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructOverloaded(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestObjectReadOnly(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestObjectReadWrite(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestIn(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestOut(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestInOut(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestConst(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestCallJS(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestParentOne(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestParentTwo(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestChild2(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestChild3(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestChild4(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestChild5(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructArrayTest(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestDOMString(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+  static nsresult ConstructXPCTestVariant(nsISupports *aOuter, REFNSIID aIID, void **aResult);
+
+private:
+    xpctest();  // not implemented
+};
+
+#endif /* xpctest_private_h___ */
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_string.cpp
@@ -0,0 +1,185 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* implement nsIXPCTestString for testing. */
+
+#include "xpctest_private.h"
+
+class xpcstringtest : public nsIXPCTestString
+{
+public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIXPCTESTSTRING
+
+    xpcstringtest();
+    virtual ~xpcstringtest();
+};
+
+xpcstringtest::xpcstringtest()
+{
+    NS_ADDREF_THIS();
+}
+
+xpcstringtest::~xpcstringtest()
+{
+}
+
+NS_IMPL_ISUPPORTS1(xpcstringtest, nsIXPCTestString)
+
+/* string GetStringA (); */
+NS_IMETHODIMP
+xpcstringtest::GetStringA(char **_retval)
+{
+    const char myResult[] = "result of xpcstringtest::GetStringA";
+
+    if(!_retval)
+        return NS_ERROR_NULL_POINTER;
+
+    *_retval = (char*) nsMemory::Clone(myResult,
+                                          sizeof(char)*(strlen(myResult)+1));
+    return *_retval ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+/* void GetStringB (out string s); */
+NS_IMETHODIMP
+xpcstringtest::GetStringB(char **s)
+{
+    const char myResult[] = "result of xpcstringtest::GetStringB";
+
+    if(!s)
+        return NS_ERROR_NULL_POINTER;
+
+    *s = (char*) nsMemory::Clone(myResult,
+                                    sizeof(char)*(strlen(myResult)+1));
+
+    return *s ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+
+/* void GetStringC ([shared, retval] out string s); */
+NS_IMETHODIMP
+xpcstringtest::GetStringC(const char **s)
+{
+    static const char myResult[] = "result of xpcstringtest::GetStringC";
+    if(!s)
+        return NS_ERROR_NULL_POINTER;
+    *s = myResult;
+    return NS_OK;
+}
+
+// quick and dirty!!!
+static PRUnichar* GetTestWString(int* size)
+{
+    static PRUnichar* sWStr;            
+    static char str[] = "This is part of a long string... ";
+    static const int slen = (sizeof(str)-1)/sizeof(char);
+    static const int rep = 1;
+    static const int space = (slen*rep*sizeof(PRUnichar))+sizeof(PRUnichar);
+
+    if(!sWStr)
+    {
+        sWStr = (PRUnichar*) nsMemory::Alloc(space);
+        if(sWStr)
+        {
+            PRUnichar* p = sWStr;
+            for(int k = 0; k < rep; k++)
+                for (int i = 0; i < slen; i++)
+                    *(p++) = (PRUnichar) str[i];
+        *p = 0;        
+        }
+    }
+    if(size)
+        *size = space;
+    return sWStr;
+}        
+
+/* void GetWStringCopied ([retval] out wstring s); */
+NS_IMETHODIMP xpcstringtest::GetWStringCopied(PRUnichar **s)
+{
+    if(!s)
+        return NS_ERROR_NULL_POINTER;
+
+    int size;
+    PRUnichar* str = GetTestWString(&size);
+    if(!str)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    *s = (PRUnichar*) nsMemory::Clone(str, size);
+    return *s ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}        
+
+/* void GetWStringShared ([shared, retval] out wstring s); */
+NS_IMETHODIMP xpcstringtest::GetWStringShared(const PRUnichar **s)
+{
+    if(!s)
+        return NS_ERROR_NULL_POINTER;
+    *s = GetTestWString(nsnull);
+    return NS_OK;
+}        
+
+/***************************************************************************/
+
+// static
+nsresult
+xpctest::ConstructStringTest(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    xpcstringtest* obj = new xpcstringtest();
+
+    if(obj)
+    {
+        rv = obj->QueryInterface(aIID, aResult);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+        NS_RELEASE(obj);
+    }
+    else
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    return rv;
+}
+/***************************************************************************/
+
+
+
+
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/components/xpctest_variant.cpp
@@ -0,0 +1,355 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* implement nsITestVariant for testing. */
+
+#include "xpctest_private.h"
+#include "nsString.h"
+
+class nsTestVariant : public nsITestVariant
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSITESTVARIANT
+
+  nsTestVariant();
+  virtual ~nsTestVariant();
+};
+
+NS_IMPL_ISUPPORTS1(nsTestVariant, nsITestVariant)
+
+nsTestVariant::nsTestVariant()
+{
+}
+
+nsTestVariant::~nsTestVariant()
+{
+}
+
+/* nsIVariant passThruVariant (in nsIVariant value); */
+NS_IMETHODIMP nsTestVariant::PassThruVariant(nsIVariant *value, nsIVariant **_retval)
+{
+    *_retval = value;
+    NS_IF_ADDREF(*_retval);
+    return NS_OK;
+}
+
+/* PRUint16 returnVariantType (in nsIVariant value); */
+NS_IMETHODIMP nsTestVariant::ReturnVariantType(nsIVariant *value, PRUint16 *_retval)
+{
+    return value->GetDataType(_retval);
+}
+
+#define MEMBER_COPY(type_)                                                    \
+    rv = inVar->GetAs##type_(&du.u.m##type_##Value);                          \
+    if(NS_FAILED(rv)) return rv;                                              \
+    rv = outVar->SetAs##type_(du.u.m##type_##Value);                          \
+    NS_ENSURE_SUCCESS(rv,rv);
+
+#define MEMBER_COPY_CAST(type_, cast_)                                        \
+    rv = inVar->GetAs##type_( (cast_*) &du.u.m##type_##Value);                \
+    if(NS_FAILED(rv)) return rv;                                              \
+    rv = outVar->SetAs##type_( (cast_) du.u.m##type_##Value);                 \
+    NS_ENSURE_SUCCESS(rv,rv);
+
+static nsresult ConvertAndCopyVariant(nsIVariant *inVar, PRUint16 type, nsIVariant **_retval)
+{
+    nsresult rv;
+    
+    nsCOMPtr<nsIWritableVariant> outVar;
+    outVar = do_CreateInstance("@mozilla.org/variant;1");
+    if(!outVar)
+        return NS_ERROR_FAILURE;
+
+    PRUint16 inVarType;
+    rv = inVar->GetDataType(&inVarType);
+    if(NS_FAILED(rv))
+        return rv;
+
+    nsDiscriminatedUnion du;
+    nsVariant::Initialize(&du);
+
+    switch(type)
+    {
+    case nsIDataType::VTYPE_INT8:
+        MEMBER_COPY_CAST(Int8, PRUint8)
+        break;
+    case nsIDataType::VTYPE_INT16:
+        MEMBER_COPY(Int16)
+        break;
+    case nsIDataType::VTYPE_INT32:        
+        MEMBER_COPY(Int32)
+        break;
+    case nsIDataType::VTYPE_INT64:        
+        MEMBER_COPY(Int64)
+        break;
+    case nsIDataType::VTYPE_UINT8:        
+        MEMBER_COPY(Uint8)
+        break;
+    case nsIDataType::VTYPE_UINT16:        
+        MEMBER_COPY(Uint16)
+        break;
+    case nsIDataType::VTYPE_UINT32:        
+        MEMBER_COPY(Uint32)
+        break;
+    case nsIDataType::VTYPE_UINT64:        
+        MEMBER_COPY(Uint64)
+        break;
+    case nsIDataType::VTYPE_FLOAT:        
+        MEMBER_COPY(Float)
+        break;
+    case nsIDataType::VTYPE_DOUBLE:        
+        MEMBER_COPY(Double)
+        break;
+    case nsIDataType::VTYPE_BOOL:        
+        MEMBER_COPY(Bool)
+        break;
+    case nsIDataType::VTYPE_CHAR:        
+        MEMBER_COPY(Char)
+        break;
+    case nsIDataType::VTYPE_WCHAR:        
+        MEMBER_COPY(WChar)
+        break;
+    case nsIDataType::VTYPE_VOID:        
+        if(inVarType != nsIDataType::VTYPE_VOID)
+            return NS_ERROR_CANNOT_CONVERT_DATA;
+        rv = outVar->SetAsVoid();
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    case nsIDataType::VTYPE_ID:        
+        MEMBER_COPY(ID)
+        break;
+    case nsIDataType::VTYPE_ASTRING:        
+    case nsIDataType::VTYPE_DOMSTRING:
+    {
+        nsAutoString str;
+        rv = inVar->GetAsAString(str);
+        if(NS_FAILED(rv)) return rv;
+        rv = outVar->SetAsAString(str);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    }
+    case nsIDataType::VTYPE_UTF8STRING:
+    {
+        nsUTF8String str;
+        rv = inVar->GetAsAUTF8String(str);
+        if(NS_FAILED(rv)) return rv;
+        rv = outVar->SetAsAUTF8String(str);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    }
+    case nsIDataType::VTYPE_CSTRING:
+    {
+        nsCAutoString str;
+        rv = inVar->GetAsACString(str);
+        if(NS_FAILED(rv)) return rv;
+        rv = outVar->SetAsACString(str);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    }    
+    case nsIDataType::VTYPE_CHAR_STR:        
+    {
+        char* str;
+        rv = inVar->GetAsString(&str);
+        if(NS_FAILED(rv)) return rv;
+        rv = outVar->SetAsString(str);
+        if(str) nsMemory::Free(str);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    }
+    case nsIDataType::VTYPE_STRING_SIZE_IS:        
+    {
+        char* str;
+        PRUint32 size;
+        rv = inVar->GetAsStringWithSize(&size, &str);
+        if(NS_FAILED(rv)) return rv;
+        rv = outVar->SetAsStringWithSize(size, str);
+        if(str) nsMemory::Free(str);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    }
+    case nsIDataType::VTYPE_WCHAR_STR:        
+    {
+        PRUnichar* str;
+        rv = inVar->GetAsWString(&str);
+        if(NS_FAILED(rv)) return rv;
+        rv = outVar->SetAsWString(str);
+        if(str) nsMemory::Free((char*)str);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    }
+    case nsIDataType::VTYPE_WSTRING_SIZE_IS:        
+    {
+        PRUnichar* str;
+        PRUint32 size;
+        rv = inVar->GetAsWStringWithSize(&size, &str);
+        if(NS_FAILED(rv)) return rv;
+        rv = outVar->SetAsWStringWithSize(size, str);
+        if(str) nsMemory::Free((char*)str);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    }
+    case nsIDataType::VTYPE_INTERFACE:        
+    {
+        nsISupports* ptr;
+        rv = inVar->GetAsISupports(&ptr);
+        if(NS_FAILED(rv)) return rv;
+        rv = outVar->SetAsISupports(ptr);
+        NS_IF_RELEASE(ptr);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    }
+    case nsIDataType::VTYPE_INTERFACE_IS:        
+    {
+        nsISupports* ptr;
+        nsIID* iid;
+        rv = inVar->GetAsInterface(&iid, (void**)&ptr);
+        if(NS_FAILED(rv)) return rv;
+        rv = outVar->SetAsInterface(*iid, ptr);
+        NS_IF_RELEASE(ptr);
+        if(iid) nsMemory::Free((char*)iid);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    }
+        break;
+    case nsIDataType::VTYPE_ARRAY:
+        rv = inVar->GetAsArray(&du.u.array.mArrayType,
+                               &du.u.array.mArrayInterfaceID,
+                               &du.u.array.mArrayCount,
+                               &du.u.array.mArrayValue);
+        if(NS_FAILED(rv)) return rv;
+        du.mType = type;
+        rv = outVar->SetAsArray(du.u.array.mArrayType,
+                                &du.u.array.mArrayInterfaceID,
+                                du.u.array.mArrayCount,
+                                du.u.array.mArrayValue);
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    case nsIDataType::VTYPE_EMPTY_ARRAY:
+        if(inVarType != nsIDataType::VTYPE_EMPTY_ARRAY)
+            return NS_ERROR_CANNOT_CONVERT_DATA;
+        rv = outVar->SetAsEmptyArray();
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;        
+    case nsIDataType::VTYPE_EMPTY:
+        if(inVarType != nsIDataType::VTYPE_EMPTY)
+            return NS_ERROR_CANNOT_CONVERT_DATA;
+        rv = outVar->SetAsEmpty();
+        NS_ENSURE_SUCCESS(rv,rv);
+        break;
+    default:
+        NS_ERROR("bad type in variant!");
+        break;
+    }
+
+    nsVariant::Cleanup(&du);
+    *_retval = outVar;
+    NS_IF_ADDREF(*_retval);
+    return NS_OK;
+}        
+
+
+/* nsIVariant copyVariant (in nsIVariant value); */
+NS_IMETHODIMP nsTestVariant::CopyVariant(nsIVariant *value, nsIVariant **_retval)
+{
+    PRUint16 type;
+    if(NS_FAILED(value->GetDataType(&type)))
+        return NS_ERROR_FAILURE;
+    return ConvertAndCopyVariant(value, type, _retval);
+}
+
+/* nsIVariant copyVariantAsType (in nsIVariant value, in PRUint16 type); */
+NS_IMETHODIMP nsTestVariant::CopyVariantAsType(nsIVariant *value, PRUint16 type, nsIVariant **_retval)
+{
+    return ConvertAndCopyVariant(value, type, _retval);
+}
+
+/* nsIVariant copyVariantAsTypeTwice (in nsIVariant value, in PRUint16 type1, in PRUint16 type2); */
+NS_IMETHODIMP nsTestVariant::CopyVariantAsTypeTwice(nsIVariant *value, PRUint16 type1, PRUint16 type2, nsIVariant **_retval)
+{
+    nsCOMPtr<nsIVariant> temp;
+    nsresult rv = ConvertAndCopyVariant(value, type1, getter_AddRefs(temp));
+    if(NS_FAILED(rv))
+        return rv;
+    return ConvertAndCopyVariant(temp, type2, _retval);
+}
+
+/* nsIVariant getNamedProperty (in nsISupports aBag, in AString aName); */
+NS_IMETHODIMP nsTestVariant::GetNamedProperty(nsISupports *aObj, const nsAString & aName, nsIVariant **_retval)
+{
+    nsresult rv;
+    nsCOMPtr<nsIPropertyBag> bag = do_QueryInterface(aObj, &rv);
+    if(!bag)
+        return rv;
+    return bag->GetProperty(aName, _retval);
+}
+
+/* nsISimpleEnumerator getEnumerator (in nsISupports aBag); */
+NS_IMETHODIMP nsTestVariant::GetEnumerator(nsISupports *aObj, nsISimpleEnumerator **_retval)
+{
+    nsresult rv;
+    nsCOMPtr<nsIPropertyBag> bag = do_QueryInterface(aObj, &rv);
+    if(!bag)
+        return rv;
+    return bag->GetEnumerator(_retval);
+}
+
+/***************************************************************************/
+
+// static
+nsresult
+xpctest::ConstructXPCTestVariant(nsISupports *aOuter, REFNSIID aIID, void **aResult)
+{
+    nsresult rv;
+    NS_ASSERTION(aOuter == nsnull, "no aggregation");
+    nsTestVariant* obj = new nsTestVariant();
+
+    if(!obj)
+    {
+        *aResult = nsnull;
+        rv = NS_ERROR_OUT_OF_MEMORY;
+    }
+
+    NS_ADDREF(obj);
+    rv = obj->QueryInterface(aIID, aResult);
+    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
+    NS_RELEASE(obj);
+    return rv;
+}
--- a/js/src/xpconnect/tests/idl/Makefile.in
+++ b/js/src/xpconnect/tests/idl/Makefile.in
@@ -31,27 +31,31 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
-DEPTH = ../../../../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
+DEPTH		= ../../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = xpctest
+MODULE		= xpconnect_tests
 
-XPIDLSRCS = \
-  xpctest_attributes.idl \
-  xpctest_params.idl \
-  $(NULL)
+XPIDLSRCS	= \
+		xpctest.idl \
+		xpctest2.idl \
+		xpctest_attributes.idl \
+		xpctest_calljs.idl \
+		xpctest_const.idl \
+		xpctest_in.idl \
+		xpctest_inout.idl \
+		xpctest_multiple.idl \
+		xpctest_domstring.idl \
+		xpctest_out.idl \
+		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
-
-componentdir = js/src/xpconnect/tests/components
-libs:: $(XPIDL_GEN_DIR)/$(MODULE).xpt
-	$(INSTALL) $^ $(testxpcobjdir)/$(componentdir)
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/idl/xpctest.idl
@@ -0,0 +1,312 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+#include "xpcexception.idl"
+#include "nsIVariant.idl"
+#include "nsIPropertyBag.idl"
+
+// forward declaration (to test that such things work)
+interface nsITestXPCSomeUselessThing;
+
+// Note the use of [function] for this scriptable function callback declaration
+[scriptable, function, uuid(4407fc90-1e41-11d5-909d-0010a4e73d9a)]
+interface nsITestXPCFunctionCallback : nsISupports {
+    void call(in string s);
+    void callWithThis(in nsISupports self, in string s);
+};
+
+[scriptable, uuid(159E36D0-991E-11d2-AC3F-00C09300144B)]
+interface nsITestXPCFoo : nsISupports {
+    long Test(in long p1, in long p2);
+    void Test2();
+
+    attribute string Foo;
+
+    const short one = 1;
+    const short five = 5;
+    const short six = 6;
+};
+
+[scriptable, uuid(5F9D20C0-9B6B-11d2-9FFE-000064657374)]
+interface nsITestXPCFoo2 : nsITestXPCFoo {
+};
+
+[scriptable, uuid(CD2F2F40-C5D9-11d2-9838-006008962422)]
+interface nsIEcho : nsISupports {
+    void SetReceiver(in nsIEcho aReceiver);
+    void SendOneString(in string str);
+    long In2OutOneInt(in long input);
+
+    long In2OutAddTwoInts(in  long input1,  in  long input2,
+                          out long output1, out long output2);
+
+    string In2OutOneString(in string input);
+
+    DOMString In2OutOneDOMString(in DOMString input);
+    DOMString EchoIn2OutOneDOMString(in DOMString input);
+
+    AString In2OutOneAString(in AString input);
+    AString EchoIn2OutOneAString(in AString input);
+
+    AUTF8String In2OutOneUTF8String(in AUTF8String input);
+    AUTF8String EchoIn2OutOneUTF8String(in AUTF8String input);
+
+    ACString In2OutOneCString(in ACString input);
+    ACString EchoIn2OutOneCString(in ACString input);
+
+    void SimpleCallNoEcho();
+    void SendManyTypes(in octet                 p1,
+                       in short                 p2,
+                       in long                  p3,
+                       in long long             p4,
+                       in octet                 p5,
+                       in unsigned short        p6,
+                       in unsigned long         p7,
+                       in unsigned long long    p8,
+                       in float                 p9,
+                       in double                p10,
+                       in boolean               p11,
+                       in char                  p12,
+                       in wchar                 p13,
+                       in nsIDPtr               p14,
+                       in string                p15,
+                       in wstring               p16);
+
+    void SendInOutManyTypes(inout octet                 p1,
+                            inout short                 p2,
+                            inout long                  p3,
+                            inout long long             p4,
+                            inout octet                 p5,
+                            inout unsigned short        p6,
+                            inout unsigned long         p7,
+                            inout unsigned long long    p8,
+                            inout float                 p9,
+                            inout double                p10,
+                            inout boolean               p11,
+                            inout char                  p12,
+                            inout wchar                 p13,
+                            inout nsIDPtr               p14,
+                            inout string                p15,
+                            inout wstring               p16);
+
+    [noscript] void MethodWithNative(in long p1, in voidPtr p2);
+    void ReturnCode(in long code);
+    void FailInJSTest(in long fail);
+    void SharedString([retval, shared] out string str);
+
+    void ReturnCode_NS_OK();
+    void ReturnCode_NS_ERROR_NULL_POINTER();
+    void ReturnCode_NS_ERROR_UNEXPECTED();
+    void ReturnCode_NS_ERROR_OUT_OF_MEMORY();
+
+    nsISupports ReturnInterface(in nsISupports obj);
+
+    nsIStackFrame GetStack();
+    void SetReceiverReturnOldReceiver(inout nsIEcho aReceiver);
+
+    void MethodWithForwardDeclaredParam(in nsITestXPCSomeUselessThing sut);
+
+    void PseudoQueryInterface(in nsIIDRef uuid, 
+                              [iid_is(uuid),retval] out nsQIResult result);
+
+    void DebugDumpJSStack();
+
+    void printArgTypes(/* optional params */);
+    void throwArg(/* optional param */);
+
+    void callReceiverSometimeLater();
+
+    readonly attribute short throwInGetter;
+
+    attribute string aString;
+    attribute PRInt32 SomeValue;
+
+    const short one = 1;
+    const short five = 5;
+    const short six = 6;
+    const PRUint32 medium = 12345;
+    const PRUint32 big = 0xFFFFFFFF;
+
+    void callFunction(in nsITestXPCFunctionCallback callback, in string s);
+    void callFunctionWithThis(in nsITestXPCFunctionCallback callback, 
+                              in nsISupports self, in string s);
+};
+
+/***************************************************************************/
+
+[scriptable, uuid(83849a30-0d6e-11d3-bab8-00805f8a5dd7)]
+interface nsIXPCTestParent : nsISupports {
+    void method1(in short i);
+    void method1a(in nsIXPCTestParent foo);
+};
+
+[scriptable, uuid(9ddf0f00-0d6e-11d3-bab8-00805f8a5dd7)]
+interface nsIXPCTestChild : nsIXPCTestParent {
+    void method2(in short i, in short j);
+};
+
+[scriptable, uuid(7bca65e0-0d73-11d3-bab8-00805f8a5dd7)]
+interface nsIXPCTestOther : nsISupports {
+    void method3(in short i, in short j, in short k);
+};
+
+[scriptable, uuid(1e4cf7b0-237a-11d3-9879-006008962422)]
+interface nsIXPCTestNoisy : nsISupports {
+    void squawk();
+};
+
+[scriptable, uuid(d970e910-30d8-11d3-9885-006008962422)]
+interface nsIXPCTestString : nsISupports {
+    string GetStringA();
+    void GetStringB(out string s);
+    void GetStringC([shared,retval] out string s);
+
+    void GetWStringCopied([retval] out wstring s);
+    void GetWStringShared([shared,retval] out wstring s);
+};
+
+[scriptable, uuid(0ff4faf0-439a-11d3-988c-006008962422)]
+interface nsIXPCTestOverloaded : nsISupports {
+    void Foo1(in PRInt32 p1);
+    void Foo2(in PRInt32 p1, in PRInt32 p2);
+};
+
+[scriptable, uuid(3d2e64b0-6552-11d3-989e-006008962422)]
+interface nsIXPCTestArray : nsISupports {
+
+    void SetReceiver(in nsIXPCTestArray aReceiver);
+
+    void PrintIntegerArray(in PRUint32 count, 
+                           [array, size_is(count)] in PRInt32 valueArray);
+    void PrintStringArray(in PRUint32 count, 
+                          [array, size_is(count)] in string valueArray);
+    void MultiplyEachItemInIntegerArray(
+                           in PRInt32 val, 
+                           in PRUint32 count, 
+                           [array, size_is(count)] inout PRInt32 valueArray);
+    void MultiplyEachItemInIntegerArrayAndAppend(
+                           in PRInt32 val, 
+                           inout PRUint32 count, 
+                           [array, size_is(count)] inout PRInt32 valueArray);
+
+    void CallEchoMethodOnEachInArray(inout nsIIDPtr uuid, 
+                                     inout PRUint32 count, 
+       [array, size_is(count), iid_is(uuid)] inout nsQIResult result);
+
+    void CallEchoMethodOnEachInArray2(inout PRUint32 count, 
+       [array, size_is(count)] inout nsIEcho result);
+
+    void DoubleStringArray(inout PRUint32 count, 
+                           [array, size_is(count)] inout string valueArray);
+    void ReverseStringArray(in PRUint32 count, 
+                            [array, size_is(count)] inout string valueArray);
+
+    void PrintStringWithSize(in PRUint32 count, 
+                             [size_is(count)] in string str);
+    void DoubleString(inout PRUint32 count, 
+                      [size_is(count)] inout string str);
+
+    void GetStrings(out PRUint32 count,
+                    [retval, array, size_is(count)] out string str);
+
+};
+
+[scriptable, uuid(13082da0-643c-11d4-8fe0-0010a4e73d9a)]
+interface nsIWrappedJSObjectTest : nsISupports
+{
+    void interfaceMember();        
+};
+
+[scriptable, uuid(41d923d0-5bc1-11d5-90db-0010a4e73d9a)]
+interface nsIBogus1 : nsISupports {};
+
+[scriptable, uuid(8d8f4210-5bc1-11d5-90db-0010a4e73d9a)]
+interface nsIBogus2 : nsISupports 
+{
+    attribute nsIBogus1 bogus;
+};
+
+[scriptable, uuid(34bc9990-95af-11d5-90fc-0010a4e73d9a)]
+interface nsITestVariant : nsISupports
+{
+    /**
+     * Just return the variant that was passed in.
+     */
+    nsIVariant passThruVariant(in nsIVariant value);
+    
+    /**
+     * Just return the type of the passed in variant.
+     */
+    PRUint16   returnVariantType(in nsIVariant value);
+    
+    /**
+     * Construct and return a default xpcom variant instance using the
+     * value of the passed in variant. Use the type of the passed in variant. 
+     */
+    nsIVariant copyVariant(in nsIVariant value);
+    
+    /**
+     * Construct and return a default xpcom variant instance using the
+     * value of the passed in variant. Use the type as specified to get data 
+     * from the passed in variant. 
+     */
+    nsIVariant copyVariantAsType(in nsIVariant value, in PRUint16 type);
+    
+    /**
+     * Construct a default xpcom variant instance using the
+     * value of the passed in variant. Use the type as specified in type1 to 
+     * get data from the passed in variant. Then construct and return a default
+     * xpcom variant based on that object using the type2. This allows for 
+     * testing all the 'ConvertTo*' methods on the default xpcom variant class.
+     */
+    nsIVariant copyVariantAsTypeTwice(in nsIVariant value, 
+                                      in PRUint16 type1, in PRUint16 type2);
+
+    /**
+     * Get a named property from object that will be QI'd to nsIPropertyBag.
+     */
+    nsIVariant getNamedProperty(in nsISupports aBag, in AString aName);
+
+    /**
+     * Get a enumerator from object that will be QI'd to nsIPropertyBag.
+     */
+    nsISimpleEnumerator getEnumerator(in nsISupports aBag);
+};
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/idl/xpctest2.idl
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+// This is a test it is only a test.
+// This was forward declared in xtestpxc.idl. But this file is *not* included.
+
+[scriptable, uuid(e8fc0860-3bb1-11d3-988a-006008962422)]
+interface nsITestXPCSomeUselessThing : nsISupports
+{
+    /* empty */
+};
+
--- a/js/src/xpconnect/tests/idl/xpctest_attributes.idl
+++ b/js/src/xpconnect/tests/idl/xpctest_attributes.idl
@@ -39,27 +39,29 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 /*
  *	This defines the interface for a test object.
  *
  */
 
-[scriptable, uuid(29e950a0-0134-44bc-b947-5e0ee95c8f7e)]
+[scriptable, uuid(1364941e-4462-11d3-82ee-0060b0eb596f)]
 interface nsIXPCTestObjectReadOnly : nsISupports {
 	readonly attribute string  strReadOnly;
 	readonly attribute boolean boolReadOnly;
 	readonly attribute short   shortReadOnly;
 	readonly attribute long    longReadOnly;
 	readonly attribute float   floatReadOnly;
 	readonly attribute char    charReadOnly;
+
+	string getID();
 };
 
-[scriptable, uuid(492609a7-2582-436b-b0ef-92e29bb9e143)]
+[scriptable, uuid(3b9b1d38-491a-11d3-82ef-0060b0eb596f)]
 interface nsIXPCTestObjectReadWrite : nsISupports {
 	attribute string  stringProperty;
 	attribute boolean booleanProperty;
 	attribute short   shortProperty;
 	attribute long    longProperty;
 	attribute float   floatProperty;
 	attribute char    charProperty;
 };
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/idl/xpctest_calljs.idl
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *  Test that calls a JavaScript object's methods and gets and
+ *	sets property values.
+ */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(38ba7d98-5a54-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestCallJS : nsISupports
+{
+	boolean CallMethodNoArgs();
+	void Evaluate( in string s );
+	nsresult EvaluateAndReturnError( in nsresult s );
+	void SetJSObject( in nsIXPCTestCallJS o );
+	void EvaluateAndEatErrors( in string s);
+	[noscript] void UnscriptableMethod();
+};
+
+
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/idl/xpctest_const.idl
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This describes an interface for objects withconst attributes of 
+ * different types and uses expressions to generate const values.
+ * | ^ & >> << + - * / % and unary - +
+ * scoped literals
+ */
+
+#include "nsISupports.idl"
+#include "nsrootidl.idl"
+
+/**
+ *	Only consts of type short and long are respected.
+ */
+
+[scriptable, uuid(83f57a56-4f55-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestConst : nsISupports {
+
+	const short              shortConst   = 254;
+	const long               longConst    = 1234567890;
+};
+
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/idl/xpctest_domstring.idl
@@ -0,0 +1,59 @@
+/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mike Shaver <shaver@mozilla.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+/**
+ * Interface for testing the DOMString-conversion infrastructure.
+ */
+
+[scriptable, uuid(646d0b6b-6872-43b9-aa73-3c6b89ac3080)]
+interface nsIXPCTestDOMString : nsISupports {
+    // Implementation should ask for the shared buffer interface and hold
+    // a refcount to it.
+    void hereHaveADOMString(in DOMString str);
+
+    // don't hold onto this one
+    void dontKeepThisOne(in DOMString str);
+    
+    void giveDOMStringTo(in nsIXPCTestDOMString recv);
+
+    void passDOMStringThroughTo(in DOMString str, in nsIXPCTestDOMString recv);
+};
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/idl/xpctest_in.idl
@@ -0,0 +1,88 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *	Test the 'in' keyword.
+ */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(a3cab49d-ae83-4e63-a735-009b9a759204)]
+interface nsIXPCTestIn : nsISupports {
+	long    EchoLong( in long l);
+	short   EchoShort( in short a );
+	char	EchoChar( in char c );
+	boolean EchoBoolean( in boolean b );
+	octet   EchoOctet( in octet o );
+	long long EchoLongLong( in long long ll );
+	unsigned short EchoUnsignedShort( in unsigned short us );
+	unsigned long  EchoUnsignedLong(  in unsigned long ul );
+	float  EchoFloat( in float f );
+	double EchoDouble( in double d );
+	wchar  EchoWchar ( in wchar wc );
+	wstring EchoString( in wstring ws );
+
+	PRBool  EchoPRBool( in PRBool b );
+	PRInt32 EchoPRInt32( in PRInt32 l );
+	PRInt16 EchoPRInt16( in PRInt16 l );
+	PRInt64 EchoPRInt64( in PRInt64 i );
+	PRUint8 EchoPRUint8( in PRUint8 i );
+	PRUint16 EchoPRUint16( in PRUint16 i );
+	PRUint32 EchoPRUint32( in PRUint32 i );
+	PRUint32 EchoPRUint32_2( in PRUint32 i );
+	PRUint64 EchoPRUint64( in PRUint64 i );
+	
+	// native types must be marked noscript or they break the idl
+	// compiler
+
+	[noscript] voidPtr EchoVoidPtr( in voidPtr vs );
+	[noscript] charPtr EchoCharPtr( in charPtr cs );
+/*
+	[noscript] voidRef EchoVoidRef( in voidRef vf );
+	[noscript] nsIDRef EchoNsIDRef( in nsIDRef r );
+	[noscript] nsCIDRef EchoNsCIDRef( in nsCIDRef r );
+
+	[noscript] nsIDPtr EchoNsIDPtr( in nsIDPtr p );
+	[noscript] nsIIDPtr EchoNsIIDPtr( in nsIIDPtr p );
+	[noscript] nsCIDPtr EchoNsCIDPtr( in nsCIDPtr p );
+	[noscript] nsQIResult EchoNsQIResult( in nsQIResult r );
+*/
+	void EchoVoid();
+};
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/idl/xpctest_inout.idl
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *	Test the 'inout' keyword.
+ */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(626dc196-5599-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestInOut : nsISupports {
+	void EchoLong( in long li, out long lo);
+	void EchoShort( in short si, out short so );
+	void EchoChar( in char ci, out char co );
+	void EchoBoolean( in boolean bi, out boolean bo );
+	void EchoOctet( in octet oi, out octet oo );
+	void EchoLongLong( in long long lli, out long long llo );
+	void EchoUnsignedShort( in unsigned short usi, out unsigned short uso );
+	void EchoUnsignedLong(  in unsigned long uli, out unsigned long ulo);
+	void EchoFloat( in float fi, out float fo);
+	void EchoDouble( in double di, out double dout );
+	void EchoWchar ( in wchar wci, out wchar wco );
+	void EchoString( in wstring wsi, out wstring wso );
+	void EchoPRBool( in PRBool bi, out PRBool bo );
+	void EchoPRInt32( in PRInt32 li, out PRInt32 lo );
+	void EchoPRInt16( in PRInt16 li, out PRInt16 lo );
+	void EchoPRInt64( in PRInt64 ii, out PRInt64 io );
+	void EchoPRUint8( in PRUint8 ii, out PRUint8 io );
+	void EchoPRUint16( in PRUint16 ii, out PRUint16 io );
+	void EchoPRUint32( in PRUint32 ii, out PRUint32 io );
+	void EchoPRUint32_2( in PRUint32 ii, out PRUint32 io );
+	void EchoPRUint64( in PRUint64 ii, out PRUint64 io );
+	
+	// native types must be marked noscript or they break the idl
+	// compiler
+
+	[noscript] void EchoVoidPtr( in voidPtr vsi, out voidPtr vso );
+	[noscript] void EchoCharPtr( in charPtr csi, out charPtr cso );
+	//[noscript] void EchoVoidRef( in voidRef vfi, out voidRef vfo );
+	//[noscript] void EchoNsIDRef( in nsIDRef ri, out nsIDRef ro );
+	//[noscript] void EchoNsCIDRef( in nsCIDRef ri, out nsCIDRef ro );
+
+	[noscript] void EchoNsIDPtr( in nsIDPtr pi, out nsIDPtr po );
+	[noscript] void EchoNsIIDPtr( in nsIIDPtr pi, out nsIIDPtr po );
+	[noscript] void EchoNsCIDPtr( in nsCIDPtr pi, out nsCIDPtr po );
+	[noscript] void EchoNsQIResult( in nsQIResult ri, out nsQIResult ro );
+
+	void EchoVoid();
+};
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/idl/xpctest_multiple.idl
@@ -0,0 +1,77 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(5408fdcc-60a3-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestParentOne : nsISupports {
+	attribute string ParentOneAttribute;
+	string ParentOneMethod();
+};
+
+[scriptable, uuid(63137392-60a3-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestParentTwo : nsISupports {
+	attribute string ParentTwoAttribute;
+	string ParentTwoMethod();
+};
+
+[scriptable, uuid(66bed216-60a3-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestChild2 : nsISupports {
+	attribute string ChildAttribute;
+	string ChildMethod();
+};
+
+[scriptable, uuid(62353978-614e-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestChild3 : nsIXPCTestParentOne {
+	attribute string ChildAttribute;
+	string ChildMethod();
+};
+
+[scriptable, uuid(a6d22202-622b-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestChild4 : nsISupports {
+	attribute string ChildAttribute;
+	string ChildMethod();
+};
+
+[scriptable, uuid(ba3eef4e-6250-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestChild5 : nsIXPCTestParentOne {
+	attribute string ChildAttribute;
+	string ChildMethod();
+};
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/idl/xpctest_out.idl
@@ -0,0 +1,142 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   John Bandhauer <jband@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *	Test the 'out' keyword.
+ */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(4105ae88-5599-11d3-82ef-0060b0eb596f)]
+interface nsIXPCTestOut : nsISupports {
+	void GetLong( out long l);
+	void SetLong( in long l );
+
+	void GetShort( out short s );
+	void SetShort( in short s );
+
+	void SetChar( in char c );
+	void GetChar( out char c);
+
+	void GetBoolean( out boolean b );
+	void SetBoolean( in boolean b );
+
+	void GetOctet( out octet o );
+	void SetOctet( in octet o );
+
+	void GetLongLong( out long long ll );
+	void SetLongLong( in long long ll );
+
+	void GetUnsignedShort( out unsigned short us );
+	void SetUnsignedShort( in unsigned short us );
+
+	void GetUnsignedLong( out unsigned long ul );
+	void SetUnsignedLong(  in unsigned long ul );
+
+	void GetFloat( out float f );
+	void SetFloat( in float f );
+
+	void GetDouble( out double d );
+	void SetDouble( in double d );
+
+	void GetWchar( out wchar wc );
+	void SetWchar ( in wchar wc );
+
+	//void GetString( out wstring ws );
+	//void SetString( in wstring ws );
+
+	void GetPRBool( out PRBool b );
+	void SetPRBool (in PRBool b );
+
+	void GetPRInt32( out PRInt32 l );
+	void SetPRInt32( in PRInt32 l );
+
+	void GetPRInt16( out PRInt16 l );
+	void SetPRInt16( in PRInt16 l );
+
+	void GetPRInt64( out PRInt64 i );
+	void SetPRInt64( in PRInt64 i );
+
+	void GetPRUint8 ( out PRUint8 i );
+	void SetPRUint8( in PRUint8 i );
+
+	void GetPRUint16( out PRUint16 i );
+	void SetPRUint16( in PRUint16 i );
+
+	void GetPRUint32( out PRUint32 i );
+	void SetPRUint32( in PRUint32 i );
+
+	void GetPRUint64( out PRUint64 i );	
+	void SetPRUint64( in PRUint64 i );
+	
+	// native types must be marked noscript or they break the idl
+	// compiler
+
+//	[noscript] void GetVoidStar( out voidStar vs );
+	//[noscript] void SetVoidStar( in voidStar vs );
+
+	//[noscript] void GetCharStar( out charStar cs );
+	//[noscript] void SetCharStar( in charStar cs );
+
+//	[noscript] void GetVoidRef( out voidRef vf );
+//	[noscript] void SetVoidRef( in voidRef vf );
+
+//	[noscript] void GetNsIDRef( out nsIDRef r );
+//	[noscript] void SetNsIDRef( in nsIDRef r );
+
+//	[noscript] void GetNsCIDRef( out nsCIDRef r );
+//	[noscript] void SetNsCIDRef( in nsCIDRef r );
+/*
+	[noscript] void GetNsIDPtr( out nsIDPtr p );
+	[noscript] void SetNsIDPtr( in nsIDPtr p );
+
+	[noscript] void GetNsIIDPtr( out nsIIDPtr p );
+	[noscript] void SetNsIIDPtr( in nsIIDPtr p );
+
+	[noscript] void GetNsCIDPtr( out nsCIDPtr p );
+	[noscript] void SetNsCIDPtr( in nsCIDPtr p );
+
+	[noscript] void GetNsQIResult( out nsQIResult r );
+	[noscript] void SetNsQIResult( in nsQIResult r );
+
+	void GetVoid();
+	void SetVoid();
+*/
+};
deleted file mode 100644
--- a/js/src/xpconnect/tests/idl/xpctest_params.idl
+++ /dev/null
@@ -1,70 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is XPConnect Test Code.
- *
- * The Initial Developer of the Original Code is The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Bobby Holley <bobbyholley@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/**
- * Test pararameter passing and argument conversion.
- *
- * Each test method returns the value in 'b', and copies 'a' into 'b'. This lets
- * us test return values, in params, and inout params (out params should be
- * covered by the intersection of return values and inout).
- */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(b94cd289-d0df-4d25-8995-facf687d921d)]
-interface nsIXPCTestParams : nsISupports {
-
-  // These types correspond to the ones in typelib.py
-  boolean               testBoolean(in boolean a, inout boolean b);
-  octet                 testOctet(in octet a, inout octet b);
-  short                 testShort(in short a, inout short b);
-  long                  testLong(in long a, inout long b);
-  long long             testLongLong(in long long a, inout long long b);
-  unsigned short        testUnsignedShort(in unsigned short a, inout unsigned short b);
-  unsigned long         testUnsignedLong(in unsigned long a, inout unsigned long b);
-  unsigned long long    testUnsignedLongLong(in unsigned long long a, inout unsigned long long b);
-  float                 testFloat(in float a, inout float b);
-  double                testDouble(in double a, inout float b);
-  char                  testChar(in char a, inout char b);
-  string                testString(in string a, inout string b);
-  wchar                 testWchar(in wchar a, inout wchar b);
-  wstring               testWstring(in wstring a, inout wstring b);
-  DOMString             testDOMString(in DOMString a, inout DOMString b);
-  AString               testAString(in AString a, inout AString b);
-  AUTF8String           testAUTF8String(in AUTF8String a, inout AUTF8String b);
-  ACString              testACString(in ACString a, inout ACString b);
-  jsval                 testJsval(in jsval a, inout jsval b);
-};
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/js/readwriteattributes.js
@@ -0,0 +1,101 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Verify that we can access but not overwrite the values of read-only 
+ * attributes.
+ */
+
+ StartTest( "Read-Write Attributes" );
+
+ /*
+  * These values come from xpctest_attributes.idl and xpctest_attributes.cpp
+  */
+
+ var CONTRACTID = "@mozilla.org/js/xpc/test/ObjectReadWrite;1";
+ var INAME   = Components.interfaces["nsIXPCTestObjectReadWrite"];
+
+ var O = Components.classes[CONTRACTID].createInstance();
+ o = O.QueryInterface( INAME );
+
+
+ AddTestCase( "typeof Components.classes[" + CONTRACTID+"].createInstance()",
+			   "object",
+			   typeof O );
+
+ AddTestCase( "typeof O.QueryInterface[" +INAME+"]",
+			"object",
+			typeof o );
+
+ AddTestCase( "o.booleanProperty", true, o.booleanProperty );
+ AddTestCase( "o.shortProperty", 32767, o.shortProperty );
+ AddTestCase( "o.longProperty", 2147483647, o.longProperty );
+ AddTestCase( "o.charProperty", "X", o.charProperty );
+			  
+ // these we can overwrite
+
+ o.booleanProperty = false;
+ o.shortProperty = -12345;
+ o.longProperty = 1234567890;
+ o.charProperty = "Z";
+
+ AddTestCase( "o.booleanProperty", false, o.booleanProperty );
+ AddTestCase( "o.shortProperty", -12345, o.shortProperty );
+ AddTestCase( "o.longProperty", 1234567890, o.longProperty );
+ AddTestCase( "o.charProperty", "Z", o.charProperty );
+
+ // try assigning values that differ from the expected type to verify
+ // conversion
+ SetAndTestBooleanProperty( false, false );
+ SetAndTestBooleanProperty( 1, true );
+ SetAndTestBooleanProperty( null, false );
+ SetAndTestBooleanProperty( "A", true );
+ SetAndTestBooleanProperty( undefined, false );
+ SetAndTestBooleanProperty( [], true );
+ SetAndTestBooleanProperty( {}, true );
+
+ StopTest();
+
+ function SetAndTestBooleanProperty( newValue, expectedValue ) {
+	 o.booleanProperty = newValue;
+
+	 AddTestCase( "o.booleanProperty = " + newValue +"; o.booleanProperty", 
+				expectedValue, 
+				o.booleanProperty );
+ }
deleted file mode 100644
--- a/js/src/xpconnect/tests/unit/test_attributes.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is XPConnect Test Code.
- *
- * The Initial Developer of the Original Code is The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Bobby Holley <bobbyholley@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-function run_test() {
-
-  // Load the component manifests.
-  Components.manager.autoRegister(do_get_file('../components/native/xpctest.manifest'));
-  Components.manager.autoRegister(do_get_file('../components/js/xpctest.manifest'));
-
-  // Test for each component.
-  test_component_readwrite("@mozilla.org/js/xpc/test/native/ObjectReadWrite;1");
-  test_component_readwrite("@mozilla.org/js/xpc/test/js/ObjectReadWrite;1");
-  test_component_readonly("@mozilla.org/js/xpc/test/native/ObjectReadOnly;1");
-  test_component_readonly("@mozilla.org/js/xpc/test/js/ObjectReadOnly;1");
-}
-
-function test_component_readwrite(contractid) {
-
-  // Instantiate the object.
-  var o = Cc[contractid].createInstance(Ci["nsIXPCTestObjectReadWrite"]);
-
-  // Test the initial values.
-  do_check_eq("XPConnect Read-Writable String", o.stringProperty);
-  do_check_eq(true, o.booleanProperty);
-  do_check_eq(32767, o.shortProperty);
-  do_check_eq(2147483647, o.longProperty);
-  do_check_true(5.25 < o.floatProperty && 5.75 > o.floatProperty);
-  do_check_eq("X", o.charProperty);
-
-  // Write new values.
-  o.stringProperty = "another string";
-  o.booleanProperty = false;
-  o.shortProperty = -12345;
-  o.longProperty = 1234567890;
-  o.floatProperty = 10.2;
-  o.charProperty = "Z";
-
-  // Test the new values.
-  do_check_eq("another string", o.stringProperty);
-  do_check_eq(false, o.booleanProperty);
-  do_check_eq(-12345, o.shortProperty);
-  do_check_eq(1234567890, o.longProperty);
-  do_check_true(10.15 < o.floatProperty && 10.25 > o.floatProperty);
-  do_check_eq("Z", o.charProperty);
-
-  // Assign values that differ from the expected type to verify conversion.
-
-  function SetAndTestBooleanProperty(newValue, expectedValue) {
-    o.booleanProperty = newValue;
-    do_check_eq(expectedValue, o.booleanProperty);
-  };
-  SetAndTestBooleanProperty(false, false);
-  SetAndTestBooleanProperty(1, true);
-  SetAndTestBooleanProperty(null, false);
-  SetAndTestBooleanProperty("A", true);
-  SetAndTestBooleanProperty(undefined, false);
-  SetAndTestBooleanProperty([], true);
-  SetAndTestBooleanProperty({}, true);
-}
-
-function test_component_readonly(contractid) {
-
-  // Instantiate the object.
-  var o = Cc[contractid].createInstance(Ci["nsIXPCTestObjectReadOnly"]);
-
-  // Test the initial values.
-  do_check_eq("XPConnect Read-Only String", o.strReadOnly);
-  do_check_eq(true, o.boolReadOnly);
-  do_check_eq(32767, o.shortReadOnly);
-  do_check_eq(2147483647, o.longReadOnly);
-  do_check_true(5.25 < o.floatReadOnly && 5.75 > o.floatReadOnly);
-  do_check_eq("X", o.charReadOnly);
-}
deleted file mode 100644
--- a/js/src/xpconnect/tests/unit/test_params.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is XPConnect Test Code.
- *
- * The Initial Developer of the Original Code is The Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Bobby Holley <bobbyholley@gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-function run_test() {
-
-  // Load the component manifests.
-  Components.manager.autoRegister(do_get_file('../components/native/xpctest.manifest'));
-  Components.manager.autoRegister(do_get_file('../components/js/xpctest.manifest'));
-
-  // Test for each component.
-  test_component("@mozilla.org/js/xpc/test/native/Params;1");
-  test_component("@mozilla.org/js/xpc/test/js/Params;1");
-}
-
-function test_component(contractid) {
-
-  // Instantiate the object.
-  var o = Cc[contractid].createInstance(Ci["nsIXPCTestParams"]);
-
-  // Helper test function - takes the name of test method and two values of
-  // the given type.
-  //
-  // The optional comparator argument can be used for alternative notions of
-  // equality. The comparator should return true on equality.
-  function doTest(name, val1, val2, comparator) {
-    var a = val1;
-    var b = {value: val2};
-    var rv = o[name].call(o, a, b);
-    if (comparator) {
-      do_check_true(comparator(rv, val2));
-      do_check_true(comparator(val1, b.value));
-    }
-    else {
-      do_check_eq(rv, val2);
-      do_check_eq(val1, b.value);
-    }
-  };
-  var fuzzComparator = function(a,b) {return Math.abs(a - b) < 0.1;};
-
-  // Workaround for bug 687612 (inout parameters broken for dipper types).
-  // We do a simple test of copying a into b, and ignore the rv.
-  function doTestWorkaround(name, val1) {
-    var a = val1;
-    var b = {value: ""};
-    o[name].call(o, a, b);
-    do_check_eq(val1, b.value);
-  }
-
-  // Test all the different types
-  doTest("testBoolean", true, false);
-  doTest("testOctet", 4, 156);
-  doTest("testShort", -456, 1299);
-  doTest("testLong", 50060, -12121212);
-  doTest("testLongLong", 12345, -10000000000);
-  doTest("testUnsignedShort", 1532, 65000);
-  doTest("testUnsignedLong", 0, 4000000000);
-  doTest("testUnsignedLongLong", 215435, 3453492580348535809);
-  doTest("testFloat", 4.9, -11.2, fuzzComparator);
-  doTest("testDouble", -80.5, 15000.2, fuzzComparator);
-  doTest("testChar", "a", "2");
-  doTest("testString", "someString", "another string");
-  // TODO: Fix bug 687679 and use the second argument listed below
-  doTest("testWchar", "z", "q");// "ア");
-  // TODO - Test nsIID in bug 687662
-  doTestWorkaround("testDOMString", "Beware: ☠ s");
-  doTestWorkaround("testAString", "Frosty the ☃ ;-)");
-  doTestWorkaround("testAUTF8String", "We deliver 〠!");
-  doTestWorkaround("testACString", "Just a regular C string.");
-  doTest("testJsval", {aprop: 12, bprop: "str"}, 4.22);
-}
--- a/js/src/xpconnect/tests/unit/xpcshell.ini
+++ b/js/src/xpconnect/tests/unit/xpcshell.ini
@@ -16,10 +16,8 @@ tail =
 [test_js_weak_references.js]
 [test_reflect_parse.js]
 [test_localeCompare.js]
 # Bug 676965: test fails consistently on Android
 fail-if = os == "android"
 [test_recursive_import.js]
 [test_xpcomutils.js]
 [test_unload.js]
-[test_attributes.js]
-[test_params.js]
--- a/xpcom/reflect/xptcall/public/xptcall.h
+++ b/xpcom/reflect/xptcall/public/xptcall.h
@@ -47,17 +47,16 @@
 # define NS_InvokeByIndex      NS_InvokeByIndex_P
 #endif
 
 #include "prtypes.h"
 #include "nscore.h"
 #include "nsISupports.h"
 #include "xpt_struct.h"
 #include "xptinfo.h"
-#include "jsapi.h"
 
 struct nsXPTCMiniVariant
 {
 // No ctors or dtors so that we can use arrays of these on the stack
 // with no penalty.
     union
     {
         PRInt8    i8;
@@ -69,74 +68,60 @@ struct nsXPTCMiniVariant
         PRUint32  u32;
         PRUint64  u64;
         float     f;
         double    d;
         PRBool    b;
         char      c;
         PRUnichar wc;
         void*     p;
-
-        // Types below here are unknown to the assembly implementations, and
-        // therefore _must_ be passed with indirect semantics. We put them in
-        // the union here for type safety, so that we can avoid void* tricks.
-        jsval j;
     } val;
 };
 
 struct nsXPTCVariant : public nsXPTCMiniVariant
 {
 // No ctors or dtors so that we can use arrays of these on the stack
 // with no penalty.
 
     // inherits 'val' here
     void*     ptr;
     nsXPTType type;
     PRUint8   flags;
 
     enum
     {
-        //
-        // Bitflag definitions
-        //
-
-        // Indicates that ptr (above, and distinct from val.p) is the value that
-        // should be passed on the stack.
-        //
-        // In theory, ptr could point anywhere. But in practice it always points
-        // to &val. So this flag is used to pass 'val' by reference, letting us
-        // avoid the extra allocation we would incur if we were to use val.p.
-        //
-        // Various parts of XPConnect assume that ptr==&val, so we enforce it
-        // explicitly with SetIndirect() and IsIndirect().
-        //
-        // Since ptr always points to &val, the semantics of this flag are kind of
-        // dumb, since the ptr field is unnecessary. But changing them would
-        // require changing dozens of assembly files, so they're likely to stay
-        // the way they are.
-        PTR_IS_DATA    = 0x1,
-
-        // Indicates that the value we hold requires some sort of cleanup (memory
-        // deallocation, interface release, jsval unrooting, etc). The precise
-        // cleanup that is performed depends on the 'type' field above.
-        // If the value is an array, this flag specifies whether the elements
-        // within the array require cleanup (we always clean up the array itself,
-        // so this flag would be redundant for that purpose).
-        VAL_NEEDS_CLEANUP = 0x2
+        // these are bitflags!
+        PTR_IS_DATA    = 0x1,  // ptr points to 'real' data in val
+        VAL_IS_ALLOCD  = 0x2,  // val.p holds alloc'd ptr that must be freed
+        VAL_IS_IFACE   = 0x4,  // val.p holds interface ptr that must be released
+        VAL_IS_ARRAY   = 0x8,  // val.p holds a pointer to an array needing cleanup
+        VAL_IS_DOMSTR  = 0x10, // val.p holds a pointer to domstring needing cleanup
+        VAL_IS_UTF8STR = 0x20, // val.p holds a pointer to utf8string needing cleanup
+        VAL_IS_CSTR    = 0x40, // val.p holds a pointer to cstring needing cleanup
+        VAL_IS_JSROOT  = 0x80  // val.p holds a pointer to a jsval that must be unrooted
     };
 
     void ClearFlags()         {flags = 0;}
-    void SetIndirect()        {ptr = &val; flags |= PTR_IS_DATA;}
-    void SetValNeedsCleanup() {flags |= VAL_NEEDS_CLEANUP;}
+    void SetPtrIsData()       {flags |= PTR_IS_DATA;}
+    void SetValIsAllocated()  {flags |= VAL_IS_ALLOCD;}
+    void SetValIsInterface()  {flags |= VAL_IS_IFACE;}
+    void SetValIsArray()      {flags |= VAL_IS_ARRAY;}
+    void SetValIsDOMString()  {flags |= VAL_IS_DOMSTR;}
+    void SetValIsUTF8String() {flags |= VAL_IS_UTF8STR;}
+    void SetValIsCString()    {flags |= VAL_IS_CSTR;}
+    void SetValIsJSRoot()     {flags |= VAL_IS_JSROOT;}
 
-    PRBool IsIndirect()         const  {return 0 != (flags & PTR_IS_DATA);}
-    PRBool DoesValNeedCleanup() const  {return 0 != (flags & VAL_NEEDS_CLEANUP);}
-
-    // Internal use only. Use IsIndirect() instead.
     PRBool IsPtrData()       const  {return 0 != (flags & PTR_IS_DATA);}
+    PRBool IsValAllocated()  const  {return 0 != (flags & VAL_IS_ALLOCD);}
+    PRBool IsValInterface()  const  {return 0 != (flags & VAL_IS_IFACE);}
+    PRBool IsValArray()      const  {return 0 != (flags & VAL_IS_ARRAY);}
+    PRBool IsValDOMString()  const  {return 0 != (flags & VAL_IS_DOMSTR);}
+    PRBool IsValUTF8String() const  {return 0 != (flags & VAL_IS_UTF8STR);}
+    PRBool IsValCString()    const  {return 0 != (flags & VAL_IS_CSTR);}    
+    PRBool IsValJSRoot()     const  {return 0 != (flags & VAL_IS_JSROOT);}
 
     void Init(const nsXPTCMiniVariant& mv, const nsXPTType& t, PRUint8 f)
     {
         type = t;
         flags = f;
 
         if(f & PTR_IS_DATA)
         {
--- a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_darwin.cpp
+++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_darwin.cpp
@@ -109,17 +109,17 @@ PrepareAndDispatch(nsXPTCStubBase * self
                 dp->val.d = *(double*) ap++;
             continue;
         }
         else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
             if (nr_fpr < FPR_COUNT)
                 // The value in %xmm register is already prepared to
                 // be retrieved as a float. Therefore, we pass the
                 // value verbatim, as a double without conversion.
-                dp->val.d = fpregs[nr_fpr++];
+                dp->val.d = *(double*) ap++;
             else
                 dp->val.f = *(float*) ap++;
             continue;
         }
         else {
             if (nr_gpr < GPR_COUNT)
                 value = gpregs[nr_gpr++];
             else
--- a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp
+++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_linux.cpp
@@ -109,17 +109,17 @@ PrepareAndDispatch(nsXPTCStubBase * self
                 dp->val.d = *(double*) ap++;
             continue;
         }
         else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
             if (nr_fpr < FPR_COUNT)
                 // The value in %xmm register is already prepared to
                 // be retrieved as a float. Therefore, we pass the
                 // value verbatim, as a double without conversion.
-                dp->val.d = fpregs[nr_fpr++];
+                dp->val.d = *(double*) ap++;
             else
                 dp->val.f = *(float*) ap++;
             continue;
         }
         else {
             if (nr_gpr < GPR_COUNT)
                 value = gpregs[nr_gpr++];
             else
--- a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_solaris.cpp
+++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_x86_64_solaris.cpp
@@ -109,17 +109,17 @@ PrepareAndDispatch(nsXPTCStubBase * self
                 dp->val.d = *(double*) ap++;
             continue;
         }
         else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
             if (nr_fpr < FPR_COUNT)
                 // The value in %xmm register is already prepared to
                 // be retrieved as a float. Therefore, we pass the
                 // value verbatim, as a double without conversion.
-                dp->val.d = fpregs[nr_fpr++];
+                dp->val.d = *(double*) ap++;
             else
                 dp->val.f = *(float*) ap++;
             continue;
         }
         else {
             if (nr_gpr < GPR_COUNT)
                 value = gpregs[nr_gpr++];
             else
--- a/xpcom/reflect/xptinfo/public/xptinfo.h
+++ b/xpcom/reflect/xptinfo/public/xptinfo.h
@@ -155,22 +155,16 @@ public:
     PRBool IsIn()  const    {return 0 != (XPT_PD_IS_IN(flags));}
     PRBool IsOut() const    {return 0 != (XPT_PD_IS_OUT(flags));}
     PRBool IsRetval() const {return 0 != (XPT_PD_IS_RETVAL(flags));}
     PRBool IsShared() const {return 0 != (XPT_PD_IS_SHARED(flags));}
     PRBool IsDipper() const {return 0 != (XPT_PD_IS_DIPPER(flags));}
     PRBool IsOptional() const {return 0 != (XPT_PD_IS_OPTIONAL(flags));}
     const nsXPTType GetType() const {return type.prefix;}
 
-    // Whether this parameter is passed indirectly on the stack. This mainly
-    // applies to out/inout params, but we use it unconditionally for certain
-    // types.
-    PRBool IsIndirect() const {return IsOut() ||
-                               GetType().TagPart() == nsXPTType::T_JSVAL;}
-
     // NOTE: other activities on types are done via methods on nsIInterfaceInfo
 
 private:
     nsXPTParamInfo();   // no implementation
 // NO DATA - this a flyweight wrapper
 };
 
 class nsXPTMethodInfo : public XPTMethodDescriptor