// Obtains information about programs running, filtered in a variety of ways.
        int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter,
                                                          PROVIDER_PROCESS_DATA[] processArray)
        {
            processArray[0] = new PROVIDER_PROCESS_DATA();

            // we handle creation of the remote program provider ourselves.  This is because we always load our program provider locally which keeps
            // attach working when developing Node Tools and running/debugging from within VS and in the experimental hive.  When we are installed
            // we install into the GAC so these types are available to create and then remote debugging works as well.  When we're running in the
            // experimental hive we are not in the GAC so if we're created outside of VS (e.g. in msvsmon on the local machine) then we can't get
            // at our program provider and debug->attach doesn't work.
            if (port != null && port.QueryIsLocal() == VSConstants.S_FALSE)
            {
                IDebugCoreServer3 server;
                if (ErrorHandler.Succeeded(port.GetServer(out server)))
                {
                    var dbgServer = server as IDebugCoreServer90;
                    if (dbgServer != null)
                    {
                        Guid g = typeof (IDebugProgramProvider2).GUID;
                        IntPtr remoteProviderPunk;

                        int hr = dbgServer.CreateManagedInstanceInServer(typeof (AD7ProgramProvider).FullName, typeof (AD7ProgramProvider).Assembly.FullName, 0, ref g, out remoteProviderPunk);
                        try
                        {
                            if (ErrorHandler.Succeeded(hr))
                            {
                                var remoteProvider = (IDebugProgramProvider2) Marshal.GetObjectForIUnknown(remoteProviderPunk);
                                return remoteProvider.GetProviderProcessData(Flags, null, ProcessId, EngineFilter, processArray);
                            }
                        }
                        finally
                        {
                            if (remoteProviderPunk != IntPtr.Zero)
                            {
                                Marshal.Release(remoteProviderPunk);
                            }
                        }
                    }
                }
            }
            else if ((Flags & enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES) != 0)
            {
                // The debugger is asking the engine to return the program nodes it can debug. We check
                // each process if it has a python##.dll or python##_d.dll loaded and if it does
                // then we report the program as being a Node process.

                IDebugProgramNode2 node = new AD7ProgramNode((int) ProcessId.dwProcessId);

                IntPtr[] programNodes = {Marshal.GetComInterfaceForObject(node, typeof (IDebugProgramNode2))};

                IntPtr destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size*programNodes.Length);
                Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length);

                processArray[0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES;
                processArray[0].ProgramNodes.Members = destinationArray;
                processArray[0].ProgramNodes.dwCount = (uint) programNodes.Length;

                return VSConstants.S_OK;
            }

            return VSConstants.S_FALSE;
        }
        // Obtains information about programs running, filtered in a variety of ways.
        int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter,
                                                          PROVIDER_PROCESS_DATA[] processArray)
        {
            processArray[0] = new PROVIDER_PROCESS_DATA();

            // we handle creation of the remote program provider ourselves.  This is because we always load our program provider locally which keeps
            // attach working when developing Node Tools and running/debugging from within VS and in the experimental hive.  When we are installed
            // we install into the GAC so these types are available to create and then remote debugging works as well.  When we're running in the
            // experimental hive we are not in the GAC so if we're created outside of VS (e.g. in msvsmon on the local machine) then we can't get
            // at our program provider and debug->attach doesn't work.
            if (port != null && port.QueryIsLocal() == VSConstants.S_FALSE)
            {
                IDebugCoreServer3 server;
                if (ErrorHandler.Succeeded(port.GetServer(out server)))
                {
                    var dbgServer = server as IDebugCoreServer90;
                    if (dbgServer != null)
                    {
                        Guid   g = typeof(IDebugProgramProvider2).GUID;
                        IntPtr remoteProviderPunk;

                        int hr = dbgServer.CreateManagedInstanceInServer(typeof(AD7ProgramProvider).FullName, typeof(AD7ProgramProvider).Assembly.FullName, 0, ref g, out remoteProviderPunk);
                        try
                        {
                            if (ErrorHandler.Succeeded(hr))
                            {
                                var remoteProvider = (IDebugProgramProvider2)Marshal.GetObjectForIUnknown(remoteProviderPunk);
                                return(remoteProvider.GetProviderProcessData(Flags, null, ProcessId, EngineFilter, processArray));
                            }
                        }
                        finally
                        {
                            if (remoteProviderPunk != IntPtr.Zero)
                            {
                                Marshal.Release(remoteProviderPunk);
                            }
                        }
                    }
                }
            }
            else if ((Flags & enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES) != 0)
            {
                // The debugger is asking the engine to return the program nodes it can debug. We check
                // each process if it has a python##.dll or python##_d.dll loaded and if it does
                // then we report the program as being a Node process.

                IDebugProgramNode2 node = new AD7ProgramNode((int)ProcessId.dwProcessId);

                IntPtr[] programNodes = { Marshal.GetComInterfaceForObject(node, typeof(IDebugProgramNode2)) };

                IntPtr destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size * programNodes.Length);
                Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length);

                processArray[0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES;
                processArray[0].ProgramNodes.Members = destinationArray;
                processArray[0].ProgramNodes.dwCount = (uint)programNodes.Length;

                return(VSConstants.S_OK);
            }

            return(VSConstants.S_FALSE);
        }