private static void PopulateSatelliteInformationHelper(CourseCategory courseCategory, List <SatelliteInformation> satList, MainCurriculum curriculum, bool[] takenCoursesArray)
        {
            if (courseCategory.IsEdge())
            {
                courseCategory.Courses.ForEach(c =>
                {
                    if (c.IsPassed || takenCoursesArray[c.Id])//*v.i
                    {
                        satList[courseCategory.Id].NumberOfCoursesPassed += 1;
                        satList[courseCategory.Id].UnitsOfCoursesPassed  += c.Units;
                        if (c.IsLabOrWorkshop())
                        {
                            satList[courseCategory.Id].NumberOfWorkshopOrLabPassed += 1;
                            satList[courseCategory.Id].UnitsOfWorkshopOrLabPassed  += c.Units;
                        }
                    }
                });
            }
            else
            {
                courseCategory.OutputGates.ForEach(og =>
                {
                    var courseCategoryChild = og.DesCourseCategory;
                    var courseCategorySrc   = og.SrcCourseCategory;

                    if (og.IsAllowedAllCredits(curriculum.StudentCredit))
                    {
                        //first calc
                        PopulateSatelliteInformationHelper(courseCategoryChild, satList, curriculum, takenCoursesArray);

                        //then set values
                        satList[courseCategorySrc.Id].NumberOfCoursesPassed       += satList[courseCategoryChild.Id].NumberOfCoursesPassed;
                        satList[courseCategorySrc.Id].UnitsOfCoursesPassed        += satList[courseCategoryChild.Id].UnitsOfCoursesPassed;
                        satList[courseCategorySrc.Id].NumberOfWorkshopOrLabPassed += satList[courseCategoryChild.Id].NumberOfWorkshopOrLabPassed;
                        satList[courseCategorySrc.Id].UnitsOfWorkshopOrLabPassed  += satList[courseCategoryChild.Id].UnitsOfWorkshopOrLabPassed;
                    }
                });
            }
        }
        private static bool IsValidStateHelper(MainCurriculum curriculum, List <SatelliteInformation> satList, CourseCategory courseCategory)
        {
            if (courseCategory.IsEdge())
            {
                return(true);
            }

            var graphEdges = courseCategory.OutputGates;

            for (int i = 0; i < graphEdges.Count; i++)
            {
                var graphEdge = graphEdges[i];

                if (graphEdge.IsAllowedAllCredits(curriculum.StudentCredit))
                {
                    var crtLst = graphEdge.CertificateList;

                    bool isOk = true;

                    for (int j = 0; j < crtLst.Count; j++)
                    {
                        var crt = crtLst[j];
                        for (int m = 0; m < crt.ConstraintList.Count; m++)
                        {
                            var constraint = crt.ConstraintList[m];

                            if (constraint is MinNumberMaxNumberOfCoursesConstraint)
                            {
                                isOk = constraint.IsOk(satList[graphEdge.DesCourseCategory.Id].NumberOfCoursesPassed);
                            }
                            else if (constraint is MinUnitsMaxUnitsOfCoursesConstraint)
                            {
                                isOk = constraint.IsOk(satList[graphEdge.DesCourseCategory.Id].UnitsOfCoursesPassed);
                            }
                            else if (constraint is NumberOfCoursesMustBeLabOrWorkshopConstraint)
                            {
                                isOk = constraint.IsOk(satList[graphEdge.DesCourseCategory.Id].NumberOfWorkshopOrLabPassed);
                            }
                            else if (constraint is UnitOfCoursesMustBeLabOrWorkshopConstraint)
                            {
                                isOk = constraint.IsOk(satList[graphEdge.DesCourseCategory.Id].UnitsOfWorkshopOrLabPassed);
                            }
                            else
                            {
                                throw new Exception();
                            }
                            if (!isOk)
                            {
                                break;
                            }
                        }

                        if (!isOk)
                        {
                            break;
                        }
                    }

                    if (!isOk)
                    {
                        return(false);
                    }

                    if (IsValidStateHelper(curriculum, satList, graphEdge.DesCourseCategory) == false)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }