private void populateSpecsIfNeeded(string snapshotName, VMSource src)
        {
            switch (src)
            {
            case VMSource.configuredServer:
                populateSpecsIfNeeded_VMServer(snapshotName);
                break;

            case VMSource.XDLClusterBlades:
                populateSpecsIfNeeded_XDLCluster(snapshotName);
                break;

            default:
                throw new ArgumentOutOfRangeException("src", src, null);
            }
        }
        public hypervisor_vmware createHypervisorForNextFreeVMOrNull(string snapshotName = "clean", clientExecutionMethod execType = clientExecutionMethod.smbWithWMI, VMSource src = VMSource.configuredServer, string bladeID = null)
        {
            lock (hypervisorSpecLock)
            {
                populateSpecsIfNeeded(snapshotName, src);

                // Atomically find an unused VM, and mark it as in-use
                KeyValuePair <hypSpec_vmware, bool> hypKVP;
                lock (hypervisorSpecLock)
                {
                    KeyValuePair <hypSpec_vmware, bool>[] selectedHyp = hypervisorSpecs.Where(x => x.Value == false).ToArray();
                    if (selectedHyp.Length == 0)
                    {
                        // Allocation failed
                        return(null);
                    }
                    if (bladeID != null)
                    {
                        // We actually throw if a user filter returned nothing, for now.
                        selectedHyp = selectedHyp.Where(x => x.Key.kernelVMServer.ToLower().Contains(bladeID.ToLower())).ToArray();
                        if (selectedHyp.Length == 0)
                        {
                            throw new Exception("XDL blade not found");
                        }
                    }

                    hypKVP = selectedHyp.First();
                    hypervisorSpecs[hypKVP.Key] = true;
                }

                try
                {
                    hypervisor_vmware toRet = new hypervisor_vmware(hypKVP.Key, execType);
                    toRet.setDisposalCallback(onDestruction);
                    return(toRet);
                }
                catch (Exception)
                {
                    lock (hypervisorSpecLock)
                    {
                        hypervisorSpecs[hypKVP.Key] = false;
                        throw;
                    }
                }
            }
        }
        public hypervisorCollection <hypSpec_vmware> createVMs(int VMsToAlloc, string snapshotName = "clean", clientExecutionMethod execType = clientExecutionMethod.smbWithWMI, VMSource src = VMSource.configuredServer, string bladeID = null)
        {
            hypervisorCollection <hypSpec_vmware> hyps = new hypervisorCollection <hypSpec_vmware>();

            for (int i = 0; i < VMsToAlloc; i++)
            {
                hypervisor_vmware thisHyp = machinePools.vmware.createHypervisorForNextFreeVMOrNull(snapshotName, execType, src, bladeID);
                if (thisHyp == null)
                {
                    break;
                }
                hyps.TryAdd(thisHyp.getConnectionSpec().kernelDebugIPOrHostname, thisHyp);
            }

            return(hyps);
        }
        public hypervisor_vmware createHypervisorForNextFreeVMOrWait(string snapshotName = "clean", clientExecutionMethod execType = clientExecutionMethod.smbWithWMI, string bladeID = null, VMSource src = VMSource.configuredServer)
        {
            while (true)
            {
                hypervisor_vmware toRet = createHypervisorForNextFreeVMOrNull(snapshotName, execType, bladeID: bladeID, src: src);
                if (toRet != null)
                {
                    return(toRet);
                }

                Thread.Sleep(TimeSpan.FromSeconds(5));
            }
        }