internal V8ScriptEngine(V8Runtime runtime, string name, V8RuntimeConstraints constraints, V8ScriptEngineFlags flags, int debugPort)
            : base((runtime != null) ? runtime.Name + ":" + name : name)
        {
            using (var localRuntime = (runtime != null) ? null : new V8Runtime(name, constraints))
            {
                var activeRuntime = runtime ?? localRuntime;
                hostItemCollateral = activeRuntime.HostItemCollateral;

                engineFlags = flags;
                proxy       = V8ContextProxy.Create(activeRuntime.IsolateProxy, Name, flags, debugPort);
                script      = GetRootItem();

                var engineInternal = Evaluate(
                    MiscHelpers.FormatInvariant("{0} [internal]", GetType().Name),
                    false,
                    @"
                        EngineInternal = (function () {

                            function convertArgs(args) {
                                var result = [];
                                var count = args.Length;
                                for (var i = 0; i < count; i++) {
                                    result.push(args[i]);
                                }
                                return result;
                            }

                            function construct(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15) {
                                return new this(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
                            }

                            var isHostObjectKey = this.isHostObjectKey;
                            delete this.isHostObjectKey;

                            return {

                                getCommandResult: function (value) {
                                    if (value == null) {
                                        return value;
                                    }
                                    if (typeof(value.hasOwnProperty) != 'function') {
                                        return '[external]';
                                    }
                                    if (value[isHostObjectKey] === true) {
                                        return value;
                                    }
                                    if (typeof(value.toString) != 'function') {
                                        return '[' + typeof(value) + ']';
                                    }
                                    return value.toString();
                                },

                                invokeConstructor: function (constructor, args) {
                                    if (typeof(constructor) != 'function') {
                                        throw new Error('Function expected');
                                    }
                                    return construct.apply(constructor, convertArgs(args));
                                },

                                invokeMethod: function (target, method, args) {
                                    if (typeof(method) != 'function') {
                                        throw new Error('Function expected');
                                    }
                                    return method.apply(target, convertArgs(args));
                                },

                                getStackTrace: function () {
                                    try {
                                        throw new Error('[stack trace]');
                                    }
                                    catch (exception) {
                                        return exception.stack;
                                    }
                                    return '';
                                }
                            };
                        })();
                    "
                    );

                ((IDisposable)engineInternal).Dispose();

                if (flags.HasFlag(V8ScriptEngineFlags.EnableDebugging | V8ScriptEngineFlags.AwaitDebuggerAndPauseOnStart))
                {
                    awaitDebuggerAndPause = true;
                }
            }
        }
        internal V8ScriptEngine(V8Runtime runtime, string name, V8RuntimeConstraints constraints, V8ScriptEngineFlags flags, int debugPort)
            : base((runtime != null) ? runtime.Name + ":" + name : name)
        {
            using (var localRuntime = (runtime != null) ? null : new V8Runtime(name, constraints))
            {
                var activeRuntime = runtime ?? localRuntime;

                engineFlags = flags;
                proxy       = V8ContextProxy.Create(activeRuntime.IsolateProxy, Name, flags.HasFlag(V8ScriptEngineFlags.EnableDebugging), flags.HasFlag(V8ScriptEngineFlags.DisableGlobalMembers), debugPort);
                script      = GetRootItem();

                var engineInternal = Evaluate(
                    MiscHelpers.FormatInvariant("{0} [internal]", GetType().Name),
                    false,
                    @"
                        EngineInternal = (function () {

                            function convertArgs(args) {
                                var result = [];
                                var count = args.Length;
                                for (var i = 0; i < count; i++) {
                                    result.push(args[i]);
                                }
                                return result;
                            }

                            function construct(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15) {
                                return new this(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
                            }

                            return {

                                getCommandResult: function (value) {
                                    if (value != null) {
                                        if (((typeof(value) == 'object') && !value.hasOwnProperty('{c2cf47d3-916b-4a3f-be2a-6ff567425808}')) || (typeof(value) == 'function')) {
                                            if (typeof(value.toString) == 'function') {
                                                return value.toString();
                                            }
                                        }
                                    }
                                    return value;
                                },

                                invokeConstructor: function (constructor, args) {
                                    if (typeof(constructor) != 'function') {
                                        throw new Error('Function expected');
                                    }
                                    return construct.apply(constructor, convertArgs(args));
                                },

                                invokeMethod: function (target, method, args) {
                                    if (typeof(method) != 'function') {
                                        throw new Error('Function expected');
                                    }
                                    return method.apply(target, convertArgs(args));
                                },

                                getStackTrace: function () {
                                    try {
                                        throw new Error('[stack trace]');
                                    }
                                    catch (exception) {
                                        return exception.stack;
                                    }
                                    return '';
                                }
                            };
                        })();
                    "
                    );

                ((IDisposable)engineInternal).Dispose();
            }
        }