public Execution AsyncBeginApply(Migration migration, Instance instance)
        {
            ProjectHistoryStep historyStep = new ProjectHistoryStep();
            historyStep.Description = string.Format("Applying migration {0} ({1}) on instance {2}.", migration.Id, migration.Description, instance.FullName);
            historyStep.At = clock.Now;
            historyStep.By = appContext.FullUserName;
            historyStep.Project = migration.AuditProject;
            historyStep.Create();

            Execution execution = new Execution();
            execution.At = clock.Now;
            execution.By = appContext.FullUserName;
            execution.Migration = migration;
            execution.Instance = instance;
            execution.ExecutionState = ExecutionState.Pending;
            execution.AppendLog("Starting migration {0}({1}) on {2}...", migration.Id, migration.Description, instance.FullName);
            execution.CreateAndFlush();
            try
            {
                migrationTablesManager.CheckAndCreateMigrationTable(instance, execution);
                execution.UpdateAndFlush();
                if (!migrationTablesManager.IsMigrationAlreadyApplied(migration, instance, execution))
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object arg)
                    {
                        SyncApplyMigration(migration, instance, execution);
                    }));
                }
                else
                {
                    execution.ExecutionState = ExecutionState.Completed;
                    execution.UpdateAndFlush();
                }

            }
            catch (Exception ex)
            {
                execution.AppendLogException(ex);
                execution.UpdateAndFlush();
            }

            return execution;
        }