public void DepthFirstSearch(PetriNetNode figure, int modelNum)
 {
     foreach (VArc a in figure.ThisArcs)
     {
         PetriNetNode f = figure == a.To ? a.From : a.To;
         f.ModelNumber = figure.ModelNumber;
         f.IsChecked   = true;
         foreach (VArc arc in f.ThisArcs)
         {
             PetriNetNode fig = f == arc.From ? arc.To : arc.From;
             if (fig.IsChecked == false)
             {
                 fig.IsChecked   = true;
                 fig.ModelNumber = modelNum;
                 DepthFirstSearch(fig, modelNum);
             }
         }
     }
 }
        private void NextColumn(List <PetriNetNode> figures)
        {
            int numberOfColumnedFigures = 0;
            int level = 1;

            while (figures.Count != numberOfColumnedFigures)
            {
                List <PetriNetNode> thisLevel = figures.Where(t => t.Column == level).ToList();
                foreach (PetriNetNode figureOnLevel in thisLevel)
                {
                    foreach (VArc arc in figureOnLevel.ThisArcs)
                    {
                        PetriNetNode figure = arc.To != figureOnLevel ? arc.To : arc.From;
                        if (figure.Column == 0)
                        {
                            figure.Column = level + 1;
                        }
                    }
                }
                level++;
                if (level > figures.Count)
                {
                    for (int i = 1; i < figures.Count; i++)
                    {
                        if (figures[i].Column == 0)
                        {
                            if (figures[i] is VPlace)
                            {
                                figures[i].Column = 1;
                            }
                            else
                            {
                                figures[i].Column = 2;
                            }
                            level = 1;
                            break;
                        }
                    }
                }
                numberOfColumnedFigures = figures.Count(figure => figure.Column != 0);
            }
        }
        //todo А почему в ArrangePetriNetModel используем MoveFigure, тогда как в ArrangeMulticlusterGraph прекрасно обходимся без него?!

        public void ArrangePetriNetModel(List <PetriNetNode> allFigures, IList <VArc> arcs, PNEditorControl control)
        {
            var PNEditorControl = new
            {
                Mode = new
                {
                    Graph    = 1,
                    PetriNet = 2
                }
            };
            var editorMode = 2;

            if (allFigures.Count == 0)
            {
                return;
            }

            foreach (var figure in allFigures)
            {
                figure.Column      = 0;
                figure.IsChecked   = false;
                figure.ModelNumber = 0;
            }

            SetColumnsForStartFigures(allFigures);
            NextColumn(allFigures);

            int modelNumber            = 0;
            int numberOfFiguresChecked = 0;

            while (numberOfFiguresChecked != allFigures.Count)
            {
                PetriNetNode next = allFigures[0];
                modelNumber++;
                foreach (PetriNetNode figure in allFigures)
                {
                    if (figure.IsChecked == false)
                    {
                        next             = figure;
                        next.ModelNumber = modelNumber;
                        next.IsChecked   = true;
                        break;
                    }
                }
                DepthFirstSearch(next, next.ModelNumber);
                numberOfFiguresChecked = allFigures.Count(t => t.IsChecked);
            }

            int numberOfModels = allFigures.Select(t => t.ModelNumber).Concat(new[] { 1 }).Max();
            List <PetriNetNode> figuresInOneModel = new List <PetriNetNode>();


            double spaceBetweenColumnsCoefficient = 1;
            int    maxNumberOfColumnsInAllModels  = 1;

            if (editorMode == PNEditorControl.Mode.Graph)
            {
                ArrangeMulticlusterGraph(numberOfModels, figuresInOneModel, allFigures, arcs);
                foreach (PetriNetNode figure in allFigures)
                {
                    control.MoveFigure(figure); //todo это ужас, конечно. надо нормально декомпозировать и убрать
                }
            }
            else
            {
                if (editorMode != PNEditorControl.Mode.PetriNet)
                {
                    return;                                              //todo нехорошо, в общем-то, привязки лишние
                }
                double maxYinModel = 0;
                for (int n = 1; n < numberOfModels + 1; n++)
                {
                    List <PetriNetNode> modelFigures;
                    int maxNumberOfRows;
                    int maxColumn;

                    SearchColumnWithMaxNumberOfRows(n, allFigures, out maxNumberOfRows, out maxColumn,
                                                    out modelFigures);

                    var numbercolumns = NumberOfColumnsOfFiguresList(modelFigures);

                    if (numbercolumns > maxNumberOfColumnsInAllModels)
                    {
                        maxNumberOfColumnsInAllModels = numbercolumns;
                    }

                    for (int i = 1; i < numbercolumns + 1; i++)
                    {
                        double coordY =
                            GetCoordYOfFirstFigureInColumn(maxNumberOfRows, i, modelFigures) +
                            maxYinModel;

                        List <PetriNetNode> thisColumn = modelFigures.Where(t => t.Column == i).ToList();
                        if (thisColumn.Count != 0)
                        {
                            if (thisColumn[0] is VPlace)
                            {
                                thisColumn[0].CoordY = coordY + 10;
                            }
                            else
                            {
                                thisColumn[0].CoordY = coordY;
                            }
                        }
                        int numberOfArcsInColumn = 0;

                        for (int k = 1; k < thisColumn.Count; k++)
                        {
                            thisColumn[k].CoordY = thisColumn[k - 1].CoordY + 70;
                        }

                        foreach (PetriNetNode figure in thisColumn)
                        {
                            numberOfArcsInColumn =
                                figure.ThisArcs.Count(t => (t.To.Column > t.From.Column && figure == t.From) ||
                                                      (t.From.Column > t.To.Column && figure == t.To));

                            figure.SpaceCoefficient = spaceBetweenColumnsCoefficient;
                        }

                        spaceBetweenColumnsCoefficient
                            = GetSpaceBetweenColumnsCoefficientMagically(numberOfArcsInColumn);
                    }

                    maxYinModel  = modelFigures.Select(t => t.CoordY).Concat(new[] { maxYinModel }).Max();
                    maxYinModel += 60; //todo magic number
                    spaceBetweenColumnsCoefficient = 1;
                }

                //todo вот тут не норм, подумать как для разных моделей свои раастояния рассчитывать
                for (int p = 1; p < maxNumberOfColumnsInAllModels + 1; p++)
                {
                    foreach (PetriNetNode figure in allFigures)
                    {
                        if (figure.Column == p)
                        {
                            //TODO здесь нужно как-то вообще убрать эту временную переменную
                            PetriNetNode tempF = PetriNetNode.Create();
                            foreach (PetriNetNode f in allFigures)
                            {
                                if (f.Column == figure.Column - 1)
                                {
                                    tempF = f;
                                    break;
                                }
                            }
                            double lyambda;
                            if (tempF is VPlace || tempF is VTransition)
                            {
                                lyambda = tempF.CoordX - 10;
                            }
                            else
                            {
                                lyambda = -60;
                            }

                            figure.CoordX = 10 + lyambda + 60 * figure.SpaceCoefficient;
                        }
                        control.MoveFigure(figure); //todo это ужас, конечно. надо нормально декомпозировать и убрать
                    }
                }
            }
        }