public static IntResult ImportVirtualMachine(int packageId,
            int serviceId, string vmId,
            string osTemplateFile, string adminPassword,
            bool startShutdownAllowed, bool pauseResumeAllowed, bool rebootAllowed, bool resetAllowed, bool reinstallAllowed,
            string externalNicMacAddress, int[] externalAddresses,
            string managementNicMacAddress, int managementAddress)
        {
            // result object
            IntResult res = new IntResult();

            // meta item
            VirtualMachine item = null;

            try
            {
                #region Check account and space statuses
                // check account
                if (!SecurityContext.CheckAccount(res, DemandAccount.NotDemo | DemandAccount.IsActive | DemandAccount.IsAdmin))
                    return res;

                // check package
                if (!SecurityContext.CheckPackage(res, packageId, DemandPackage.IsActive))
                    return res;

                #endregion

                // load package context
                PackageContext cntx = PackageController.GetPackageContext(packageId);

                item = new VirtualMachine();
                item.ServiceId = serviceId;
                item.PackageId = packageId;
                item.VirtualMachineId = vmId;

                // load service settings
                StringDictionary settings = ServerController.GetServiceSettings(serviceId);

                // load virtual machine info from service
                VirtualizationServer2012 vs = GetVirtualizationProxy(serviceId);
                VirtualMachine vm = vs.GetVirtualMachineEx(vmId);

                // set VM properties
                item.Name = vm.Name;
                item.ProvisioningStatus = VirtualMachineProvisioningStatus.OK;

                item.Generation = vm.Generation;
                item.CpuCores = vm.CpuCores;
                item.RamSize = vm.RamSize;
                item.DynamicMemory = vm.DynamicMemory;
                item.HddSize = vm.HddSize;
                item.VirtualHardDrivePath = vm.VirtualHardDrivePath;
                item.RootFolderPath = Path.GetDirectoryName(vm.VirtualHardDrivePath);
                item.SnapshotsNumber = cntx.Quotas[Quotas.VPS2012_SNAPSHOTS_NUMBER].QuotaAllocatedValue;
                item.DvdDriveInstalled = vm.DvdDriveInstalled;
                item.BootFromCD = vm.BootFromCD;
                item.NumLockEnabled = vm.NumLockEnabled;
                item.StartTurnOffAllowed = startShutdownAllowed;
                item.PauseResumeAllowed = pauseResumeAllowed;
                item.RebootAllowed = rebootAllowed;
                item.ResetAllowed = resetAllowed;
                item.ReinstallAllowed = reinstallAllowed;

                // remote desktop
                if(!String.IsNullOrEmpty(adminPassword))
                {
                    item.RemoteDesktopEnabled = true;
                    item.AdministratorPassword = CryptoUtils.Encrypt(adminPassword);
                }

                // set OS template
                string templatesPath = settings["OsTemplatesPath"];
                var correctVhdPath = GetCorrectTemplateFilePath(templatesPath, osTemplateFile);
                item.OperatingSystemTemplatePath = correctVhdPath;
                try
                {
                    LibraryItem[] osTemplates = GetOperatingSystemTemplatesByServiceId(serviceId);
                    foreach (LibraryItem osTemplate in osTemplates)
                    {
                        if (String.Compare(osTemplate.Path, osTemplateFile, true) == 0)
                        {
                            item.OperatingSystemTemplate = osTemplate.Name;
                            item.LegacyNetworkAdapter = osTemplate.LegacyNetworkAdapter;
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    res.AddError(VirtualizationErrorCodes.GET_OS_TEMPLATES_ERROR, ex);
                    return res;
                }

                // save item
                int itemId = PackageController.AddPackageItem(item);
                item.Id = itemId;
                res.Value = itemId;

                #region Setup external network
                // setup external network
                if (!String.IsNullOrEmpty(externalNicMacAddress))
                {
                    item.ExternalNetworkEnabled = true;
                    item.ExternalNicMacAddress = externalNicMacAddress;
                    item.ExternalSwitchId = settings["ExternalNetworkId"];

                    // assign selected IP addresses to package
                    ServerController.AllocatePackageIPAddresses(packageId, externalAddresses);

                    // re-read package IPs
                    List<PackageIPAddress> packageIPs = ServerController.GetPackageUnassignedIPAddresses(
                                    packageId, IPAddressPool.VpsExternalNetwork);

                    // assign IP addresses to VM
                    for(int i = 0; i < externalAddresses.Length; i++)
                    {
                        foreach (PackageIPAddress ip in packageIPs)
                        {
                            if (ip.AddressID == externalAddresses[i])
                            {
                                // assign to the item
                                ServerController.AddItemIPAddress(itemId, ip.PackageAddressID);

                                // set primary IP address
                                if(i == 0)
                                    ServerController.SetItemPrimaryIPAddress(itemId, ip.PackageAddressID);

                                break;
                            }
                        }
                    }
                }
                #endregion

                #region Setup management network
                // setup management network
                if (!String.IsNullOrEmpty(managementNicMacAddress))
                {
                    item.ManagementNetworkEnabled = true;
                    item.ManagementNicMacAddress = managementNicMacAddress;
                    item.ManagementSwitchId = settings["ManagementNetworkId"];

                    // assign selected IP addresses to package
                    ServerController.AllocatePackageIPAddresses(packageId, new int[] { managementAddress });

                    // re-read package IPs
                    List<PackageIPAddress> packageIPs = ServerController.GetPackageUnassignedIPAddresses(
                                    packageId, IPAddressPool.VpsManagementNetwork);

                    // assign IP addresses to VM
                    foreach (PackageIPAddress ip in packageIPs)
                    {
                        if (ip.AddressID == managementAddress)
                        {
                            // assign to the item
                            ServerController.AddItemIPAddress(itemId, ip.PackageAddressID);

                            break;
                        }
                    }
                }
                #endregion

                // save item once again
                PackageController.UpdatePackageItem(item);
            }
            catch (Exception ex)
            {
                res.AddError(VirtualizationErrorCodes.IMPORT_ERROR, ex);
                return res;
            }

            res.IsSuccess = true;
            return res;
        }
        public static IntResult CreateVirtualMachine(int packageId,
                string hostname, string osTemplateFile, string password, string summaryLetterEmail,
                int cpuCores, int ramMB, int hddGB, int snapshots,
                bool dvdInstalled, bool bootFromCD, bool numLock,
                bool startShutdownAllowed, bool pauseResumeAllowed, bool rebootAllowed, bool resetAllowed, bool reinstallAllowed,
                bool externalNetworkEnabled, int externalAddressesNumber, bool randomExternalAddresses, int[] externalAddresses,
                bool privateNetworkEnabled, int privateAddressesNumber, bool randomPrivateAddresses, string[] privateAddresses, VirtualMachine otherSettings)
        {
            // result object
            IntResult res = new IntResult();

            // meta item
            VirtualMachine vm = null;

            try
            {
                #region Check account and space statuses
                // check account
                if (!SecurityContext.CheckAccount(res, DemandAccount.NotDemo | DemandAccount.IsActive))
                    return res;

                // check package
                if (!SecurityContext.CheckPackage(res, packageId, DemandPackage.IsActive))
                    return res;
                
                #endregion

                #region Check if host name is already used

                try
                {
                    ServiceProviderItem item = PackageController.GetPackageItemByName(packageId, hostname,
                                                                                      typeof (VirtualMachine));
                    if (item != null)
                    {
                        res.ErrorCodes.Add(VirtualizationErrorCodes.HOST_NAMER_IS_ALREADY_USED);
                        return res;
                    }
                }
                catch(Exception ex)
                {
                    res.AddError(VirtualizationErrorCodes.CANNOT_CHECK_HOST_EXISTS, ex);
                    return res;   
                }

                #endregion

                #region Check Quotas
                // check quotas
                List<string> quotaResults = new List<string>();
                PackageContext cntx = PackageController.GetPackageContext(packageId);

                // dynamic memory
                var newRam = ramMB;
                if (otherSettings.DynamicMemory != null && otherSettings.DynamicMemory.Enabled)
                {
                    newRam = otherSettings.DynamicMemory.Maximum;

                    if (ramMB > otherSettings.DynamicMemory.Maximum || ramMB < otherSettings.DynamicMemory.Minimum)
                        quotaResults.Add(VirtualizationErrorCodes.QUOTA_NOT_IN_DYNAMIC_RAM);
                }

                QuotaHelper.CheckListsQuota(cntx, quotaResults, Quotas.VPS2012_SERVERS_NUMBER, VirtualizationErrorCodes.QUOTA_EXCEEDED_SERVERS_NUMBER);

                QuotaHelper.CheckNumericQuota(cntx, quotaResults, Quotas.VPS2012_CPU_NUMBER, cpuCores, VirtualizationErrorCodes.QUOTA_EXCEEDED_CPU);
                QuotaHelper.CheckNumericQuota(cntx, quotaResults, Quotas.VPS2012_RAM, newRam, VirtualizationErrorCodes.QUOTA_EXCEEDED_RAM);
                QuotaHelper.CheckNumericQuota(cntx, quotaResults, Quotas.VPS2012_HDD, hddGB, VirtualizationErrorCodes.QUOTA_EXCEEDED_HDD);
                QuotaHelper.CheckNumericQuota(cntx, quotaResults, Quotas.VPS2012_SNAPSHOTS_NUMBER, snapshots, VirtualizationErrorCodes.QUOTA_EXCEEDED_SNAPSHOTS);

                QuotaHelper.CheckBooleanQuota(cntx, quotaResults, Quotas.VPS2012_DVD_ENABLED, dvdInstalled, VirtualizationErrorCodes.QUOTA_EXCEEDED_DVD_ENABLED);
                QuotaHelper.CheckBooleanQuota(cntx, quotaResults, Quotas.VPS2012_BOOT_CD_ALLOWED, bootFromCD, VirtualizationErrorCodes.QUOTA_EXCEEDED_CD_ALLOWED);

                QuotaHelper.CheckBooleanQuota(cntx, quotaResults, Quotas.VPS2012_START_SHUTDOWN_ALLOWED, startShutdownAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_START_SHUTDOWN_ALLOWED);
                QuotaHelper.CheckBooleanQuota(cntx, quotaResults, Quotas.VPS2012_PAUSE_RESUME_ALLOWED, pauseResumeAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_PAUSE_RESUME_ALLOWED);
                QuotaHelper.CheckBooleanQuota(cntx, quotaResults, Quotas.VPS2012_REBOOT_ALLOWED, rebootAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_REBOOT_ALLOWED);
                QuotaHelper.CheckBooleanQuota(cntx, quotaResults, Quotas.VPS2012_RESET_ALOWED, resetAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_RESET_ALOWED);
                QuotaHelper.CheckBooleanQuota(cntx, quotaResults, Quotas.VPS2012_REINSTALL_ALLOWED, reinstallAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_REINSTALL_ALLOWED);

                QuotaHelper.CheckBooleanQuota(cntx, quotaResults, Quotas.VPS2012_EXTERNAL_NETWORK_ENABLED, externalNetworkEnabled, VirtualizationErrorCodes.QUOTA_EXCEEDED_EXTERNAL_NETWORK_ENABLED);
                QuotaHelper.CheckBooleanQuota(cntx, quotaResults, Quotas.VPS2012_PRIVATE_NETWORK_ENABLED, privateNetworkEnabled, VirtualizationErrorCodes.QUOTA_EXCEEDED_PRIVATE_NETWORK_ENABLED);

                // check external addresses number
                if (!randomExternalAddresses && externalAddresses != null)
                    externalAddressesNumber = externalAddresses.Length;

                int maxAddresses = ServerController.GetPackageUnassignedIPAddresses(packageId, IPAddressPool.VpsExternalNetwork).Count;
                if (externalNetworkEnabled && externalAddressesNumber > maxAddresses)
                    quotaResults.Add(VirtualizationErrorCodes.QUOTA_EXCEEDED_EXTERNAL_ADDRESSES_NUMBER + ":" + maxAddresses.ToString());

                // check private addresses number
                if (!randomPrivateAddresses && privateAddresses != null)
                    privateAddressesNumber = privateAddresses.Length;
                QuotaHelper.CheckNumericQuota(cntx, quotaResults, Quotas.VPS2012_PRIVATE_IP_ADDRESSES_NUMBER, privateAddressesNumber, VirtualizationErrorCodes.QUOTA_EXCEEDED_PRIVATE_ADDRESSES_NUMBER);

                // check management network parameters
                NetworkAdapterDetails manageNic = GetManagementNetworkDetails(packageId);
                if (!String.IsNullOrEmpty(manageNic.NetworkId))
                {
                    // network enabled - check management IPs pool
                    int manageIpsNumber = ServerController.GetUnallottedIPAddresses(
                            packageId, ResourceGroups.VPS2012, IPAddressPool.VpsManagementNetwork).Count;

                    if (manageIpsNumber == 0)
                        quotaResults.Add(VirtualizationErrorCodes.QUOTA_EXCEEDED_MANAGEMENT_NETWORK);
                }

                // check acceptable values
                if (ramMB <= 0)
                    quotaResults.Add(VirtualizationErrorCodes.QUOTA_WRONG_RAM);
                if (hddGB <= 0)
                    quotaResults.Add(VirtualizationErrorCodes.QUOTA_WRONG_HDD);
                if (snapshots < 0)
                    quotaResults.Add(VirtualizationErrorCodes.QUOTA_WRONG_SNAPSHOTS);

                if (quotaResults.Count > 0)
                {
                    res.ErrorCodes.AddRange(quotaResults);
                    return res;
                }
                #endregion

                #region Check input parameters
                // check private network IP addresses if they are specified
                List<string> checkResults = CheckPrivateIPAddresses(packageId, privateAddresses);
                if (checkResults.Count > 0)
                {
                    res.ErrorCodes.AddRange(checkResults);
                    return res;
                }
                #endregion

                #region Context variables
                // service ID
                int serviceId = GetServiceId(packageId);

                // load service settings
                StringDictionary settings = ServerController.GetServiceSettings(serviceId);
                #endregion

                #region Create meta item
                // create meta item
                vm = new VirtualMachine();

                vm.Name = hostname;
                vm.AdministratorPassword = CryptoUtils.Encrypt(password);
                vm.PackageId = packageId;
                vm.VirtualMachineId = null; // from service
                vm.ServiceId = serviceId;

                vm.CurrentTaskId = Guid.NewGuid().ToString("N"); // generate creation task id
                vm.ProvisioningStatus = VirtualMachineProvisioningStatus.InProgress;

                vm.Generation = otherSettings.Generation;
                vm.CpuCores = cpuCores;
                vm.RamSize = ramMB;
                vm.HddSize = hddGB;
                vm.SnapshotsNumber = snapshots;
                vm.DvdDriveInstalled = dvdInstalled;
                vm.BootFromCD = bootFromCD;
                vm.NumLockEnabled = numLock;
                vm.StartTurnOffAllowed = startShutdownAllowed;
                vm.PauseResumeAllowed = pauseResumeAllowed;
                vm.RebootAllowed = rebootAllowed;
                vm.ResetAllowed = resetAllowed;
                vm.ReinstallAllowed = reinstallAllowed;

                // dynamic memory
                if (otherSettings.DynamicMemory != null && otherSettings.DynamicMemory.Enabled)
                    vm.DynamicMemory = otherSettings.DynamicMemory;
                else
                    vm.DynamicMemory = null;

                // networking
                vm.ExternalNetworkEnabled = externalNetworkEnabled;
                vm.PrivateNetworkEnabled = privateNetworkEnabled;
                vm.ManagementNetworkEnabled = !String.IsNullOrEmpty(manageNic.NetworkId);

                // load OS templates
                LibraryItem osTemplate = null;

                try
                {
                    LibraryItem[] osTemplates = GetOperatingSystemTemplates(vm.PackageId);
                    foreach (LibraryItem item in osTemplates)
                    {
                        if (String.Compare(item.Path, osTemplateFile, true) == 0)
                        {
                            osTemplate = item;

                            // check minimal disk size
                            if (osTemplate.DiskSize > 0 && vm.HddSize < osTemplate.DiskSize)
                            {
                                TaskManager.CompleteResultTask(res, VirtualizationErrorCodes.QUOTA_TEMPLATE_DISK_MINIMAL_SIZE + ":" + osTemplate.DiskSize);
                                return res;
                            }

                            vm.OperatingSystemTemplate = osTemplate.Name;
                            vm.LegacyNetworkAdapter = osTemplate.LegacyNetworkAdapter;
                            vm.RemoteDesktopEnabled = osTemplate.RemoteDesktop;
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    res.AddError(VirtualizationErrorCodes.GET_OS_TEMPLATES_ERROR, ex);
                    return res;
                }

                // setup VM paths
                string templatesPath = settings["OsTemplatesPath"];
                string rootFolderPattern = settings["RootFolder"];
                if(rootFolderPattern.IndexOf("[") == -1)
                {
                    // no pattern has been specified
                    if(!rootFolderPattern.EndsWith("\\"))
                        rootFolderPattern += "\\";
                    rootFolderPattern += "[username]\\[vps_hostname]";
                }

                vm.RootFolderPath = EvaluateItemVariables(rootFolderPattern, vm);
                var correctVhdPath = GetCorrectTemplateFilePath(templatesPath, osTemplateFile);
                vm.OperatingSystemTemplatePath = correctVhdPath;
                vm.VirtualHardDrivePath = Path.Combine(vm.RootFolderPath, hostname + Path.GetExtension(correctVhdPath));

                // save meta-item
                try
                {
                    vm.Id = PackageController.AddPackageItem(vm);
                }
                catch (Exception ex)
                {
                    res.AddError(VirtualizationErrorCodes.CREATE_META_ITEM_ERROR, ex);
                    return res;
                }
                
                #endregion

                #region Start Asynchronous task
                try
                {
                    // asynchronous process starts here
                    CreateServerAsyncWorker2012 worker = new CreateServerAsyncWorker2012();

                    worker.TaskId = vm.CurrentTaskId; // async task ID
                    worker.ThreadUserId = SecurityContext.User.UserId;
                    worker.Item = vm;
                    worker.OsTemplate = osTemplate;

                    worker.ExternalAddressesNumber = externalAddressesNumber;
                    worker.RandomExternalAddresses = randomExternalAddresses;
                    worker.ExternalAddresses = externalAddresses;

                    worker.PrivateAddressesNumber = privateAddressesNumber;
                    worker.RandomPrivateAddresses = randomPrivateAddresses;
                    worker.PrivateAddresses = privateAddresses;

                    worker.SummaryLetterEmail = summaryLetterEmail;

                    worker.CreateAsync();
                }
                catch (Exception ex)
                {
                    // delete meta item
                    PackageController.DeletePackageItem(vm.Id);

                    // return from method
                    res.AddError(VirtualizationErrorCodes.CREATE_TASK_START_ERROR, ex);
                    return res;
                }
                #endregion
            }
            catch (Exception ex)
            {
                res.AddError(VirtualizationErrorCodes.CREATE_ERROR, ex);
                return res;
            }

            res.Value = vm.Id;
            res.IsSuccess = true;
            return res;
        }
        public static IntResult CreateVirtualMachine(int packageId,
                string hostname, string domain, string osTemplateFile, string vmName, string password, string summaryLetterEmail,
                int cpuCores, int ramMB, int hddGB, int snapshots,
                bool dvdInstalled, bool bootFromCD, bool numLock,
                bool startShutdownAllowed, bool pauseResumeAllowed, bool rebootAllowed, bool resetAllowed, bool reinstallAllowed,
                bool externalNetworkEnabled, string externalNetworkLocation, string externalNicMacAddress, string externalVirtualNetwork,
                bool privateNetworkEnabled, string privateNetworkLocation, string privateNicMacAddress, string privateVirtualNetwork, ushort privateVLanID)
        {
            // result object
            IntResult res = new IntResult();

            //Create Task 
            res = TaskManager.StartResultTask<IntResult>("VPSForPC", "CREATE");
            TaskManager.PackageId = packageId;
            TaskManager.ItemName = vmName;

            // meta item
            VMInfo vmInfo = null;

            try
            {
                #region Check account and space statuses
                // check account
                if (!SecurityContext.CheckAccount(res, DemandAccount.NotDemo | DemandAccount.IsActive))
                {
                    res.ErrorCodes.Add(VirtualizationErrorCodes.CREATE_ERROR);
                    TaskManager.CompleteResultTask(res);
                    return res;
                }
                // check package
                if (!SecurityContext.CheckPackage(res, packageId, DemandPackage.IsActive))
                {
                    res.ErrorCodes.Add(VirtualizationErrorCodes.CREATE_ERROR);
                    TaskManager.CompleteResultTask(res);
                    return res;
                }
                
                #endregion

                #region Check if host name is already used

                try
                {
                    string itemName = (String.IsNullOrEmpty(hostname) && String.IsNullOrEmpty(domain) ? vmName: String.Format("{0}.{1}", hostname, domain));
                    ServiceProviderItem item = PackageController.GetPackageItemByName(packageId, itemName,
                                                                                      typeof (VMInfo));

                    if (item != null)
                    {
                        res.ErrorCodes.Add(VirtualizationErrorCodes.HOST_NAMER_IS_ALREADY_USED);
                        TaskManager.CompleteResultTask(res);
                        return res;
                    }
                }
                catch(Exception ex)
                {
                    res.AddError(VirtualizationErrorCodes.CANNOT_CHECK_HOST_EXISTS, ex);
                    TaskManager.CompleteResultTask(res);
                    return res;   
                }

                #endregion

                #region Check Quotas
                // check quotas
                List<string> quotaResults = new List<string>();
                PackageContext cntx = PackageController.GetPackageContext(packageId);


                CheckListsQuota(cntx, quotaResults, Quotas.VPSForPC_SERVERS_NUMBER, VirtualizationErrorCodes.QUOTA_EXCEEDED_SERVERS_NUMBER);

                CheckNumericQuota(cntx, quotaResults, Quotas.VPSForPC_CPU_NUMBER, cpuCores, VirtualizationErrorCodes.QUOTA_EXCEEDED_CPU);
                CheckNumericQuota(cntx, quotaResults, Quotas.VPSForPC_RAM, ramMB, VirtualizationErrorCodes.QUOTA_EXCEEDED_RAM);
                CheckNumericQuota(cntx, quotaResults, Quotas.VPSForPC_HDD, hddGB, VirtualizationErrorCodes.QUOTA_EXCEEDED_HDD);
                CheckNumericQuota(cntx, quotaResults, Quotas.VPSForPC_SNAPSHOTS_NUMBER, snapshots, VirtualizationErrorCodes.QUOTA_EXCEEDED_SNAPSHOTS);

                CheckBooleanQuota(cntx, quotaResults, Quotas.VPSForPC_DVD_ENABLED, dvdInstalled, VirtualizationErrorCodes.QUOTA_EXCEEDED_DVD_ENABLED);
                CheckBooleanQuota(cntx, quotaResults, Quotas.VPSForPC_BOOT_CD_ALLOWED, bootFromCD, VirtualizationErrorCodes.QUOTA_EXCEEDED_CD_ALLOWED);

                CheckBooleanQuota(cntx, quotaResults, Quotas.VPSForPC_START_SHUTDOWN_ALLOWED, startShutdownAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_START_SHUTDOWN_ALLOWED);
                CheckBooleanQuota(cntx, quotaResults, Quotas.VPSForPC_PAUSE_RESUME_ALLOWED, pauseResumeAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_PAUSE_RESUME_ALLOWED);
                CheckBooleanQuota(cntx, quotaResults, Quotas.VPSForPC_REBOOT_ALLOWED, rebootAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_REBOOT_ALLOWED);
                CheckBooleanQuota(cntx, quotaResults, Quotas.VPSForPC_RESET_ALOWED, resetAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_RESET_ALOWED);
                CheckBooleanQuota(cntx, quotaResults, Quotas.VPSForPC_REINSTALL_ALLOWED, reinstallAllowed, VirtualizationErrorCodes.QUOTA_EXCEEDED_REINSTALL_ALLOWED);

                CheckBooleanQuota(cntx, quotaResults, Quotas.VPSForPC_EXTERNAL_NETWORK_ENABLED, externalNetworkEnabled, VirtualizationErrorCodes.QUOTA_EXCEEDED_EXTERNAL_NETWORK_ENABLED);
                CheckBooleanQuota(cntx, quotaResults, Quotas.VPSForPC_PRIVATE_NETWORK_ENABLED, privateNetworkEnabled, VirtualizationErrorCodes.QUOTA_EXCEEDED_PRIVATE_NETWORK_ENABLED);

                // check management network parameters
                NetworkAdapterDetails manageNic = GetManagementNetworkDetails(packageId);
                if (!String.IsNullOrEmpty(manageNic.NetworkId))
                {
                    // network enabled - check management IPs pool
                    int manageIpsNumber = ServerController.GetUnallottedIPAddresses(
                            packageId, ResourceGroups.VPSForPC, IPAddressPool.VpsManagementNetwork).Count;

                    if (manageIpsNumber == 0)
                        quotaResults.Add(VirtualizationErrorCodes.QUOTA_EXCEEDED_MANAGEMENT_NETWORK);
                }

                // check acceptable values
                if (ramMB <= 0)
                    quotaResults.Add(VirtualizationErrorCodes.QUOTA_WRONG_RAM);
                if (hddGB <= 0)
                    quotaResults.Add(VirtualizationErrorCodes.QUOTA_WRONG_HDD);
                if (snapshots < 0)
                    quotaResults.Add(VirtualizationErrorCodes.QUOTA_WRONG_SNAPSHOTS);

                if (quotaResults.Count > 0)
                {
                    res.ErrorCodes.AddRange(quotaResults);
                    TaskManager.CompleteResultTask(res);
                    return res;
                }
                #endregion

                #region Context variables
                // service ID
                int serviceId = GetServiceId(packageId);

                // load service settings
                StringDictionary settings = ServerController.GetServiceSettings(serviceId);

                PackageInfo pk = PackageController.GetPackage(packageId);
                UserInfo user = UserController.GetUser(pk.UserId);
                #endregion

                #region Create meta item
                // create meta item

                vmInfo = new VMInfo();

//                vmInfo.AdminUserName = user.Username;
                vmInfo.AdminUserName = null;
                vmInfo.AdminPassword = password;
                vmInfo.DvdDriver = dvdInstalled;
                vmInfo.HostName = hostname;
                vmInfo.CPUCount = cpuCores;
                vmInfo.JoinDomain = (String.IsNullOrWhiteSpace(domain) ? null : domain);
                vmInfo.JoinDomainPassword = null;
                vmInfo.JoinDomainUserName = null;
                vmInfo.Memory = ramMB;
                vmInfo.NumLockEnabled = numLock;
                vmInfo.HddSize = hddGB;

                vmInfo.ProductKey = null;
                vmInfo.TemplateId = new Guid(osTemplateFile);
                vmInfo.VmPath = settings["RootFolder"];
                vmInfo.ComputerName = vmName;
                vmInfo.Owner = null;

                vmInfo.PackageId = packageId;
                vmInfo.ServiceId = serviceId;
                vmInfo.Name = vmName;

                vmInfo.StartTurnOffAllowed = startShutdownAllowed;
                vmInfo.PauseResumeAllowed = pauseResumeAllowed;
                vmInfo.RebootAllowed = rebootAllowed;
                vmInfo.ResetAllowed = resetAllowed;
                vmInfo.ReinstallAllowed = reinstallAllowed;

                vmInfo.BootFromCD = bootFromCD;

                //vmInfo.CurrentTaskId = Guid.NewGuid().ToString("N"); // generate creation task id
                vmInfo.ProvisioningStatus = VirtualMachineProvisioningStatus.InProgress;

                // networking
                vmInfo.ExternalNetworkEnabled = externalNetworkEnabled;
                vmInfo.ExternalNetworkLocation = externalNetworkLocation;
                vmInfo.ExternalNicMacAddress = externalNicMacAddress;
                vmInfo.ExternalVirtualNetwork = string.IsNullOrEmpty(externalVirtualNetwork) ? settings["ExternalNetworkName"] : externalVirtualNetwork;

                vmInfo.PrivateNetworkEnabled = privateNetworkEnabled;
                vmInfo.PrivateNetworkLocation = privateNetworkLocation;
                vmInfo.PrivateNicMacAddress = privateNicMacAddress;
                vmInfo.PrivateVLanID = privateVLanID;
                vmInfo.PrivateVirtualNetwork = string.IsNullOrEmpty(privateVirtualNetwork) ? settings["PrivateNetworkName"] : privateVirtualNetwork;
                
                // save meta-item
                try
                {
                    vmInfo.VmId = PackageController.AddPackageItem(vmInfo);
                    vmInfo.Id = vmInfo.VmId;
                    TaskManager.ItemId = vmInfo.VmId;
                }
                catch (Exception ex)
                {
                    res.AddError(VirtualizationErrorCodes.CREATE_META_ITEM_ERROR, ex);
                    TaskManager.CompleteResultTask(res);
                    return res;
                }
                
                #endregion

                #region Start Asynchronous task
                try
                {
//                    CreateServerAsyncWorkerForPrivateCloud worker = new CreateServerAsyncWorkerForPrivateCloud();
                    CreateVMAsyncWorker worker = new CreateVMAsyncWorker();
                    worker.vmTemplate = vmInfo;
                    worker.ThreadUserId = SecurityContext.User.UserId;
                    worker.CreateAsync();

//                    CreateServerAsyncWorkerForPrivateCloud.Run(vmInfo);

//                    worker.Run(vmInfo);
                }
                catch (Exception ex)
                {
                    // delete meta item
                    PackageController.DeletePackageItem(vmInfo.VmId);
                    // return from method
                    res.AddError(VirtualizationErrorCodes.CREATE_TASK_START_ERROR, ex);
                    TaskManager.CompleteResultTask(res);
                    return res;
                }
                #endregion
            }
            catch (Exception ex)
            {
                res.AddError(VirtualizationErrorCodes.CREATE_ERROR, ex);
                TaskManager.CompleteResultTask(res);
                return res;
            }

            res.Value = vmInfo.VmId;
            res.IsSuccess = true;
            TaskManager.CompleteTask();
            return res;
        }