private void DoPrepareDeploymentToStandardEnvironment(EnvironmentInfo environmentInfo, Lazy<string> artifactsBinariesDirPathProvider)
        {
            Func<CollectedCredentials> collectCredentialsFunc =
            () =>
            {
              EnvironmentUser environmentUser =
            environmentInfo.GetEnvironmentUserById(_projectInfo.NtServiceUserId);

              string environmentUserPassword =
            PasswordCollectorHelper.CollectPasssword(
              _passwordCollector,
              DeploymentInfo.DeploymentId,
              environmentInfo,
              environmentInfo.AppServerMachineName,
              environmentUser,
              OnDiagnosticMessagePosted);

              return
            new CollectedCredentials(
              environmentUser.UserName,
              environmentUserPassword);
            };

              DoPrepareCommonDeploymentSteps(
            _projectInfo.NtServiceName,
            environmentInfo.AppServerMachineName,
            environmentInfo.NtServicesBaseDirPath,
            environmentInfo.GetAppServerNetworkPath,
            artifactsBinariesDirPathProvider,
            collectCredentialsFunc,
            true);
        }
        private void AddTaskConfigurationSteps(EnvironmentInfo environmentInfo, string schedulerServerTasksMachineName, SchedulerAppTask schedulerAppTask, ScheduledTaskDetails taskDetails = null)
        {
            bool hasSettingsChanged = HasSettingsChanged(taskDetails, schedulerAppTask, environmentInfo);
              bool taskExists = taskDetails != null;

              EnvironmentUser environmentUser =
            environmentInfo.GetEnvironmentUserById(schedulerAppTask.UserId);

              string environmentUserPassword = null;

              if (!taskExists || hasSettingsChanged)
              {
            // collect password if not already collected
            if (!_collectedPasswordsByUserName.TryGetValue(environmentUser.UserName, out environmentUserPassword))
            {
              environmentUserPassword =
            PasswordCollectorHelper.CollectPasssword(
              _passwordCollector,
              DeploymentInfo.DeploymentId,
              environmentInfo,
              schedulerServerTasksMachineName,
              environmentUser,
              OnDiagnosticMessagePosted);

              _collectedPasswordsByUserName.Add(environmentUser.UserName, environmentUserPassword);
            }
              }

              string taskExecutablePath =
            GetTaskExecutablePath(schedulerAppTask, environmentInfo);

              if (!taskExists)
              {
            // create a step for scheduling a new app
            AddSubTask(
              new CreateSchedulerTaskDeploymentStep(
            schedulerServerTasksMachineName,
            schedulerAppTask.Name,
            taskExecutablePath,
            environmentUser.UserName,
            environmentUserPassword,
            schedulerAppTask.ScheduledHour,
            schedulerAppTask.ScheduledMinute,
            schedulerAppTask.ExecutionTimeLimitInMinutes,
            schedulerAppTask.Repetition,
            _taskScheduler));
              }
              else if (hasSettingsChanged)
              {
            // create a step for updating an existing scheduler app
            AddSubTask(
              new UpdateSchedulerTaskDeploymentStep(
            schedulerServerTasksMachineName,
            schedulerAppTask.Name,
            taskExecutablePath,
            environmentUser.UserName,
            environmentUserPassword,
            schedulerAppTask.ScheduledHour,
            schedulerAppTask.ScheduledMinute,
            schedulerAppTask.ExecutionTimeLimitInMinutes,
            schedulerAppTask.Repetition,
            _taskScheduler));
              }
        }
        private void DoPrepareDeploymentToClusteredEnvironment(EnvironmentInfo environmentInfo, Lazy<string> artifactsBinariesDirPathProvider)
        {
            string clusterGroupName = environmentInfo.GetFailoverClusterGroupNameForProject(DeploymentInfo.ProjectName);

              if (string.IsNullOrEmpty(clusterGroupName))
              {
            throw new InvalidOperationException(string.Format("There is no cluster group defined for project '{0}' in environment '{1}'.", DeploymentInfo.ProjectName, environmentInfo.Name));
              }

              string failoverClusterMachineName = environmentInfo.FailoverClusterMachineName;

              if (string.IsNullOrEmpty(failoverClusterMachineName))
              {
            throw new InvalidOperationException(string.Format("Environment '{0}' has no failover cluster machine name defined.", environmentInfo.Name));
              }

              string currentNodeName =
            _failoverClusterManager.GetCurrentNodeName(failoverClusterMachineName, clusterGroupName);

              if (string.IsNullOrEmpty(currentNodeName))
              {
            throw new InvalidOperationException(string.Format("Cluster group '{0}' has no current node in a cluster '{1}' in environment '{2}'.", clusterGroupName, environmentInfo.FailoverClusterMachineName, environmentInfo.Name));
              }

              PostDiagnosticMessage(string.Format("Current node: '{0}'.", currentNodeName), DiagnosticMessageType.Trace);

              List<string> possibleNodeNames =
            _failoverClusterManager.GetPossibleNodeNames(failoverClusterMachineName, clusterGroupName)
              .ToList();

              PostDiagnosticMessage(string.Format("Possible nodes: {0}.", string.Join(", ", possibleNodeNames.Select(n => string.Format("'{0}'", n)))), DiagnosticMessageType.Trace);

              if (possibleNodeNames.Count < 2)
              {
            throw new InvalidOperationException(string.Format("There is only one possible node for cluster group '{0}' in a cluster '{1}' in environment '{2}'.", clusterGroupName, environmentInfo.FailoverClusterMachineName, environmentInfo.Name));
              }

              // update nt service on all machines other than current owner node
              CollectedCredentials cachedCollectedCredentials = null;

              Func<string, Func<CollectedCredentials>> collectCredentialsFunc =
            machineName =>
            () =>
            {
              // ReSharper disable AccessToModifiedClosure
              if (cachedCollectedCredentials != null)
              {
            return cachedCollectedCredentials;
              }
              // ReSharper restore AccessToModifiedClosure

              EnvironmentUser environmentUser =
            environmentInfo.GetEnvironmentUserById(_projectInfo.NtServiceUserId);

              string environmentUserPassword =
            PasswordCollectorHelper.CollectPasssword(
              _passwordCollector,
              DeploymentInfo.DeploymentId,
              environmentInfo,
              machineName,
              environmentUser,
              OnDiagnosticMessagePosted);

              cachedCollectedCredentials =
            new CollectedCredentials(
              environmentUser.UserName,
              environmentUserPassword);

              return cachedCollectedCredentials;
            };

              foreach (string possibleNodeName in possibleNodeNames)
              {
            string machineName = possibleNodeName;

            if (string.Equals(machineName, currentNodeName, StringComparison.OrdinalIgnoreCase))
            {
              continue;
            }

            DoPrepareCommonDeploymentSteps(
              _projectInfo.NtServiceName,
              machineName,
              environmentInfo.NtServicesBaseDirPath,
              absoluteLocalPath => EnvironmentInfo.GetNetworkPath(machineName, absoluteLocalPath),
              artifactsBinariesDirPathProvider,
              collectCredentialsFunc(machineName),
              false);
              }

              // move cluster group to another node
              string targetNodeName =
            possibleNodeNames.FirstOrDefault(nodeName => nodeName != currentNodeName);

              PostDiagnosticMessage(string.Format("Target node: '{0}'.", targetNodeName), DiagnosticMessageType.Trace);

              if (string.IsNullOrEmpty(targetNodeName))
              {
            throw new InvalidOperationException(string.Format("There is no node in cluster '{0}' that we can move cluster group '{1}' to.", failoverClusterMachineName, clusterGroupName));
              }

              AddSubTask(
            new MoveClusterGroupToAnotherNodeDeploymentStep(
              _failoverClusterManager,
              failoverClusterMachineName,
              clusterGroupName,
              targetNodeName));

              // update nt service on the machine that was the previous owner node
              string previousMachineName = currentNodeName;

              DoPrepareCommonDeploymentSteps(
            _projectInfo.NtServiceName,
            previousMachineName,
            environmentInfo.NtServicesBaseDirPath,
            absoluteLocalPath => EnvironmentInfo.GetNetworkPath(previousMachineName, absoluteLocalPath),
            artifactsBinariesDirPathProvider,
            collectCredentialsFunc(previousMachineName),
            false);
        }