/// <summary>
        /// Ermittelt zu einem Filter einen ausgangsseitigen Steuerknoten der Topologie.
        /// </summary>
        /// <typeparam name="T">Die Art der benötigten Schnittstelle.</typeparam>
        /// <param name="filter">Ein Filter.</param>
        /// <param name="nodeType">Die Art des Knotens.</param>
        /// <returns>Der gewünschte Knoten.</returns>
        public static T GetOutputControlNode <T>(this TypedComIdentity <IBaseFilter> filter, uint nodeType) where T : class
        {
            // Validate
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }

            // Attach to alternate interface
            using (var instance = filter.MarshalToManaged())
            {
                // Change type
                var topology = instance.Object as IBDATopology;
                if (topology == null)
                {
                    return(null);
                }

                // Load
                var node   = topology.GetControlNode(0, 1, nodeType);
                var result = node as T;

                // Cleanup
                if (result == null)
                {
                    BDAEnvironment.Release(ref node);
                }

                // Report
                return(result);
            }
        }
        /// <summary>
        /// Erzeugt eine neue Instanz.
        /// </summary>
        /// <typeparam name="DataType">Die Art der Daten.</typeparam>
        /// <param name="interface">Die zu verwendende Schnittstelle.</param>
        /// <returns>Eine neue Zugriffsinstanz.</returns>
        public static IKsPropertySet <DataType> Create <DataType>(IntPtr @interface)
            where DataType : struct
        {
            // None
            if (@interface == null)
            {
                return(null);
            }

            // Try to access the interface
            var com = ComIdentity.TryQueryInterface(@interface, typeof(IKsPropertySet));

            if (com == IntPtr.Zero)
            {
                return(null);
            }

            // Be safe
            try
            {
                // Create the wrapper
                using (var typed = new TypedComIdentity <IKsPropertySet>(com))
                {
                    // No longer needed to release
                    com = IntPtr.Zero;

                    // Create wrapper
                    var wrapper = typed.MarshalToManaged();
                    try
                    {
                        // Safe process
                        return(new Typed <DataType>(wrapper));
                    }
                    catch
                    {
                        // Cleanup
                        wrapper.Dispose();

                        // Forward
                        throw;
                    }
                }
            }
            finally
            {
                // Cleanup
                BDAEnvironment.Release(ref com);
            }
        }
        /// <summary>
        /// Untersucht alle Endpunkte eines Filters.
        /// </summary>
        /// <param name="filter">Der zu betrachtende Filter.</param>
        /// <param name="selector">Optional eine Auswahlfunktion.</param>
        /// <param name="action">Optional eine Aktion, die pro Endpunkt ausgeführt werden soll.</param>
        /// <exception cref="ArgumentNullException">Es wurde kein Filter angegeben.</exception>
        public static void InspectAllPins(this TypedComIdentity <IBaseFilter> filter, Predicate <IPin> selector, Func <IPin, bool> action)
        {
            // Validate
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }

            // Attach to the instance
            using (var filterInstance = filter.MarshalToManaged())
            {
                // Attach to all pins
                var pins = filterInstance.Object.EnumPins();
                try
                {
                    // Process all
                    for (; ;)
                    {
                        using (var array = new COMArray(1))
                        {
                            // Load
                            uint count = 0;
                            if (pins.Next(1, array.Address, ref count) != 0)
                            {
                                break;
                            }

                            // Load object
                            if (count != 1)
                            {
                                continue;
                            }

                            // Load the one
                            var pin = array.GetObject <IPin>(0);
                            try
                            {
                                // Check predicate
                                if (selector != null)
                                {
                                    if (!selector(pin))
                                    {
                                        continue;
                                    }
                                }

                                // Execute
                                if (action != null)
                                {
                                    if (!action(pin))
                                    {
                                        return;
                                    }
                                }
                            }
                            finally
                            {
                                // Cleanup
                                BDAEnvironment.Release(ref pin);
                            }
                        }
                    }
                }
                finally
                {
                    // Cleanup
                    BDAEnvironment.Release(ref pins);
                }
            }
        }