public static Type FindInputPortDataType(this ComponentConfiguration config, IPortMetadata portMetadata, IReadOnlyList <ComponentConfiguration> configs, params Tuple <ComponentConfiguration, IPortMetadata>[] exclude)
        {
            var dataType = portMetadata.GetTransmissionDataType(null, Array.Empty <Type>(), Array.Empty <Type>());

            if (dataType is null)
            {
                var i = config.Inputs.FirstOrDefault(c => Equals(c.LocalPort.Identifier, portMetadata.Identifier));
                if (i is null)
                {
                    return(null);
                }
                foreach (var other in configs)
                {
                    if (Equals(i.RemoteId, other.Id))
                    {
                        var newExclude = new Tuple <ComponentConfiguration, IPortMetadata> [exclude.Length + 1];
                        Array.Copy(exclude, newExclude, exclude.Length);
                        var oMetadata = other.FindPortMetadata(i.RemotePort);
                        newExclude[exclude.Length] = new Tuple <ComponentConfiguration, IPortMetadata>(other, oMetadata);
                        var otherInput  = FindInputPortDataTypes(other, configs, newExclude);
                        var otherOutput = FindOutputPortDataTypes(other, configs, newExclude);
                        var otherEnd    = oMetadata.GetTransmissionDataType(null, otherInput, otherOutput);
                        if (otherEnd != null)
                        {
                            dataType = portMetadata.GetTransmissionDataType(otherEnd, Array.Empty <Type>(), Array.Empty <Type>());
                            if (dataType != null)
                            {
                                goto jump;
                            }
                            newExclude[exclude.Length] = new Tuple <ComponentConfiguration, IPortMetadata>(config, portMetadata);
                            var selfOutput = FindOutputPortDataTypes(config, configs, newExclude);
                            dataType = portMetadata.GetTransmissionDataType(otherEnd, selfOutput, Array.Empty <Type>());
                            if (dataType != null)
                            {
                                goto jump;
                            }
                            var selfInput = FindInputPortDataTypes(config, configs, newExclude);
                            dataType = portMetadata.GetTransmissionDataType(otherEnd, selfOutput, selfInput);
                            if (dataType != null)
                            {
                                goto jump;
                            }
                        }
                    }
                }
                jump :;
            }
            return(dataType);
        }
 public static IList <Type> FindOutputPortDataTypes(this ComponentConfiguration config, IReadOnlyList <ComponentConfiguration> configs, IPortMetadata exclude)
 {
     return(FindOutputPortDataTypes(config, configs, new Tuple <ComponentConfiguration, IPortMetadata>(config, exclude)));
 }