public DeploymentPlan Build(DeployBatchRequest deployBatchRequest)
        {
            var returnValue = new DeploymentPlan()
            {
                DeployBatchRequestId = deployBatchRequest.Id
            };
            DeploymentPlanParallelBatch currentParallelBatch = null;
            var itemList = FilterItemList(deployBatchRequest.ItemList);
            if(itemList != null)
            {
                foreach (var item in itemList)
                {
                    EnumDeploymentIsolationType isolationType = _projectManager.GetComponentIsolationType(item.Build.ProjectId, item.Build.ProjectComponentId);
                    if(isolationType == EnumDeploymentIsolationType.IsolatedPerDeployment)
                    {
                        currentParallelBatch = null;
                        foreach(var machine in item.MachineList)
                        {
                            var parallelBatchItem = new DeploymentPlanParallelBatch
                            {
                                IsolationType = EnumDeploymentIsolationType.IsolatedPerDeployment,
                                MachineQueueList = new List<DeploymentPlanMachineQueue>
                                {
                                    new DeploymentPlanMachineQueue()
                                    {
										Id = Guid.NewGuid().ToString(),
                                        MachineName = machine.MachineName,
                                        MachineQueueItemList = new List<DeploymentPlanMachineQueueItem>
                                        {
                                            new DeploymentPlanMachineQueueItem
                                            {
                                                MachineId = machine.Id,
                                                DeployBatchRequestItem = item
                                            }
                                        }
                                    }
                                }
                            };
                            returnValue.ParallelBatchList.Add(parallelBatchItem);
                        }
                    }
                    else if (isolationType == EnumDeploymentIsolationType.IsolatedPerMachine)
                    {
                        if (currentParallelBatch == null || currentParallelBatch.IsolationType != EnumDeploymentIsolationType.IsolatedPerMachine)
                        {
                            currentParallelBatch = new DeploymentPlanParallelBatch
                            {
                                IsolationType = EnumDeploymentIsolationType.IsolatedPerMachine
                            };
                            returnValue.ParallelBatchList.Add(currentParallelBatch);
                        }
                        foreach(var machine in item.MachineList)
                        {
                            var machineQueue = currentParallelBatch.MachineQueueList.FirstOrDefault(i=>i.MachineName.Equals(machine.MachineName, StringComparison.CurrentCultureIgnoreCase));
                            if(machineQueue == null)
                            {
                                machineQueue = new DeploymentPlanMachineQueue
                                {
									Id = Guid.NewGuid().ToString(),
                                    MachineName = machine.MachineName
                                };
                                currentParallelBatch.MachineQueueList.Add(machineQueue);
                            }
                            var machineQueueItem = new DeploymentPlanMachineQueueItem
                            {
                                MachineId = machine.Id,
                                DeployBatchRequestItem = item
                            };
                            machineQueue.MachineQueueItemList.Add(machineQueueItem);
                        }
                    }
                    else if(isolationType == EnumDeploymentIsolationType.NoIsolation)
                    {
                        if (currentParallelBatch == null || currentParallelBatch.IsolationType != EnumDeploymentIsolationType.NoIsolation)
                        {
                            currentParallelBatch = new DeploymentPlanParallelBatch
                            {
                                IsolationType = EnumDeploymentIsolationType.NoIsolation
                            };
                            returnValue.ParallelBatchList.Add(currentParallelBatch);
                        }
                        foreach (var machine in item.MachineList)
                        {
                            var machineQueue = new DeploymentPlanMachineQueue
                            {
								Id = Guid.NewGuid().ToString(),
								MachineName = machine.MachineName
                            };
                            currentParallelBatch.MachineQueueList.Add(machineQueue);
                            var machineQueueItem = new DeploymentPlanMachineQueueItem
                            {
                                MachineId = machine.Id,
                                DeployBatchRequestItem = item
                            };
                            machineQueue.MachineQueueItemList.Add(machineQueueItem);
                        }
                    }
                    else 
                    {
                        throw new UnknownEnumValueException(isolationType);
                    }
                }
            }
            return returnValue;
        }
		public void DeployMachineQueue(DeploymentPlan plan, string machineQueueId, RuntimeSystemSettings runtimeSettings)
		{
			string deployBatchRequestId = plan.DeployBatchRequestId;
			var machineQueue = plan.ParallelBatchList.SelectMany(i=>i.MachineQueueList.Where(j=>j.Id == machineQueueId)).SingleOrDefault();
			if(machineQueue == null)
			{
				throw new RecordNotFoundException(typeof(DeploymentPlanMachineQueue), "Id", machineQueueId);
			}
			//Sooooo, we're in some threads now.  And some of our repository types (Raven) doesn't like sharing sessions between threads.
			//	So let's create a new instance now for this method
			var localDeployRequestManager = _diFactory.CreateInjectedObject<IDeployRequestManager>();
			var localDeployRunner = _diFactory.CreateInjectedObject<IDeployRunner>();
			var localDeployStateManager = _diFactory.CreateInjectedObject<IDeployStateManager>();

			foreach(var machineQueueItem in machineQueue.MachineQueueItemList)
			{
				if (localDeployRequestManager.HasCancelRequested(deployBatchRequestId))
				{
					localDeployStateManager.MarkBatchDeploymentCancelled(deployBatchRequestId, null);
					return;
				}
				else if (localDeployRequestManager.IsStopped(deployBatchRequestId))
				{
					return;
				}
				var machine = machineQueueItem.DeployBatchRequestItem.MachineList.FirstOrDefault(i=>i.Id == machineQueueItem.MachineId);
				if(machine == null)
				{
					throw new Exception("Failed to find machine " + machineQueueItem.MachineId);
				}
				var deployState = localDeployStateManager.GetOrCreateDeployState(machineQueueItem.DeployBatchRequestItem.Build.ProjectId, machineQueueItem.DeployBatchRequestItem.Build.Id, machine.EnvironmentId, machine.Id, machineQueueItem.DeployBatchRequestItem.Id);
				if (deployState.Status != EnumDeployStatus.Success)
				{
					try
					{
						localDeployStateManager.MarkDeploymentInProcess(deployState.Id);
						var machineIdList = new List<string> { machine.Id };
						localDeployRunner.Deploy(deployState.Id, machine.EnvironmentId, machineQueueItem.DeployBatchRequestItem.Build.Id, machineIdList, runtimeSettings);
						localDeployStateManager.MarkDeploymentSuccess(deployState.Id);
					}
					catch (Exception err)
					{
						localDeployStateManager.MarkDeploymentFailed(deployState.Id, err);
						throw;
					}
				}
			}
		}