/// <summary>
        /// Initializes a new Windows Script engine instance with the specified list of supported file name extensions and synchronous invoker.
        /// </summary>
        /// <param name="progID">The programmatic identifier (ProgID) of the Windows Script engine class.</param>
        /// <param name="name">A name to associate with the instance. Currently this name is used only as a label in presentation contexts such as debugger user interfaces.</param>
        /// <param name="fileNameExtensions">A semicolon-delimited list of supported file name extensions.</param>
        /// <param name="flags">A value that selects options for the operation.</param>
        /// <param name="syncInvoker">An object that enforces thread affinity for the instance.</param>
        /// <remarks>
        /// The <paramref name="progID"/> argument can be a class identifier (CLSID) in standard
        /// GUID format with braces (e.g., "{F414C260-6AC0-11CF-B6D1-00AA00BBBB58}").
        /// </remarks>
        protected WindowsScriptEngine(string progID, string name, string fileNameExtensions, WindowsScriptEngineFlags flags, ISyncInvoker syncInvoker)
            : base(name, fileNameExtensions)
        {
            MiscHelpers.VerifyNonNullArgument(syncInvoker, nameof(syncInvoker));
            this.syncInvoker = syncInvoker;

            script = base.ScriptInvoke(() =>
            {
                activeScript = ActiveScriptWrapper.Create(progID, flags);
                engineFlags  = flags;

                if (flags.HasFlag(WindowsScriptEngineFlags.EnableDebugging) && ProcessDebugManagerWrapper.TryCreate(out processDebugManager))
                {
                    processDebugManager.CreateApplication(out debugApplication);
                    debugApplication.SetName(Name);

                    if (processDebugManager.TryAddApplication(debugApplication, out debugApplicationCookie))
                    {
                        sourceManagement = !flags.HasFlag(WindowsScriptEngineFlags.DisableSourceManagement);
                    }
                    else
                    {
                        debugApplication.Close();
                        debugApplication    = null;
                        processDebugManager = null;
                    }
                }

                activeScript.SetScriptSite(new ScriptSite(this));
                activeScript.InitNew();
                activeScript.SetScriptState(ScriptState.Started);
                return(WindowsScriptItem.Wrap(this, GetScriptDispatch()));
            });
        }
        private object MarshalToHostInternal(object obj, bool preserveHostTarget, HashSet <Array> marshaledArraySet)
        {
            if (obj == null)
            {
                return(UndefinedImportValue);
            }

            if (obj is DBNull)
            {
                return(null);
            }

            if (MiscHelpers.TryMarshalPrimitiveToHost(obj, DisableFloatNarrowing, out var result))
            {
                return(result);
            }

            if (obj is Array array)
            {
                // COM interop converts VBScript arrays to managed arrays

                bool alreadyMarshaled;
                if (marshaledArraySet != null)
                {
                    alreadyMarshaled = marshaledArraySet.Contains(array);
                }
                else
                {
                    marshaledArraySet = new HashSet <Array>();
                    alreadyMarshaled  = false;
                }

                if (!alreadyMarshaled)
                {
                    marshaledArraySet.Add(array);
                    array.Iterate(indices => array.SetValue(MarshalToHostInternal(array.GetValue(indices), preserveHostTarget, marshaledArraySet), indices));
                }

                return(array);
            }

            if (obj is HostTarget hostTarget)
            {
                return(preserveHostTarget ? hostTarget : hostTarget.Target);
            }

            if (obj is HostItem hostItem)
            {
                return(preserveHostTarget ? hostItem.Target : hostItem.Unwrap());
            }

            if (obj is ScriptItem)
            {
                return(obj);
            }

            return(WindowsScriptItem.Wrap(this, obj));
        }