private DeploymentStepGraph GetAdjacencyGraphForComponentGroup(ComponentDeploymentGraph adjacencyDeploymentGraphForProductGroup, int numberOfComponentGroups)
        {
            var relatedComponentGroupDependancies = new DeploymentStepGraph();

            for (var j = 0; j < numberOfComponentGroups; j++)
            {
                var stepGroup = j;

                var vertices = adjacencyDeploymentGraphForProductGroup.Vertices
                               .Where(vertex => vertex.ComponentGroup == stepGroup)
                               .ToList();

                var edges = adjacencyDeploymentGraphForProductGroup.Edges
                            .Where(edge => edge.Source.ComponentGroup == stepGroup)
                            .ToList();

                var componentDeployments = vertices.Select(x => new ComponentDeployment
                {
                    Vertex = x,
                    Edges  = edges
                }).ToList();

                var productDeploymentStep = new ProductDeploymentStep(componentDeployments);
                relatedComponentGroupDependancies.AddVertex(productDeploymentStep);
            }

            foreach (var productDeploymentStep in relatedComponentGroupDependancies.Vertices)
            {
                var relatedComponentGroupDependancyEdges = productDeploymentStep.ComponentDeployments
                                                           .SelectMany(x => x.Edges)
                                                           .ToList();

                var relatedComponentGroupDependancyVertices = productDeploymentStep.ComponentDeployments
                                                              .Select(x => x.Vertex)
                                                              .ToList();

                var componentGroupExternalEdges = relatedComponentGroupDependancyEdges
                                                  .Where(edge => relatedComponentGroupDependancyVertices.All(vertex => vertex != edge.Target));

                foreach (var componentGroupExternalEdge in componentGroupExternalEdges)
                {
                    var componentGroupVertexTarget = relatedComponentGroupDependancies.Vertices
                                                     .First(vertex => vertex.ComponentDeployments.Select(x => x.Vertex).Any(x => x == componentGroupExternalEdge.Target));

                    var deploymentStepEdge = new DeploymentStepEdge(productDeploymentStep, componentGroupVertexTarget);
                    relatedComponentGroupDependancies.AddEdge(deploymentStepEdge);
                }
            }

            return(relatedComponentGroupDependancies);
        }
        private void AddExecutionOrderToComponentGroupAndComponents(DeploymentStepGraph adjacencyGraphForDeploymentStep)
        {
            var adjacencyGraphForComponentGroupThatAreNotProcessed = adjacencyGraphForDeploymentStep.Clone();

            var executionOrder = -1;

            while (!adjacencyGraphForComponentGroupThatAreNotProcessed.IsVerticesEmpty)
            {
                executionOrder++;
                var rootComponentGroupVertices = adjacencyGraphForComponentGroupThatAreNotProcessed.Roots().ToList();

                foreach (var rootComponentGroupVertex in rootComponentGroupVertices)
                {
                    rootComponentGroupVertex.ExecutionOrder = executionOrder;

                    foreach (var componentDeployment in rootComponentGroupVertex.ComponentDeployments)
                    {
                        componentDeployment.Vertex.ExecutionOrder = executionOrder;
                    }

                    adjacencyGraphForComponentGroupThatAreNotProcessed.RemoveVertex(rootComponentGroupVertex);
                }
            }
        }