public static MmiModelClient StartModel(string library, string configFile, bool createNoWindow = false, params string[] options)
        {
            // start runner
            var info = new MmiRunnerInfo
            {
                Port = currentPort++,
                ConfigFilePath = configFile,
                Library = library
            };

            var arguments = string.Format("{0} {1} --pause --disable-logger --port {2} {3}", info.Library, info.ConfigFilePath, info.Port, String.Join(@" ", options));

            info.Process = new Process
            {
                StartInfo = new ProcessStartInfo(MmiRunnerPath, arguments)
                {
                    WindowStyle = ProcessWindowStyle.Hidden,
                    WorkingDirectory = Path.GetDirectoryName(configFile),
                    CreateNoWindow = createNoWindow,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                }
            };

            info.LogFilePath = "mmi-runner-" + Path.GetFileName(configFile) + "-" + info.Port + ".log";

            if (File.Exists(info.LogFilePath))
            {
                File.Delete(info.LogFilePath);
            }

            info.Process.OutputDataReceived += (sender, args) => WriteOutput(info, args.Data);
            info.Process.ErrorDataReceived += (sender, args) => WriteOutput(info, args.Data);
            info.Process.EnableRaisingEvents = true;
            info.Process.Exited += (sender, args) => ProcessOnExited(sender, args, info);

            info.Process.Start();

            info.Process.BeginOutputReadLine();
            info.Process.BeginErrorReadLine();

            runners.Add(info);

            if (info.Process.HasExited)
            {
                throw new Exception("Can't start MMI runner");
            }

            // connect client
            var client = new MmiModelClient("tcp://localhost:" + info.Port);
            client.Connect();
            clients.Add(client);

            return client;
        }
 private static void WriteOutput(MmiRunnerInfo info, string str)
 {
     lock (info)
     {
         File.AppendAllText(info.LogFilePath, str + "\n");
     }
 }
        private static void ProcessOnExited(object sender, EventArgs eventArgs, MmiRunnerInfo info)
        {
            var index = runners.IndexOf(info);
            clients[index].IsServerExited = true;

            Console.WriteLine("Model runner process has exited");
            // TODO: cleanup
        }