async Task ExecuteSolutionItemAsync (ProgressMonitor monitor, IBuildTarget entry, ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration)
		{
			try {
				OnBeforeStartProject ();
				if (entry is IRunTarget)
					await ((IRunTarget)entry).Execute (monitor, context, configuration, runConfiguration);
				else
					await entry.Execute (monitor, context, configuration);
			} catch (Exception ex) {
				monitor.ReportError (GettextCatalog.GetString ("Execution failed."), ex);
				LoggingService.LogError ("Execution failed", ex);
			} finally {
				monitor.Dispose ();
			}
		}
		async Task<bool> CheckAndBuildForExecute (IBuildTarget executionTarget, ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration)
		{
			if (currentBuildOperation != null && !currentBuildOperation.IsCompleted) {
				var bres = await currentBuildOperation.Task;
				if (bres.HasErrors || !IdeApp.Preferences.RunWithWarnings && bres.HasWarnings)
					return false;
			}

			//saves open documents since it may dirty the "needs building" check
			var r = await DoBeforeCompileAction ();
			if (r.Failed)
				return false;

			var buildTarget = executionTarget;
			var buildDeps = buildTarget.GetExecutionDependencies ().ToList ();
			if (buildDeps.Count > 1)
				throw new NotImplementedException ("Multiple execution dependencies not yet supported");
			if (buildDeps.Count != 0)
				buildTarget = buildDeps [0];

			bool needsBuild = FastCheckNeedsBuild (buildTarget, configuration);
			if (!needsBuild) {
				return true;
			}

			if (IdeApp.Preferences.BuildBeforeExecuting) {
				// Building the project may take some time, so we call PrepareExecution so that the target can
				// prepare the execution (for example, it could start a simulator).
				var cs = new CancellationTokenSource ();
				Task prepareExecution;
				if (buildTarget is IRunTarget)
					prepareExecution = ((IRunTarget)buildTarget).PrepareExecution (new ProgressMonitor ().WithCancellationSource (cs), context, configuration, runConfiguration);
				else
					prepareExecution = buildTarget.PrepareExecution (new ProgressMonitor ().WithCancellationSource (cs), context, configuration);
				
				var result = await Build (buildTarget, true).Task;

				if (result.HasErrors || (!IdeApp.Preferences.RunWithWarnings && result.HasWarnings)) {
					cs.Cancel ();
					return false;
				}
				else {
					await prepareExecution;
					return true;
				}
			}

			var bBuild = new AlertButton (GettextCatalog.GetString ("Build"));
			var bRun = new AlertButton (Gtk.Stock.Execute, true);
			var res = MessageService.AskQuestion (
				GettextCatalog.GetString ("Outdated Build"),
				GettextCatalog.GetString ("The project you are executing has changes done after the last time it was compiled. Do you want to continue?"),
				2,
				AlertButton.Cancel,
				bBuild,
				bRun);

			// This call is a workaround for bug #6907. Without it, the main monodevelop window is left it a weird
			// drawing state after the message dialog is shown. This may be a gtk/mac issue. Still under research.
			DispatchService.RunPendingEvents ();

			if (res == bRun) {
				return true;
			}

			if (res == bBuild) {
				// Building the project may take some time, so we call PrepareExecution so that the target can
				// prepare the execution (for example, it could start a simulator).
				var cs = new CancellationTokenSource ();

				Task prepareExecution;
				if (buildTarget is IRunTarget)
					prepareExecution = ((IRunTarget)buildTarget).PrepareExecution (new ProgressMonitor ().WithCancellationSource (cs), context, configuration, runConfiguration);
				else
					prepareExecution = buildTarget.PrepareExecution (new ProgressMonitor ().WithCancellationSource (cs), context, configuration);
				
				var result = await Build (buildTarget, true).Task;

				if (result.HasErrors || (!IdeApp.Preferences.RunWithWarnings && result.HasWarnings)) {
					cs.Cancel ();
					return false;
				}
				else {
					await prepareExecution;
					return true;
				}
			}

			return false;
		}
		async Task ExecuteAsync (IBuildTarget entry, ExecutionContext context, CancellationTokenSource cs, ConfigurationSelector configuration, RunConfiguration runConfiguration, bool buildBeforeExecuting)
		{
			if (configuration == null)
				configuration = IdeApp.Workspace.ActiveConfiguration;
			
			var bth = context.ExecutionHandler as IConfigurableExecutionHandler;
			var rt = entry as IRunTarget;
			if (bth != null && rt != null) {
				var h = await bth.Configure (rt, context, configuration, runConfiguration);
				if (h == null)
					return;
				context = new ExecutionContext (h, context.ConsoleFactory, context.ExecutionTarget);
			}
			
			if (buildBeforeExecuting) {
				if (!await CheckAndBuildForExecute (entry, context, configuration, runConfiguration))
					return;
			}

			ProgressMonitor monitor = new ProgressMonitor (cs);

			var t = ExecuteSolutionItemAsync (monitor, entry, context, configuration, runConfiguration);

			var op = new AsyncOperation (t, cs);
			CurrentRunOperation = op;
			currentRunOperationOwner = entry;

			await t;

			var error = monitor.Errors.FirstOrDefault ();
			if (error != null)
				IdeApp.Workbench.StatusBar.ShowError (error.DisplayMessage);
			currentRunOperationOwner = null;
		}
		public AsyncOperation Execute (IBuildTarget entry, ExecutionContext context, ConfigurationSelector configuration = null, RunConfiguration runConfiguration = null, bool buildBeforeExecuting = true)
		{
			if (currentRunOperation != null && !currentRunOperation.IsCompleted) return currentRunOperation;

			var cs = new CancellationTokenSource ();
			return new AsyncOperation (ExecuteAsync (entry, context, cs, configuration, runConfiguration, buildBeforeExecuting), cs);
		}
		public AsyncOperation Execute (IBuildTarget entry, IExecutionHandler handler, ConfigurationSelector configuration = null, RunConfiguration runConfiguration = null, bool buildBeforeExecuting = true)
		{
			ExecutionContext context = new ExecutionContext (handler, IdeApp.Workbench.ProgressMonitors.ConsoleFactory, IdeApp.Workspace.ActiveExecutionTarget);
			return Execute (entry, context, configuration, runConfiguration, buildBeforeExecuting);
		}
		internal bool Resolve (IRunTarget item)
		{
			if (RunConfiguration != null && Mode != null)
				return true;
			RunConfiguration = item.GetRunConfigurations ().FirstOrDefault (co => co.Id == runConfigurationId);
			if (RunConfiguration == null)
				return false;
			var ctx = new CommandExecutionContext (item, h => item.CanExecute (new MonoDevelop.Projects.ExecutionContext (h, null, IdeApp.Workspace.ActiveExecutionTarget), IdeApp.Workspace.ActiveConfiguration, RunConfiguration));
			IExecutionModeSet modeSet;
			IExecutionMode mode;
			if (!ExecutionModeCommandService.GetExecutionMode (ctx, executionModeId, out modeSet, out mode))
				return false;
			ModeSet = modeSet;
			Mode = mode;
			return true;
		}
		public ExecutionConfiguration (RunConfiguration runConfiguration, IExecutionModeSet modeSet, IExecutionMode mode)
		{
			ModeSet = modeSet;
			Mode = mode;
			RunConfiguration = runConfiguration;
			runConfigurationId = runConfiguration.Id;
			executionModeId = mode.Id;
		}