public string GetWorkflowCode(IFlowSharpCodeService codeService, BaseController canvasController, GraphicElement wf)
        {
            StringBuilder  sb               = new StringBuilder();
            string         packetName       = Clifton.Core.ExtensionMethods.ExtensionMethods.LeftOf(wf.Text, "Workflow");
            GraphicElement elDefiningPacket = FindPacket(canvasController, packetName);

            if (elDefiningPacket == null)
            {
                ServiceManager.Get <IFlowSharpCodeOutputWindowService>().WriteLine("Workflow packet '" + packetName + "' must be defined.");
            }
            else
            {
                bool packetHasParameterlessConstructor = HasParameterlessConstructor(GetCode(elDefiningPacket), packetName);

                // TODO: Hardcoded for now for POC.
                sb.AppendLine("// This code has been auto-generated by FlowSharpCode");
                sb.AppendLine("// Do not modify this code -- your changes will be overwritten!");
                sb.AppendLine("namespace App");
                sb.AppendLine("{");
                sb.AppendLine("\tpublic partial class " + wf.Text);
                sb.AppendLine("\t{");

                if (packetHasParameterlessConstructor)
                {
                    sb.AppendLine("\t\tpublic static void Execute()");
                    sb.AppendLine("\t\t{");
                    sb.AppendLine("\t\t\tExecute(new " + packetName + "());");
                    sb.AppendLine("\t\t}");
                    sb.AppendLine();
                }

                sb.AppendLine("\t\tpublic static void Execute(" + packetName + " packet)");
                sb.AppendLine("\t\t{");
                sb.AppendLine("\t\t\t" + wf.Text + " workflow = new " + wf.Text + "();");

                // Fill in the workflow steps.
                GraphicElement el = codeService.FindStartOfWorkflow(canvasController, wf);
                GenerateCodeForWorkflow(codeService, sb, el, 3);

                // We're all done.
                sb.AppendLine("\t\t}");
                sb.AppendLine("\t}");
                sb.AppendLine("}");
            }

            return(sb.ToString());
        }
        protected void DrakonWorkflowCodeGenerator(BaseController canvasController, GraphicElement elClass, string className, string filename)
        {
            IFlowSharpCodeService codeService = ServiceManager.Get <IFlowSharpCodeService>();
            GraphicElement        el          = codeService.FindStartOfWorkflow(canvasController, elClass);

            if (el == null)
            {
                var outputWindow = ServiceManager.Get <IFlowSharpCodeOutputWindowService>();
                outputWindow.Clear();
                outputWindow.WriteLine("Cannot find shape that is the start of the workflow.");
            }
            else
            {
                DrakonCodeTree dcg = new DrakonCodeTree();
                codeService.ParseDrakonWorkflow(dcg, codeService, canvasController, el);
                var codeGenSvc = new PythonCodeGeneratorService();
                dcg.GenerateCode(codeGenSvc);
                codeGenSvc.CodeResult.Insert(0, PYLINT + "\n");

                File.WriteAllText(filename, codeGenSvc.CodeResult.ToString());
                elClass.Json["python"] = codeGenSvc.CodeResult.ToString();
            }
        }
        public void Compile()
        {
            TerminateRunningProcess();

            var outputWindow = ServiceManager.Get <IFlowSharpCodeOutputWindowService>();

            outputWindow.Clear();

            IFlowSharpCanvasService canvasService    = ServiceManager.Get <IFlowSharpCanvasService>();
            IFlowSharpMenuService   menuService      = ServiceManager.Get <IFlowSharpMenuService>();
            IFlowSharpCodeService   codeService      = ServiceManager.Get <IFlowSharpCodeService>();
            BaseController          canvasController = canvasService.ActiveController;

            tempToTextBoxMap.Clear();

            List <GraphicElement> compiledAssemblies = new List <GraphicElement>();
            bool ok = CompileAssemblies(canvasController, compiledAssemblies);

            if (!ok)
            {
                DeleteTempFiles();
                return;
            }

            List <string> refs    = new List <string>();
            List <string> sources = new List <string>();

            // Add specific assembly references on the drawing.
            List <IAssemblyReferenceBox> references = GetReferences(canvasController);

            refs.AddRange(references.Select(r => r.Filename));

            List <GraphicElement> rootSourceShapes = GetSources(canvasController);

            rootSourceShapes.ForEach(root => GetReferencedAssemblies(root).Where(refassy => refassy is IAssemblyBox).ForEach(refassy => refs.Add(((IAssemblyBox)refassy).Filename)));

            // Get code for workflow boxes first, as this code will then be included in the rootSourceShape code listing.
            IEnumerable <GraphicElement> workflowShapes = canvasController.Elements.Where(el => el is IWorkflowBox);

            workflowShapes.ForEach(wf =>
            {
                string code     = GetWorkflowCode(codeService, canvasController, wf);
                wf.Json["Code"] = code;
            });

            List <GraphicElement> excludeClassShapes = new List <GraphicElement>();
            List <GraphicElement> classes            = GetClasses(canvasController);

            // Get CSharpClass shapes that contain DRAKON shapes.
            classes.Where(cls => HasDrakonShapes(canvasController, cls)).ForEach(cls =>
            {
                excludeClassShapes.AddRange(canvasController.Elements.Where(el => cls.DisplayRectangle.Contains(el.DisplayRectangle)));
                DrakonCodeTree dcg = new DrakonCodeTree();
                var workflowStart  = codeService.FindStartOfWorkflow(canvasController, cls);
                codeService.ParseDrakonWorkflow(dcg, codeService, canvasController, workflowStart);
                var codeGenSvc = new CSharpCodeGeneratorService();
                dcg.GenerateCode(codeGenSvc);
                InsertCodeInRunWorkflowMethod(cls, codeGenSvc.CodeResult);
                string filename = CreateCodeFile(cls);
                sources.Add(filename);
            });

            rootSourceShapes.Where(root => !excludeClassShapes.Contains(root)).ForEach(root =>
            {
                // Get all other shapes that are not part of CSharpClass shapes:
                // TODO: Better Linq!
                if (!String.IsNullOrEmpty(GetCode(root)))
                {
                    string filename = CreateCodeFile(root);
                    sources.Add(filename);
                }
            });

            exeFilename = String.IsNullOrEmpty(menuService.Filename) ? "temp.exe" : Path.GetFileNameWithoutExtension(menuService.Filename) + ".exe";
            Compile(exeFilename, sources, refs, true);
            DeleteTempFiles();

            if (!results.Errors.HasErrors)
            {
                outputWindow.WriteLine("No Errors");
            }
        }