public static void defineClass(Scriptable scope, Class clazz, boolean sealed)
public static void defineClass(Scriptable scope, Class clazz)
    public static void defineClass(Scriptable scope, Class clazz,                                   boolean sealed)        throws IllegalAccessException, InstantiationException,               InvocationTargetException, ClassDefinitionException,               PropertyException    {        Method[] methods = FunctionObject.getMethodList(clazz);        for (int i=0; i < methods.length; i++) {            Method method = methods[i];            if (!method.getName().equals("init"))                continue;            Class[] parmTypes = method.getParameterTypes();            if (parmTypes.length == 3 &&                parmTypes[0] == ScriptRuntime.ContextClass &&                parmTypes[1] == ScriptRuntime.ScriptableClass &&                parmTypes[2] == Boolean.TYPE &&                Modifier.isStatic(method.getModifiers()))            {                Object args[] = { Context.getContext(), scope,                                  sealed ? Boolean.TRUE : Boolean.FALSE };                method.invoke(null, args);                return;            }            if (parmTypes.length == 1 &&                parmTypes[0] == ScriptRuntime.ScriptableClass &&                Modifier.isStatic(method.getModifiers()))            {                Object args[] = { scope };                method.invoke(null, args);                return;            }        }        // If we got here, there isn't an "init" method with the right        // parameter types.        Constructor[] ctors = clazz.getConstructors();        Constructor protoCtor = null;        for (int i=0; i < ctors.length; i++) {            if (ctors[i].getParameterTypes().length == 0) {                protoCtor = ctors[i];                break;            }        }        if (protoCtor == null) {            throw new ClassDefinitionException(                    Context.getMessage1("msg.zero.arg.ctor", clazz.getName()));        }        Scriptable proto = (Scriptable)                        protoCtor.newInstance(ScriptRuntime.emptyArgs);        proto.setPrototype(getObjectPrototype(scope));        String className = proto.getClassName();        // Find out whether there are any methods that begin with        // "js". If so, then only methods that begin with special        // prefixes will be defined as JavaScript entities.        final String functionPrefix = "jsFunction_";        final String staticFunctionPrefix = "jsStaticFunction_";        final String getterPrefix = "jsGet_";        final String setterPrefix = "jsSet_";        final String ctorName = "jsConstructor";        Member ctorMember = FunctionObject.findSingleMethod(methods, ctorName);        if (ctorMember == null) {            if (ctors.length == 1) {                ctorMember = ctors[0];            } else if (ctors.length == 2) {                if (ctors[0].getParameterTypes().length == 0)                    ctorMember = ctors[1];                else if (ctors[1].getParameterTypes().length == 0)                    ctorMember = ctors[0];            }            if (ctorMember == null) {                throw new ClassDefinitionException(                    Context.getMessage1("msg.ctor.multiple.parms",                                        clazz.getName()));            }        }        FunctionObject ctor = new FunctionObject(className, ctorMember, scope);        if (ctor.isVarArgsMethod()) {            throw Context.reportRuntimeError1                ("msg.varargs.ctor", ctorMember.getName());        }        ctor.addAsConstructor(scope, proto);        Method finishInit = null;        for (int i=0; i < methods.length; i++) {            if (methods[i] == ctorMember) {                continue;            }            String name = methods[i].getName();            if (name.equals("finishInit")) {                Class[] parmTypes = methods[i].getParameterTypes();                if (parmTypes.length == 3 &&                    parmTypes[0] == ScriptRuntime.ScriptableClass &&                    parmTypes[1] == FunctionObject.class &&                    parmTypes[2] == ScriptRuntime.ScriptableClass &&                    Modifier.isStatic(methods[i].getModifiers()))                {                    finishInit = methods[i];                    continue;                }            }            // ignore any compiler generated methods.            if (name.indexOf('$') != -1)                continue;            if (name.equals(ctorName))                continue;            String prefix = null;            if (name.startsWith(functionPrefix)) {                prefix = functionPrefix;            } else if (name.startsWith(staticFunctionPrefix)) {                prefix = staticFunctionPrefix;                if (!Modifier.isStatic(methods[i].getModifiers())) {                    throw new ClassDefinitionException(                        "jsStaticFunction must be used with static method.");                }            } else if (name.startsWith(getterPrefix)) {                prefix = getterPrefix;            } else if (name.startsWith(setterPrefix)) {                prefix = setterPrefix;            } else {                continue;            }            name = name.substring(prefix.length());            if (prefix == setterPrefix)                continue;   // deal with set when we see get            if (prefix == getterPrefix) {                if (!(proto instanceof ScriptableObject)) {                    throw PropertyException.withMessage2                        ("msg.extend.scriptable",                                                         proto.getClass().toString(), name);                }                Method setter = FunctionObject.findSingleMethod(                                    methods,                                    setterPrefix + name);                int attr = ScriptableObject.PERMANENT |                           ScriptableObject.DONTENUM  |                           (setter != null ? 0                                           : ScriptableObject.READONLY);                ((ScriptableObject) proto).defineProperty(name, null,                                                          methods[i], setter,                                                          attr);                continue;            }            FunctionObject f = new FunctionObject(name, methods[i], proto);            if (f.isVarArgsConstructor()) {                throw Context.reportRuntimeError1                    ("msg.varargs.fun", ctorMember.getName());            }            Scriptable dest = prefix == staticFunctionPrefix                              ? ctor                              : proto;            defineProperty(dest, name, f, DONTENUM);            if (sealed) {                f.sealObject();            }        }        if (finishInit != null) {            // call user code to complete the initialization            Object[] finishArgs = { scope, ctor, proto };            finishInit.invoke(null, finishArgs);        }        if (sealed) {            ctor.sealObject();            if (proto instanceof ScriptableObject) {                ((ScriptableObject) proto).sealObject();            }        }    }