public void WriteSummary(MasterInterpreterResult[] results)
        {
            // Print Summary
            this.Logger.WriteInfo(" Summary ");

            if (results == null)
            {
                this.Logger.WriteInfo("No results to show");
            }
            else
            {
                // print sussess messages for the user
                var currentLevel = this.Logger.GMEConsoleLoggingLevel;

                try
                {
                    this.Logger.GMEConsoleLoggingLevel = CyPhyGUIs.SmartLogger.MessageType_enum.Success;

                    this.ExecuteInTransaction(this.Project, () =>
                    {
                        // print failure/success statistics
                        // user master interpreter's result set in case user canceled the execution
                        foreach (var result in results)
                        {
                            string message = string.Format(" {0} {1} {2} ",
                                GME.CSharp.GmeConsoleHelper.ToMgaHyperLink(result.Context, this.Logger.Traceability, true),
                                GME.CSharp.GmeConsoleHelper.ToMgaHyperLink(result.Configuration, this.Logger.Traceability, true),
                                result.Message);

                            if (result.Success)
                            {
                                this.Logger.WriteSuccess(message);
                            }
                            else
                            {
                                this.Logger.WriteFailed(message);
                                this.Logger.WriteDebug(result.Exception);
                            }
                        }
                    });
                }
                finally
                {
                    // change level back what ever it was
                    this.Logger.GMEConsoleLoggingLevel = currentLevel;
                }
            }
        }
        private MasterInterpreterResult RunAnalysisModelProcessors(
            IMgaModel context,
            IMgaFCO configuration,
            bool postToJobManager = false,
            bool keepTempModels = false)
        {
            if (context == null ||
                configuration == null)
            {
                throw new ArgumentNullException();
            }

            this.Logger.WriteDebug("Preparing analysis model processor");
            var result = new MasterInterpreterResult();
            result.Context = context;
            result.Configuration = configuration;
            result.Success = true;

            string contextName = string.Empty;
            string configurationName = string.Empty;

            AnalysisModelProcessor analysisModelProcessor = null;

            Exception exceptionToThrow = null;

            try
            {
                this.Logger.WriteDebug("Turning off addons for perfomance reasons: {0}", string.Join(", ", this.addonNames));
                this.TurnOffAddons(context);

                this.ExecuteInTransaction(context, () =>
                {
                    contextName = context.Name;
                    configurationName = configuration.Name;

                    this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                    {
                        Percent = 0,
                        Context = contextName,
                        Configuration = configuration.AbsPath,
                        Title = "Initializing"
                    });

                    // expand context for configuration
                    this.Logger.WriteDebug("Getting analysis model processor instance for {0} type", context.MetaBase.Name);
                    analysisModelProcessor = AnalysisModelProcessor.GetAnalysisModelProcessor(context);
                    this.Logger.WriteDebug("Got {0} for {1} {2}", analysisModelProcessor.GetType().Name, context.MetaBase.Name, context.AbsPath);

                    this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                    {
                        Percent = 25,
                        Context = contextName,
                        Configuration = configurationName,
                        Title = "Expanding"
                    });

                    if (configuration.MetaBase.Name == typeof(CyPhy.CWC).Name)
                    {
                        this.Logger.WriteDebug("{0} was specified as configuration. Start expanding it. {1}", configuration.MetaBase.Name, configuration.AbsPath);
                        analysisModelProcessor.Expand(CyPhyClasses.CWC.Cast(configuration));
                        this.Logger.WriteDebug("Expand finished for {0}", configuration.AbsPath);
                    }
                    else if (configuration.MetaBase.Name == typeof(CyPhy.ComponentAssembly).Name)
                    {
                        this.Logger.WriteDebug("{0} was specified as configuration. Start expanding it. {1}", configuration.MetaBase.Name, configuration.AbsPath);
                        analysisModelProcessor.Expand(CyPhyClasses.ComponentAssembly.Cast(configuration));
                        this.Logger.WriteDebug("Expand finished for {0}", configuration.AbsPath);
                    }
                    else
                    {
                        this.Logger.WriteDebug("{0} expand is not supported {1}", configuration.MetaBase.Name, configuration.AbsPath);
                        throw new AnalysisModelContextNotSupportedException("Configuration type is not supported. Use CWC or Component Assembly.");
                    }

                    // TODO: give progress update about exporters & their success

                    // design space might be saved multiple times

                    if (analysisModelProcessor.OriginalSystemUnderTest.AllReferred is CyPhy.DesignContainer)
                    {
                        this.Logger.WriteDebug("Calling design space exporter");
                        bool successDesignSpaceExport = analysisModelProcessor.SaveDesignSpace(this.ProjectManifest);

                        // FIXME: this would case the entire test bench to fail if it is a single configuration.
                        // result.Success = result.Success && successDesignSpaceExport;

                        if (successDesignSpaceExport)
                        {
                            this.Logger.WriteDebug("Design space exporter succeeded.");
                        }
                        else
                        {
                            this.Logger.WriteWarning("Design space exporter failed.");
                        }
                    }
                    else
                    {
                        this.Logger.WriteDebug("[SKIP] Calling design space exporter, since the test bench is defined over a design and not a design space.");
                    }

                    this.Logger.WriteDebug("Calling design exporter");
                    bool successDesignExport = analysisModelProcessor.SaveDesign(this.ProjectManifest);
                    // result.Success = result.Success && successDesignExport;

                    if (successDesignExport)
                    {
                        this.Logger.WriteDebug("Design exporter succeeded.");
                    }
                    else
                    {
                        this.Logger.WriteWarning("Design exporter failed.");
                    }

                    this.Logger.WriteDebug("Saving test bench definition");
                    bool successTestBench = analysisModelProcessor.SaveTestBench(this.ProjectManifest);
                    // result.Success = result.Success && successTestBench;

                    if (successTestBench)
                    {
                        this.Logger.WriteDebug("Saving test bench definition succeeded.");
                    }
                    else
                    {
                        this.Logger.WriteWarning("Saving test bench definition failed.");
                    }

                    this.Logger.WriteDebug("Saving test bench manifest");
                    bool successTestBenchManifest = analysisModelProcessor.SaveTestBenchManifest(this.ProjectManifest);
                    result.Success = result.Success && successTestBenchManifest;

                    if (successTestBenchManifest)
                    {
                        this.Logger.WriteDebug("Saving test bench manifest succeeded.");
                    }
                    else
                    {
                        this.Logger.WriteError("Saving test bench manifest failed.");
                    }

                    this.Logger.WriteDebug("Serializing Project manifest file with updates.");
                    this.ProjectManifest.Serialize();
                    this.Logger.WriteDebug("Project manifest was successfully saved.");
                });

                this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                {
                    Percent = 45,
                    Context = contextName,
                    Configuration = configurationName,
                    Title = "Model is ready for interpreters"
                });

                if (this.IsInteractive)
                {
                    this.Logger.WriteDebug("Execution is interactive, showing interpreter configuration forms.");
                    analysisModelProcessor.ShowInterpreterConfigs(this.interpreterConfigurations);
                }
                else
                {
                    analysisModelProcessor.ShowInterpreterConfigs(this.interpreterConfigurations, interactive: false);
                    this.Logger.WriteDebug("Execution is non interactive, not showing interpreter configuration forms. Using settings from files.");
                }

                analysisModelProcessor.InterpreterProgress += (object sender, InterpreterProgressEventArgs e) =>
                {
                    var interpreterName = e.Interpreter == null ? string.Empty : e.Interpreter.Name;
                    this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                    {
                        Percent = 50 + (e.Percent / 5), // we have 20 percent room on the main progress
                        Context = contextName,
                        Configuration = configurationName,
                        Title = string.Format("Running interpreters {0}% {1} success status: {2}", e.Percent, interpreterName, e.Success)
                    });
                };

                this.Logger.WriteDebug("Running interpreters. Keeping temp models: {0}", keepTempModels);

                bool isVerbose = this.Logger.GMEConsoleLoggingLevel == CyPhyGUIs.SmartLogger.MessageType_enum.Debug;

                analysisModelProcessor.RunInterpreters(keepTempModels == false, isVerbose);
                result.OutputDirectory = analysisModelProcessor.OutputDirectory;

                this.Logger.WriteDebug("Interpreters finished.");

                this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                {
                    Percent = 70,
                    Context = contextName,
                    Configuration = configurationName,
                    Title = "All interpreters successfully finished"
                });

                this.ExecuteInTransaction(context, () =>
                {
                    if (postToJobManager)
                    {
                        this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                        {
                            Percent = 80,
                            Context = contextName,
                            Configuration = configurationName,
                            Title = "Posting to Job Manager"
                        });

                        if (this.Manager == null)
                        {
                            this.Logger.WriteDebug("Job manager instance is null. Initializing one.");
                            this.Manager = new JobManagerDispatch();
                            this.Logger.WriteDebug("Job manager dispatch is ready to receive jobs");
                        }

                        this.Logger.WriteDebug("Posting to the job manager");
                        var postedToJobManager = analysisModelProcessor.PostToJobManager(this.Manager);
                        result.Success = result.Success && postedToJobManager;

                        if (postedToJobManager)
                        {
                            this.Logger.WriteInfo("Job posted to the job manager: {0}", context.Name);
                        }
                        else
                        {
                            this.Logger.WriteError("Job was not posted to the job manager: {0}", context.Name);
                        }

                        this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                        {
                            Percent = 89,
                            Context = contextName,
                            Configuration = configurationName,
                            Title = "Posted to Job Manager"
                        });
                    }
                    else
                    {
                        this.Logger.WriteDebug("Not posting to the job manager");

                        this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                        {
                            Percent = 89,
                            Context = contextName,
                            Configuration = configurationName,
                            Title = "Skip posting to Job Manager"
                        });
                    }
                });
            }
            catch (AnalysisModelInterpreterConfigurationFailedException ex)
            {
                this.Logger.WriteDebug(ex.ToString());
                result.Success = false;
                result.Message = ex.Message;
                result.Exception = ex.ToString();
                exceptionToThrow = ex;
            }
            catch (AnalysisModelInterpreterException ex)
            {
                this.Logger.WriteDebug(ex.ToString());
                result.Success = false;
                result.Message = ex.Message;
                result.Exception = ex.ToString();
            }
            catch (AnalysisModelExpandFailedException ex)
            {
                this.Logger.WriteDebug(ex.ToString());
                result.Success = false;
                result.Message = ex.Message;
                result.Exception = ex.ToString();
            }
            catch (Exception ex)
            {
                this.Logger.WriteDebug(ex.ToString());
                result.Success = false;
                result.Message = ex.Message;
                if (ex.InnerException != null)
                {
                    result.Message = string.Format("{0} ---> {1}", ex.Message, ex.InnerException.Message);
                }

                result.Exception = ex.ToString();
            }
            finally
            {
                // clean up if interpreter is canceled
                this.ExecuteInTransaction(context, () =>
                {
                    // destroy objects if keepTempModels == false
                    if (keepTempModels == false)
                    {
                        this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                        {
                            Percent = 90,
                            Context = contextName,
                            Configuration = configurationName,
                            Title = "Removing temporary models"
                        });

                        this.Logger.WriteDebug("Removing temporary models.");

                        analysisModelProcessor.DeleteTemporaryObjects();

                        this.Logger.WriteDebug("Temporary models are removed.");

                        this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                        {
                            Percent = 100,
                            Context = contextName,
                            Configuration = configurationName,
                            Title = "Removing temporary models"
                        });
                    }
                    else
                    {
                        this.OnSingleConfigurationProgress(new ProgressCallbackEventArgs()
                        {
                            Percent = 100,
                            Context = contextName,
                            Configuration = configurationName,
                            Title = "Keeping temporary models"
                        });
                    }
                });

                this.Logger.WriteDebug("Turning addons back on: {0}", string.Join(", ", this.addonNames));
                this.TurnOnAddons(context);
            }

            if (exceptionToThrow != null)
            {
                this.Logger.WriteDebug(exceptionToThrow.ToString());
                throw exceptionToThrow;
            }

            return result;
        }