/// <summary>
        /// create a single footprint from a list of footprints
        /// </summary>
        /// <param name="footprintList">A list of footprints</param>
        /// <returns>A Footprint</returns>
        /// <autor>Andrej Albrecht</autor>
        public static ComparingFootprint MergeFootprints(List <ComparingFootprint> footprintList)
        {
            ComparingFootprint footprintResult = new ComparingFootprint();

            footprintResult.MergeFootprints(footprintList);
            return(footprintResult);
        }
 /// <summary>
 /// Adds the event header from a given footprint
 /// </summary>
 /// <param name="footprint">A Footprint</param>
 /// <autor>Andrej Albrecht</autor>
 private void AddEventHeader(ComparingFootprint footprint)
 {
     foreach (String name in footprint.HeaderWithEventNames)
     {
         AddEventHeader(name);
     }
 }
        //ResultMatrix with ResultMatrix-cellTypes

        /// <summary>
        /// Compares two footprints and saves the result in ResultMatrix
        /// </summary>
        /// <param name="footprint1">The first footprint</param>
        /// <param name="footprint2">The second footprint</param>
        /// <autor>Andrej Albrecht</autor>
        public ComparingFootprintResultMatrix(ComparingFootprint footprint1, ComparingFootprint footprint2)
        {
            AddEventHeader(footprint1);
            AddEventHeader(footprint2);

            ResultMatrix = new ResultCellType[HeaderWithEventNames.Count, HeaderWithEventNames.Count];

            for (int row = 0; row < HeaderWithEventNames.Count; row++)
            {
                for (int column = 0; column < HeaderWithEventNames.Count; column++)
                {
                    CellType matrix1Cell = footprint1.GetFootprintCellState(HeaderWithEventNames[row], HeaderWithEventNames[column]);
                    CellType matrix2Cell = footprint2.GetFootprintCellState(HeaderWithEventNames[row], HeaderWithEventNames[column]);

                    if (matrix1Cell.Equals(matrix2Cell))
                    {
                        //If the cellstates of the both footprints are equal, then they have no differences
                        ResultMatrix[row, column] = ResultCellType.NoDifferences;
                    }
                    else
                    {
                        // find the right CellState for the differences of both footprints
                        ResultMatrix[row, column] = ComparingFootprintResultMatrixCell.GetResultCellType(matrix1Cell, matrix2Cell);
                    }
                }
            }
        }
        /// <summary>
        /// Create a footprint from one case
        /// </summary>
        /// <param name="c">A case</param>
        /// <param name="cases">A list of cases</param>
        /// <autor>Andrej Albrecht</autor>
        public static ComparingFootprint CreateFootprint(Case c, List <Case> cases = null)
        {
            ComparingFootprint footprint = new ComparingFootprint();

            foreach (Event Event in c.EventList)
            {
                footprint.AddEventHeader(Event.Name);
            }

            int numberOfEventsInCase = c.EventList.Count;

            CellType[,] resultMatrix = new CellType[numberOfEventsInCase, numberOfEventsInCase];

            for (int row = 0; row < footprint.HeaderWithEventNames.Count; row++)
            {
                for (int column = 0; column < footprint.HeaderWithEventNames.Count; column++)
                {
                    //first of all, reset the cellstate to nothing:
                    resultMatrix[row, column] = CellType.Nothing;

                    //Go through all events of the case
                    for (int eventIndex = 0; eventIndex < c.EventList.Count - 1; eventIndex++)
                    {
                        String leftEventName  = c.EventList.ElementAt(eventIndex).Name;
                        String rightEventName = c.EventList.ElementAt(eventIndex + 1).Name;

                        if (footprint.HeaderWithEventNames[row].Equals(leftEventName) && footprint.HeaderWithEventNames[column].Equals(rightEventName) &&
                            leftEventName.Equals(rightEventName))
                        {
                            resultMatrix[row, column] = CellType.Loop;
                            resultMatrix[row, column] = CellType.Loop;
                        }

                        else if (footprint.HeaderWithEventNames[row].Equals(leftEventName) && footprint.HeaderWithEventNames[column].Equals(rightEventName))
                        {
                            if (resultMatrix[row, column].Equals(CellType.Left))
                            {
                                resultMatrix[row, column] = CellType.Parallel;
                            }

                            else if (resultMatrix[row, column].Equals(CellType.Nothing))
                            {
                                resultMatrix[row, column] = CellType.Right;

                                if (row != column)
                                {
                                    resultMatrix[column, row] = CellType.Left;
                                    //ResultMatrix[Row, Column] = CellType.Left;
                                }
                            }
                        }

                        else if (footprint.HeaderWithEventNames[row].Equals(rightEventName) && footprint.HeaderWithEventNames[column].Equals(leftEventName))
                        {
                            if (resultMatrix[row, column].Equals(CellType.Right))
                            {
                                resultMatrix[row, column] = CellType.Parallel;
                            }

                            else if (resultMatrix[row, column].Equals(CellType.Nothing))
                            {
                                resultMatrix[row, column] = CellType.Left;
                            }
                            else if (resultMatrix[row, column].Equals(CellType.Parallel))
                            {
                                resultMatrix[row, column] = CellType.Parallel;
                            }
                        }
                    }
                }
            }

            footprint.ResultMatrix = resultMatrix;

            return(footprint);
        }
        /// <summary>
        /// Create a footprint for a petrinet
        /// </summary>
        /// <param name="petriNet">Petrinet</param>
        /// <returns>returns a ComparingFootprint</returns>
        /// <autor>Andrej Albrecht</autor>
        public static ComparingFootprint CreateFootprint(PetriNet petriNet)
        {
            ComparingFootprint resultFootprint = new ComparingFootprint(new CellType[petriNet.Transitions.Count, petriNet.Transitions.Count]);

            foreach (Transition transition in petriNet.Transitions)
            {
                if (!transition.IsLoop)
                {
                    resultFootprint.AddEventHeader(transition.Name);
                }
            }

            List <String> transitionLoops = Transition.GetTransitionLoops(petriNet);

            int indexRow = 0;

            foreach (String headerNameRow in resultFootprint.HeaderWithEventNames)
            {
                int indexColumn = 0;
                foreach (String headerNameColumn in resultFootprint.HeaderWithEventNames)
                {
                    CellType transitionRelationship = GetTransitionRelationship(headerNameRow, headerNameColumn, petriNet);

                    //reset the cellstate to nothing, if the cell have no state:
                    resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Nothing;

                    //save the found transition relationship to the cell and check parallelism with method checkTransitionParallel:
                    if (headerNameRow.Equals(headerNameColumn) && transitionLoops.Contains(headerNameColumn))
                    {
                        resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Loop;
                    }
                    else if (transitionRelationship.Equals(CellType.Parallel))
                    {
                        resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Parallel;

                        if (indexRow != indexColumn)
                        {
                            resultFootprint.ResultMatrix[indexColumn, indexRow] = CellType.Parallel;
                        }
                    }
                    else if (transitionRelationship.Equals(CellType.Right))
                    {
                        if (resultFootprint.ResultMatrix[indexRow, indexColumn].Equals(CellType.Left))
                        {
                            resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Parallel;
                        }

                        resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Right;

                        if (indexRow != indexColumn)
                        {
                            resultFootprint.ResultMatrix[indexColumn, indexRow] = CellType.Left;
                        }
                    }
                    else if (transitionRelationship.Equals(CellType.Left))
                    {
                        if (resultFootprint.ResultMatrix[indexRow, indexColumn].Equals(CellType.Right))
                        {
                            resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Parallel;
                        }

                        resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Left;
                    }

                    indexColumn++;
                }
                indexRow++;
            }
            return(resultFootprint);
        }