/// <summary>
    /// Starts an application in a separate AppDomain.
    /// Loads all enabled plugins and starts the application via an ApplicationManager instance activated in the new AppDomain.
    /// </summary>
    /// <param name="appInfo">application to run</param>
    public void Run(ApplicationDescription appInfo, ICommandLineArgument[] args) {
      if (!initialized) throw new InvalidOperationException("PluginManager is not initialized. DiscoverAndCheckPlugins() must be called before Run()");
      // create a separate AppDomain for the application
      // initialize the static ApplicationManager in the AppDomain
      // and remotely tell it to start the application

      OnApplicationStarting(new PluginInfrastructureEventArgs(appInfo));
      AppDomain applicationDomain = null;
      try {
        AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
        setup.PrivateBinPath = pluginDir;
        applicationDomain = AppDomain.CreateDomain(AppDomain.CurrentDomain.FriendlyName, null, setup);
        Type applicationManagerType = typeof(DefaultApplicationManager);
        DefaultApplicationManager applicationManager =
          (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap(applicationManagerType.Assembly.FullName, applicationManagerType.FullName, true, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null, null);
        applicationManager.PluginLoaded += applicationManager_PluginLoaded;
        applicationManager.PluginUnloaded += applicationManager_PluginUnloaded;
        applicationManager.PrepareApplicationDomain(applications, plugins);
        OnApplicationStarted(new PluginInfrastructureEventArgs(appInfo));
        applicationManager.Run(appInfo, args);
      }
      finally {
        // make sure domain is unloaded in all cases
        AppDomain.Unload(applicationDomain);
      }
    }
    private void DiscoverApplications(IEnumerable<PluginDescription> pluginDescriptions) {
      applications = new List<ApplicationDescription>();
      foreach (IApplication application in GetApplications(pluginDescriptions)) {
        Type appType = application.GetType();
        ApplicationAttribute attr = (from x in appType.GetCustomAttributes(typeof(ApplicationAttribute), false)
                                     select (ApplicationAttribute)x).Single();
        ApplicationDescription info = new ApplicationDescription();
        PluginDescription declaringPlugin = GetDeclaringPlugin(appType, pluginDescriptions);
        info.Name = application.Name;
        info.Version = declaringPlugin.Version;
        info.Description = application.Description;
        info.AutoRestart = attr.RestartOnErrors;
        info.DeclaringAssemblyName = appType.Assembly.GetName().Name;
        info.DeclaringTypeName = appType.Namespace + "." + application.GetType().Name;

        applications.Add(info);
      }
    }
 private void StartApplication(ApplicationDescription app, ICommandLineArgument[] args) {
   splashScreen.Show("Loading " + app.Name);
   Thread t = new Thread(delegate() {
     bool stopped = false;
     do {
       try {
         if (!abortRequested) {
           pluginManager.Run(app, args);
         }
         stopped = true;
       }
       catch (Exception ex) {
         stopped = false;
         ThreadPool.QueueUserWorkItem(delegate(object exception) { ErrorHandling.ShowErrorDialog(this, (Exception)exception); }, ex);
         Thread.Sleep(5000); // sleep 5 seconds before autorestart
       }
     } while (!abortRequested && !stopped && app.AutoRestart);
   });
   t.SetApartmentState(ApartmentState.STA); // needed for the AdvancedOptimizationFrontent
   t.Start();
 }