public void Main(MgaProject project, MgaFCO currentobj, MgaFCOs selectedobjs, ComponentStartMode startMode)
        {
            // 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
            // [ParadigmName].[KindName] dsCurrentObj = ISIS.GME.Dsml.[ParadigmName].Classes.[KindName].Cast(currentobj);

            // TODO: find model editor window and open form inside it. Would be nice to find it based on  C++ class.
            var mainHwd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;

            IntPtr mdiClient = IntPtr.Zero;

            foreach (var childHwd in GetChildWindows(mainHwd))
            {
                StringBuilder sb = new StringBuilder(100);
                GetClassName(childHwd, sb, 100);
                if ("MDIClient" == sb.ToString())
                {
                    mdiClient = childHwd;
                    break;
                }
            }

            //GMEConsole.Warning.WriteLine("Name: '{0}' Position: {1} {2} {3} {4}", name, rr.Top, rr.Left, rr.Bottom, rr.Right);

            List <string> supportedKinds = new List <string>()
            {
                typeof(CyPhy.Component).Name,
                typeof(CyPhy.ComponentAssembly).Name,
                typeof(CyPhy.TestComponent).Name,
                typeof(CyPhy.DesignContainer).Name,
                typeof(CyPhy.TestBench).Name,
                typeof(CyPhy.BlastTestBench).Name,
                typeof(CyPhy.BallisticTestBench).Name,
                typeof(CyPhy.CADTestBench).Name,
                typeof(CyPhy.CFDTestBench).Name,
                typeof(CyPhy.TestBenchSuite).Name,
            };

            if (currentobj == null ||
                supportedKinds.Contains(currentobj.Meta.Name) == false)
            {
                GMEConsole.Warning.WriteLine("One of the following object types must be open in the editor: {0}", string.Join(", ", supportedKinds));
                return;
            }

            List <ComponentParameterItem> parameterItems = new List <ComponentParameterItem>();

            if (currentobj.Meta.Name == typeof(CyPhy.Component).Name ||
                currentobj.Meta.Name == typeof(CyPhy.ComponentAssembly).Name)
            {
                var component = CyPhyClasses.DesignElement.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.PropertyCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }
            }
            else if (currentobj.Meta.Name == typeof(CyPhy.DesignContainer).Name)
            {
                var component = CyPhyClasses.DesignContainer.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not  shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.PropertyCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }
            }
            else if (currentobj.Meta.Name == typeof(CyPhy.TestComponent).Name)
            {
                var component = CyPhyClasses.TestComponent.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not  shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.PropertyCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.MetricCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        //GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        //continue;
                    }

                    parameterItems.Add(parameterItem);
                }
            }

            else if (currentobj.Meta.Name == typeof(CyPhy.TestBench).Name ||
                     currentobj.Meta.Name == typeof(CyPhy.BlastTestBench).Name ||
                     currentobj.Meta.Name == typeof(CyPhy.BallisticTestBench).Name ||
                     currentobj.Meta.Name == typeof(CyPhy.CADTestBench).Name ||
                     currentobj.Meta.Name == typeof(CyPhy.CFDTestBench).Name)
            {
                var component = CyPhyClasses.TestBenchType.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not  shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.PropertyCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.MetricCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        //GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        //continue;
                    }

                    parameterItems.Add(parameterItem);
                }
            }
            else if (currentobj.Meta.Name == typeof(CyPhy.TestBenchSuite).Name)
            {
                var component = CyPhyClasses.TestBenchSuite.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not  shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.MetricCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        //GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        //continue;
                    }

                    parameterItems.Add(parameterItem);
                }
            }

            parameterItems.Sort((x, y) => x.Name.CompareTo(y.Name));

            if (parameterItems.Any() == false)
            {
                GMEConsole.Warning.WriteLine("Please insert at least one non-derived Parameter/Property in the model.");
                return;
            }

            using (ComponentParameterForm cpForm = new ComponentParameterForm(currentobj))
            {
                cpForm.dgvParameters.DataSource = new BindingList <ComponentParameterItem>(parameterItems);
                if (mdiClient != IntPtr.Zero)
                {
                    // TODO: would be nice to attach the form to the MDIClient window.
                    var parentWindow = new NativeWindowWrapper(mdiClient);
                    var dialogResult = cpForm.ShowDialog(parentWindow);
                }
                else
                {
                    var dialogResult = cpForm.ShowDialog();
                }
            }
        }
        public void Main(MgaProject project, MgaFCO currentobj, MgaFCOs selectedobjs, ComponentStartMode startMode)
        {

            // 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
            // [ParadigmName].[KindName] dsCurrentObj = ISIS.GME.Dsml.[ParadigmName].Classes.[KindName].Cast(currentobj);

            // TODO: find model editor window and open form inside it. Would be nice to find it based on  C++ class.
            var mainHwd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;

            IntPtr mdiClient = IntPtr.Zero;

            foreach (var childHwd in GetChildWindows(mainHwd))
            {
                StringBuilder sb = new StringBuilder(100);
                GetClassName(childHwd, sb, 100);
                if ("MDIClient" == sb.ToString())
                {
                    mdiClient = childHwd;
                    break;
                }
            }

            //GMEConsole.Warning.WriteLine("Name: '{0}' Position: {1} {2} {3} {4}", name, rr.Top, rr.Left, rr.Bottom, rr.Right);

            List<string> supportedKinds = new List<string>()
            {
                typeof(CyPhy.Component).Name,
                typeof(CyPhy.ComponentAssembly).Name,
                typeof(CyPhy.TestComponent).Name,
                typeof(CyPhy.DesignContainer).Name,
                typeof(CyPhy.TestBench).Name,
                typeof(CyPhy.BlastTestBench).Name,
                typeof(CyPhy.BallisticTestBench).Name,
                typeof(CyPhy.CADTestBench).Name,
                typeof(CyPhy.CFDTestBench).Name,
                typeof(CyPhy.TestBenchSuite).Name,
            };

            if (currentobj == null ||
                supportedKinds.Contains(currentobj.Meta.Name) == false)
            {
                GMEConsole.Warning.WriteLine("One of the following object types must be open in the editor: {0}", string.Join(", ", supportedKinds));
                return;
            }

            List<ComponentParameterItem> parameterItems = new List<ComponentParameterItem>();

            if (currentobj.Meta.Name == typeof(CyPhy.Component).Name ||
                currentobj.Meta.Name == typeof(CyPhy.ComponentAssembly).Name)
            {
                var component = CyPhyClasses.DesignElement.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.PropertyCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }
            }
            else if (currentobj.Meta.Name == typeof(CyPhy.DesignContainer).Name)
            {
                var component = CyPhyClasses.DesignContainer.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not  shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.PropertyCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

            }
            else if (currentobj.Meta.Name == typeof(CyPhy.TestComponent).Name)
            {
                var component = CyPhyClasses.TestComponent.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not  shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.PropertyCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.MetricCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        //GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        //continue;
                    }

                    parameterItems.Add(parameterItem);
                }
            }

            else if (currentobj.Meta.Name == typeof(CyPhy.TestBench).Name ||
                currentobj.Meta.Name == typeof(CyPhy.BlastTestBench).Name ||
                currentobj.Meta.Name == typeof(CyPhy.BallisticTestBench).Name ||
                currentobj.Meta.Name == typeof(CyPhy.CADTestBench).Name ||
                currentobj.Meta.Name == typeof(CyPhy.CFDTestBench).Name)
            {
                var component = CyPhyClasses.TestBenchType.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not  shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.PropertyCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.MetricCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        //GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        //continue;
                    }

                    parameterItems.Add(parameterItem);
                }
            }
            else if (currentobj.Meta.Name == typeof(CyPhy.TestBenchSuite).Name)
            {
                var component = CyPhyClasses.TestBenchSuite.Cast(currentobj);

                foreach (var item in component.Children.ParameterCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not  shown in list.", item.Name);
                        continue;
                    }

                    parameterItems.Add(parameterItem);
                }

                foreach (var item in component.Children.MetricCollection)
                {
                    var parameterItem = new ComponentParameterItem(item.Impl as MgaFCO);

                    if (item.SrcConnections.ValueFlowCollection.Where(x => x.ParentContainer.ID == item.ParentContainer.ID).Count() > 0)
                    {
                        // skip derived parameters
                        //GMEConsole.Info.WriteLine("{0} is a derived parameter; it is not shown in list.", item.Name);
                        //continue;
                    }

                    parameterItems.Add(parameterItem);
                }
            }

            parameterItems.Sort((x, y) => x.Name.CompareTo(y.Name));

            if (parameterItems.Any() == false)
            {
                GMEConsole.Warning.WriteLine("Please insert at least one non-derived Parameter/Property in the model.");
                return;
            }

            using (ComponentParameterForm cpForm = new ComponentParameterForm(currentobj))
            {
                cpForm.dgvParameters.DataSource = new BindingList<ComponentParameterItem>(parameterItems);
                if (mdiClient != IntPtr.Zero)
                {
                    // TODO: would be nice to attach the form to the MDIClient window.
                    var parentWindow = new WindowWrapper(mdiClient);
                    var dialogResult = cpForm.ShowDialog(parentWindow);
                }
                else
                {
                    var dialogResult = cpForm.ShowDialog();
                }
            }
        }