public static MonoMacProcess OpenApplication (MonoMacExecutionCommand command, ApplicationStartInfo asi,
			Action<string> stdout, Action<string> stderr)
		{
			var logDir = command.AppPath.ParentDirectory;
			var outLog = logDir.Combine ("stdout.log");
			var errLog = logDir.Combine ("stderr.log");
			try {
				if (File.Exists (errLog))
				    File.Delete (errLog);
				if (File.Exists (outLog))
					File.Delete (outLog);
			} catch (IOException) {}
			
			var outTail = new Tail (outLog, stdout);
			var errTail = new Tail (errLog, stderr);
			outTail.Start ();
			errTail.Start ();
			
			if (asi == null)
				asi = new ApplicationStartInfo (command.AppPath);
			asi.NewInstance = true;
			
			//need async or we won't be able to debug things that happen while the app is launching
			asi.Async = true;
			
			var monoRuntime = (MonoDevelop.Core.Assemblies.MonoTargetRuntime)command.Runtime;
			
			//assume MD is running on /L/F/M.f/V/Current
			//if target runtime is different then override for bundle
			if (!monoRuntime.IsRunning) {
				asi.Environment ["MONOMAC_DEBUGLAUNCHER_RUNTIME"] = monoRuntime.Prefix;
			}
			
			asi.Environment ["MONOMAC_DEBUGLAUNCHER_LOGDIR"] = logDir;
			
			var psn = LaunchServices.OpenApplication (asi);
			return new MonoMacProcess (psn, outTail, errTail);
		}
		void Dispose (bool disposing)
		{
			if (disposing) {
				if (outTail != null) {
					outTail.Dispose ();
					outTail = null;
				}
				if (errTail != null) {
					errTail.Dispose ();
					errTail = null;
				}
			}
		}
		public MonoMacProcess (ProcessSerialNumber psn, Tail outTail, Tail errTail)
		{
			this.psn = psn;
			
			this.pid = ProcessManager.GetProcessPid (psn);
			if (pid < 0)
				throw new Exception (string.Format ("Could not get PID for PSN {0} {1}", psn.High, psn.Low));
			
			this.outTail = outTail;
			this.errTail = errTail;
		}