/// <summary> Function.prototype.apply and Function.prototype.call
        /// 
        /// See Ecma 15.3.4.[34]
        /// </summary>
        public static object applyOrCall(bool isApply, Context cx, IScriptable scope, IScriptable thisObj, object [] args)
        {
            int L = args.Length;
            ICallable function;
            if (thisObj is ICallable) {
                function = (ICallable)thisObj;
            }
            else {
                object value = thisObj.GetDefaultValue (typeof (IFunction));
                if (!(value is ICallable)) {
                    throw ScriptRuntime.NotFunctionError (value, thisObj);
                }
                function = (ICallable)value;
            }

            IScriptable callThis = null;
            if (L != 0) {
                callThis = ScriptConvert.ToObjectOrNull (cx, args [0]);
            }
            if (callThis == null) {
                // This covers the case of args[0] == (null|undefined) as well.
                callThis = getTopCallScope (cx);
            }

            object [] callArgs;
            if (isApply) {
                // Follow Ecma 15.3.4.3
                if (L <= 1) {
                    callArgs = ScriptRuntime.EmptyArgs;
                }
                else {
                    object arg1 = args [1];
                    if (arg1 == null || arg1 == Undefined.Value) {
                        callArgs = ScriptRuntime.EmptyArgs;
                    }
                    else if (arg1 is BuiltinArray || arg1 is Arguments) {
                        callArgs = cx.GetElements ((IScriptable)arg1);
                    }
                    else {
                        throw ScriptRuntime.TypeErrorById ("msg.arg.isnt.array");
                    }
                }
            }
            else {
                // Follow Ecma 15.3.4.4
                if (L <= 1) {
                    callArgs = ScriptRuntime.EmptyArgs;
                }
                else {
                    callArgs = new object [L - 1];
                    Array.Copy (args, 1, callArgs, 0, L - 1);
                }
            }

            return function.Call (cx, scope, callThis, callArgs);
        }