public void Main(MgaProject project, MgaFCO currentobj, MgaFCOs selectedobjs, ComponentStartMode startMode)
        {
            // This is the main ShowNet interpreter code
            Boolean ownLogger = false;
            if (Logger == null)
            {
                ownLogger = true;
                Logger = new CyPhyGUIs.GMELogger(project, "ShowNet");
            }
            GMEConsole.Out.WriteLine("\n======================================================================================================================================\n");
            Logger.WriteInfo("Starting ShowNet.");

            // Get RootFolder
            IMgaFolder rootFolder = project.RootFolder;
            //GMEConsole.Out.WriteLine(rootFolder.Name);

            // To use the domain-specific API:
            //  Create another project with the same name as the paradigm name
            //  Copy the paradigm .mga file to the directory containing the new project
            //  In the new project, install the GME DSMLGenerator NuGet package (search for DSMLGenerator)
            //  Add a Reference in this project to the other project
            //  Add "using [ParadigmName] = ISIS.GME.Dsml.[ParadigmName].Classes.Interfaces;" to the top of this file
            bool done = false;

            if ((!done) && (null == currentobj))
            {
                done = true;
                Logger.WriteError("The current object is null.  Please select a ComponentAssembly or DesignContainer object.");
            }

            if ((!done) && (currentobj.Meta.Name != "ComponentAssembly" &&
                			currentobj.Meta.Name != "DesignContainer"))
            {
                done = true;
                Logger.WriteError("ShowNet only works on ComponentAssembly and DesignContainer objects.");
                Logger.WriteError("But, {1} is neither; it is a {0}.", currentobj.Meta.Name, currentobj.Name);
            }

            if (!done)
            {
				IEnumerable<CyPhy.PortComposition> portCompositionChildren = null;
	            IEnumerable<CyPhy.ConnectorComposition> connectorCompositionChildren = null;

	            if (currentobj.Meta.Name == "ComponentAssembly")
	            {
	                var componentAssembly = ISIS.GME.Dsml.CyPhyML.Classes.ComponentAssembly.Cast(currentobj);
	                portCompositionChildren = componentAssembly.Children.PortCompositionCollection;
	                connectorCompositionChildren = componentAssembly.Children.ConnectorCompositionCollection;                    
	            }
	            else if (currentobj.Meta.Name == "DesignContainer")
	            {
	                var designContainer = ISIS.GME.Dsml.CyPhyML.Classes.DesignContainer.Cast(currentobj);
	                portCompositionChildren = designContainer.Children.PortCompositionCollection;
	                connectorCompositionChildren = designContainer.Children.ConnectorCompositionCollection;   
	            }

                //=================================================================
                // Process the port connections
                //=================================================================

                NetworkManager portNetworkManager = new NetworkManager();

            	foreach (CyPhy.PortComposition port in portCompositionChildren)
                {
                    Endpoint dstEndPoint = new Endpoint(port.DstEnd, port.GenericDstEndRef);
                    Endpoint srcEndPoint = new Endpoint(port.SrcEnd, port.GenericSrcEndRef);

                    //GMEConsole.Out.WriteLine("Found port: dst = '{0}' in the '{1}' {2}.",
                    //    dstEndPoint.Name,
                    //    dstEndPoint.ParentName,
                    //    dstEndPoint.ParentKind);

                    //GMEConsole.Out.WriteLine("            src = '{0}' in the '{1}' {2}.",
                    //    srcEndPoint.Name,
                    //    srcEndPoint.ParentName,
                    //    srcEndPoint.ParentKind);

                    // Create a network from the endpoints
                    List<Endpoint> nodes = new List<Endpoint>() { srcEndPoint, dstEndPoint };
                    Network newNetwork = new Network(nodes);
                    portNetworkManager.Add(newNetwork);
                }

                //=================================================================
                // Process the connector connections
                //=================================================================

                NetworkManager connectorNetworkManager = new NetworkManager();

            	foreach (CyPhy.ConnectorComposition connector in connectorCompositionChildren)
                {
                    Endpoint dstEndPoint = new Endpoint(connector.DstEnd, connector.GenericDstEndRef);
                    Endpoint srcEndPoint = new Endpoint(connector.SrcEnd, connector.GenericSrcEndRef);

                    // Create a network from the endpoints
                    List<Endpoint> nodes = new List<Endpoint>() { srcEndPoint, dstEndPoint };
                    Network newNetwork = new Network(nodes);
                    connectorNetworkManager.Add(newNetwork);
                }

                // Make sure the network names are unique.
                NetworkNameChecker.Init();
                NetworkNameChecker.Update(ref portNetworkManager.NetworkList);
                NetworkNameChecker.Update(ref connectorNetworkManager.NetworkList);

                // Display all the networks.

                Logger.WriteInfo(string.Format("===== Found {0} port networks on {1}: =====\n", 
                    portNetworkManager.NetworkList.Count,
                    currentobj.Name));

                foreach (Network mergedNet in portNetworkManager.NetworkList)
                {
                    using (StringReader sr = new StringReader(mergedNet.ToString()))
                    {
                        string line;
                        while ((line = sr.ReadLine()) != null)
                        {
                            GMEConsole.Out.WriteLine(line);
                        }
                    }
                }

                Logger.WriteInfo(string.Format("===== Found {0} connector networks on {1}: =====\n", 
                    connectorNetworkManager.NetworkList.Count,
                    currentobj.Name));

                foreach (Network mergedNet in connectorNetworkManager.NetworkList)
                {
                    using (StringReader sr = new StringReader(mergedNet.ToString()))
                    {
                        string line;
                        while ((line = sr.ReadLine()) != null)
                        {
                            GMEConsole.Out.WriteLine(line);
                        }
                    }
                }
            }

            Logger.WriteInfo("The ShowNet interpreter has finished.");

            if (ownLogger)
            {
                Logger.Dispose();
                Logger = null;
            }
        }
        /// <summary>
        /// Check if there is a connection between two networks.
        /// </summary>
        /// <param name="net1">The first network.</param>
        /// <param name="net2">The second network.</param>
        /// <exception>
        /// Throws an exception if the first network has internal duplicate endpoints.
        /// </exception>
        /// <returns>true if there is a connection, otherwise false.</returns>
        bool IsConnectionShared(Network net1, Network net2)
        {
            bool rVal = false;

            // We use the Endpoint ID as the key to determine endpoint uniqueness.
            Dictionary<string, Endpoint> epDictionary = new Dictionary<string, Endpoint>();

            foreach (Endpoint ep in net1.Nodes)
            {
                if (!epDictionary.ContainsKey(ep.ID))
                {
                    epDictionary.Add(ep.ID, ep);
                }
                else
                {
                    throw new Exception("Network contains duplicate endpoints.");
                }
            };
            foreach (Endpoint ep in net2.Nodes)
            {
                if (!epDictionary.ContainsKey(ep.ID))
                {
                    epDictionary.Add(ep.ID, ep);
                }
                else
                {
                    // Found a connection between the two networks.
                    rVal = true;
                }
            };

            return rVal;
        }
        /// <summary>
        /// Merge the source netlist into the destination netlist.
        /// </summary>
        /// <param name="src">The source netlist.</param>
        /// <param name="dst">The destination netlist.</param>
        void MergeSrcIntoDst(Network src, ref Network dst)
        {
            // Build a dictionary with all the unique endpoints.
            // We use the Endpoint ID as the key to determine endpoint uniqueness.
            Dictionary<string, Endpoint> epDictionary = new Dictionary<string, Endpoint>();

            foreach (Endpoint ep in src.Nodes)
            {
                if (!epDictionary.ContainsKey(ep.ID))
                {
                    epDictionary.Add(ep.ID, ep);
                }
            };

            foreach (Endpoint ep in dst.Nodes)
            {
                if (!epDictionary.ContainsKey(ep.ID))
                {
                    epDictionary.Add(ep.ID, ep);
                }
            };

            // Get the endpoint list from the dictionary.
            List<Endpoint> nodes = epDictionary.Values.ToList();

            // Set the destination netlist to the merged network.
            dst = new Network(nodes);
        }
        // Add a network to the list of networks, coalescing those with common connections.
        public void Add(Network newNetwork)
        {
            // Iterate list in reverse order, see http://stackoverflow.com/questions/1582285/how-to-remove-elements-from-a-generic-list-while-iterating-over-it
            for (int i = NetworkList.Count - 1; i >= 0; i--)
            {
                if (IsConnectionShared(NetworkList[i], newNetwork))
                {
                    MergeSrcIntoDst(NetworkList[i], ref newNetwork);
                    NetworkList.RemoveAt(i);
                }
            }

            NetworkList.Add(newNetwork);
        }