private EventVertex CreateVertexEvent(InternalEventVertex vertex, int inDegree, int outDegree)
        {
            int eventVertexId;

            if (!verticeIdsMap.TryGetValue(vertex.Id, out eventVertexId))
            {
                verticeIdsMap[vertex.Id] = eventVertexId = verticeNextId;
                verticeNextId++;
            }

            EventVertex eventVertex;

            if (inDegree == 0)
            {
                eventVertex = EventVertex.CreateGraphStart(eventVertexId);
            }
            else if (outDegree == 0)
            {
                eventVertex = EventVertex.CreateGraphEnd(eventVertexId);
            }
            else
            {
                eventVertex = EventVertex.Create(eventVertexId);
            }
            return(eventVertex);
        }
        private BidirectionalGraph <InternalEventVertex, InternalActivityEdge> ExplodeActivityNodeGraphToArrowGraph(BidirectionalGraph <int, SEdge <int> > nodeGraph)
        {
            var arrowGraph = new BidirectionalGraph <InternalEventVertex, InternalActivityEdge>();

            // Go over all vertice - add them as new activity edges.
            // activity vertex names are important for resuse when adding the edges.
            foreach (var vertex in nodeGraph.Vertices)
            {
                bool isCritical = activitiesDictionary[vertex].IsCritical;

                var startNode = InternalEventVertex.Create(vertex, ActivityVertexType.ActivityStart, isCritical);
                var endNode   = InternalEventVertex.Create(vertex, ActivityVertexType.ActivityEnd, isCritical);
                arrowGraph.AddVertex(startNode);
                arrowGraph.AddVertex(endNode);

                InternalActivityEdge activityEdge = new InternalActivityEdge(startNode, endNode, isCritical, vertex);

                arrowGraph.AddEdge(activityEdge);
            }

            // Go over all edges - convert them to dummy edges.
            // Make sure connections are maintained.
            foreach (var edge in nodeGraph.Edges)
            {
                bool isSourceCritical = activitiesDictionary[edge.Source].IsCritical;
                bool isTargetCritical = activitiesDictionary[edge.Target].IsCritical;

                InternalActivityEdge activityEdge = new InternalActivityEdge(
                    InternalEventVertex.Create(edge.Source, ActivityVertexType.ActivityEnd, isSourceCritical),
                    InternalEventVertex.Create(edge.Target, ActivityVertexType.ActivityStart, isTargetCritical),
                    isSourceCritical && isTargetCritical);

                arrowGraph.AddEdge(activityEdge);
            }

            return(arrowGraph);
        }
        private void RedirectCommonDependencyToNexus(InternalEventVertex nexusVertex, IEnumerable <InternalEventVertex> depndents, InternalEventVertex commonDependency)
        {
            bool isAddedEdgeCritical = false;
            IEnumerable <InternalActivityEdge> edgesOutOfDependency;

            if (arrowGraph.TryGetOutEdges(commonDependency, out edgesOutOfDependency))
            {
                // Remove the edges between the dependency and the dependents of the nexus vertex
                var edgesToRemove = edgesOutOfDependency.Where(e => depndents.Contains(e.Target)).ToList();
                foreach (var edgeToRemove in edgesToRemove)
                {
                    arrowGraph.RemoveEdge(edgeToRemove);

                    // Replacing even one critical edge means the new edge would be also critical
                    isAddedEdgeCritical = isAddedEdgeCritical || edgeToRemove.IsCritical;
                }
            }
            // Else should never happen

            // This dependency should point at nexus vertex
            var edgeToAdd = new InternalActivityEdge(commonDependency, nexusVertex, isAddedEdgeCritical);

            arrowGraph.AddEdge(edgeToAdd);
        }
 private bool TryGetActivity(InternalEventVertex vertex, out Activity activity)
 {
     activity = null;
     return(activitiesDictionary.TryGetValue(vertex.ActivityId, out activity));
 }
        private bool WillParallelEdgesBeCreated(IEnumerable <InternalActivityEdge> plannedEdgesToReplace, InternalEventVertex plannedNewSource, InternalEventVertex plannedNewTarget)
        {
            bool abortMerge = false;

            foreach (var edge in plannedEdgesToReplace.ToList())
            {
                var sourceToTestWith = plannedNewSource ?? edge.Source;
                var targetToTestWith = plannedNewTarget ?? edge.Target;

                InternalActivityEdge dummy;
                if (arrowGraph.TryGetEdge(sourceToTestWith, targetToTestWith, out dummy))
                {
                    abortMerge = abortMerge || true;
                }
            }

            return(abortMerge);
        }