public void AddEdge(IEdge edge)
        {
            INode      edgeTail = edge.TailNode;
            INode      edgeHead = edge.HeadNode;
            IGraphNode tail;
            IGraphNode head;

            if (_nodes.Contains(edgeTail.GetId()) == false)
            {
                tail = new GraphNode(edgeTail);
                _nodes.Push(tail);
            }
            else
            {
                tail = _nodes.GetById(edgeTail.GetId());
            }

            if (_nodes.Contains(edgeHead.GetId()) == false)
            {
                head = new GraphNode(edgeHead);
                _nodes.Push(head);
            }
            else
            {
                head = _nodes.GetById(edgeHead.GetId());
            }

            head.AddPredecessor(tail);
            tail.AddSuccessor(head);
        }
        private void TraverseDemandToProviderGraph(INode node,
                                                   IStackSet <INode> visitedProductionOrders)
        {
            if (node.GetEntity().GetType() == typeof(ProductionOrderBom))
            {
                // remove, ProductionOrderBoms will be ignored and replaced by operations
                RemoveNode(node, true);
            }
            else if (node.GetEntity().GetType() == typeof(ProductionOrder) &&
                     visitedProductionOrders.Contains(node) == false)
            {
                // insert it like it is in ProductionOrderToOperationGraph

                OperationGraph operationGraph =
                    new OperationGraph((ProductionOrder)node.GetEntity());
                ReplaceNodeByDirectedGraph(node, operationGraph);
                visitedProductionOrders.Push(node);
            }

            INodes successorNodes = GetSuccessorNodes(node);

            if (successorNodes == null)
            {
                return;
            }

            foreach (var successor in successorNodes)
            {
                TraverseDemandToProviderGraph(successor, visitedProductionOrders);
            }
        }
        /**
         * Bottom-Up-Traversal
         */
        private void ValidatePredecessorOperationsTransitionTimeIsCorrect(
            IStackSet <ProductionOrderOperation> predecessorOperations,
            ProductionOrderOperation lastOperation,
            IDirectedGraph <INode> operationGraph,
            IStackSet <INode> traversedOperations)
        {
            if (predecessorOperations == null)
            {
                return;
            }

            foreach (var currentPredecessor in predecessorOperations)
            {
                if (currentPredecessor.GetType() == typeof(ProductionOrderOperation))
                {
                    ProductionOrderOperation currentOperation = currentPredecessor;
                    traversedOperations.Push(new Node(currentPredecessor));

                    // transition time MUST be before the start of Operation
                    int expectedStartBackwardLowerLimit =
                        lastOperation.GetValue().EndBackward.GetValueOrDefault() +
                        TransitionTimer.GetTransitionTimeFactor() *
                        currentOperation.GetValue().Duration;
                    int actualStartBackward = currentOperation.GetValue().StartBackward
                                              .GetValueOrDefault();
                    Assert.True(actualStartBackward >= expectedStartBackwardLowerLimit,
                                $"The transition time between the operations is not correct: " +
                                $"expectedStartBackward: {expectedStartBackwardLowerLimit}, actualStartBackward {actualStartBackward}");

                    INodes predecessorNodesRecursive =
                        operationGraph.GetPredecessorNodesRecursive(new Node(currentPredecessor));
                    if (predecessorNodesRecursive != null)
                    {
                        IStackSet <ProductionOrderOperation> newPredecessorNodes =
                            new StackSet <ProductionOrderOperation>(
                                predecessorNodesRecursive.Select(x =>
                                                                 (ProductionOrderOperation)x.GetEntity()));
                        ValidatePredecessorOperationsTransitionTimeIsCorrect(newPredecessorNodes,
                                                                             currentOperation, operationGraph, traversedOperations);
                    }
                }
                else
                {
                    throw new MrpRunException(
                              "ProductionOrderToOperationGraph should only contain productionOrders/operations.");
                }
            }
        }
 public virtual void Add(T item)
 {
     StackSet.Push(item);
 }
 public void PurchaseOrderAdd(T_PurchaseOrder purchaseOrder)
 {
     _purchaseOrders.Push(purchaseOrder);
 }
 public void AddPredecessor(IGraphNode node)
 {
     _predecessors.Push(node);
 }
 public void AddSuccessor(IGraphNode node)
 {
     _successors.Push(node);
 }