void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            lock (_lock)
            {
                Program.Invoke(this, () =>
                                         {
                                             dataGridView1.Rows.Clear();
                                             progressBar1.Value = 0;
                                         });

                RevertActions.Clear();
                List<KeyValuePair<string, List<Check>>> checks = GenerateChecks();
                _numberChecks = checks.Count;
                for (int i = 0; i < checks.Count; i++)
                {
                    List<Check> checkGroup = checks[i].Value;
                    DataGridViewRow row =
                        new PreCheckHeaderRow(string.Format(Messages.DR_WIZARD_PRECHECKPAGE_HEADER, i + 1,
                                                            checks.Count, checks[i].Key));
                    _worker.ReportProgress(5, row);

                    Session metadataSession = null;

                    // execute checks
                    for (int j = 0; j < checkGroup.Count; j++)
                    {
                        if (_worker.CancellationPending)
                        {
                            e.Cancel = true;
                            return;
                        }
                        Check check = checkGroup[j];

                        // special case - AssertCanBeRecoveredCheck - we need to open the metadata database
                        if (check is AssertCanBeRecoveredCheck)
                        {
                            AssertCanBeRecoveredCheck thisCheck = check as AssertCanBeRecoveredCheck;
                            AssertCanBeRecoveredCheck prevCheck = j > 0
                                                                      ? checkGroup[j - 1] as
                                                                        AssertCanBeRecoveredCheck
                                                                      : null;
                            if (prevCheck == null || prevCheck.Vdi.uuid != thisCheck.Vdi.uuid)
                            {
                                // close previous metadata session
                                if (metadataSession != null)
                                    metadataSession.logout();

                                // open metadata database
                                VdiOpenDatabaseAction action = new VdiOpenDatabaseAction(Connection,
                                                                                         ((AssertCanBeRecoveredCheck
                                                                                          )checkGroup[0]).Vdi);
                                action.RunExternal(action.Session);
                                if (action.Succeeded && action.MetadataSession != null)
                                    metadataSession = action.MetadataSession;
                            }

                            // run check
                            if (metadataSession != null)
                            {
                                thisCheck.MetadataSession = metadataSession;
                                row = ExecuteCheck(thisCheck);
                                _worker.ReportProgress(PercentageSelectedObjects(j + 1), row);

                                // close metadata session if this is the last check
                                if (j == checkGroup.Count - 1)
                                    metadataSession.logout();
                            }
                        }
                        else
                        {
                            row = ExecuteCheck(check);
                            _worker.ReportProgress(PercentageSelectedObjects(j + 1), row);
                        }
                    }
                }
            }
        }
        List<AsyncAction> CreateSubActionsFor(PoolMetadata poolMetadata)
        {
            log.DebugFormat("Generating recovery actions from pool {0} (VDI {1})", poolMetadata.Pool.Name, poolMetadata.Vdi.Name);
                
            List<AsyncAction> subActions = new List<AsyncAction>();

            VdiOpenDatabaseAction openDatabaseAction = new VdiOpenDatabaseAction(Connection, poolMetadata.Vdi);
            openDatabaseAction.Completed += OpenDatabaseActionCompleted;

            subActions.Add(openDatabaseAction);

            foreach (var vmAppliance in poolMetadata.VmAppliances.Values)
            {
                DrRecoverAction drRecoverAction = new DrRecoverAction(Connection, vmAppliance);
                drRecoverAction.Completed += SingleRecoverActionCompleted;
                drRecoverAction.Changed += SingleRecoverActionChanged;
                subActions.Add(drRecoverAction);
                dataGridView1.Rows.Add(new DataGridViewRowRecover(vmAppliance));
                objectsToBeRecovered++;
            }

            foreach (var vm in poolMetadata.Vms.Values)
            {
                if (vm.appliance.opaque_ref != null && vm.appliance.opaque_ref.StartsWith("OpaqueRef:") && vm.appliance.opaque_ref != "OpaqueRef:NULL")
                {
                    //VM included in an appliance
                    continue;
                }
                DrRecoverAction drRecoverAction = new DrRecoverAction(Connection, vm);
                drRecoverAction.Completed += SingleRecoverActionCompleted;
                drRecoverAction.Changed += SingleRecoverActionChanged;
                subActions.Add(drRecoverAction);
                dataGridView1.Rows.Add(new DataGridViewRowRecover(vm));
                objectsToBeRecovered++;
            }
            log.DebugFormat("Done - {0} actions generated", subActions.Count);
            
            return subActions;
        }