public static CourseCommitContext From(HomeServerContext db, int courseId)
        {
            var workThemeExtensions = db.WorkThemes.Include(wt => wt.Work)
                .Where(wt => wt.Work.CourseId == courseId)
                .ToList()
                .Select(wt => new WorkThemeExtension(){Entity = wt})
                .ToList();

            return new CourseCommitContext()
            {
                CourseId = courseId,
                WorkThemeExtensions = workThemeExtensions
            };
        }
        public static object FromContext(int userId, HomeServerContext context)
        {
            var activeCourses = context.Courses.Where(c => c.UserId == userId && c.CourseStateId == 2).ToList();

            List<object> students = new List<object>();
            List<object> groups = new List<object>();

            List<object> subjects = new List<object>();
            List<object> terms = new List<object>();
            List<object> works = new List<object>();
            List<object> workStages = new List<object>();

            List<object> packs = new List<object>();
            List<object> courses = new List<object>();
            List<object> packToGroups = new List<object>();

            foreach (var course in activeCourses)
            {
                courses.Add(new
                {
                    Id = course.Id,
                    TermId = course.TermId,
                    Year = course.Year
                });

                terms.Add(new
                {
                    Id = course.Term.Id,
                    SubjectId = course.Term.SubjectId,
                    Name = course.Term.Name
                });

                subjects.Add(new
                {
                    Id = course.Term.Subject.Id,
                    Name = course.Term.Subject.Name
                });

                foreach (var work in course.Works)
                {
                    works.Add(new
                    {
                        Id = work.Id,
                        CourseId = work.CourseId,
                        Name = work.Name,
                        ShortName = work.ShortName,
                        WorkTypeId = work.WorkTypeId,
                        WorkControlTypeId = work.WorkControlTypeId,
                        HasThemes = work.HasThemes
                    });

                    work.WorkStages = context.WorkStages.Where(ws => ws.WorkId == work.Id).ToList();

                    foreach (var workStage in work.WorkStages)
                    {
                        workStages.Add(new
                        {
                            Id = workStage.Id,
                            WorkId = workStage.WorkId,
                            Name = workStage.Name,
                            Optional = workStage.Optional,
                            ParentWorkStageId = workStage.ParentWorkStageId
                        });
                    }
                }

                //init groups and students
                HashSet<Group> groupsSet = new HashSet<Group>();

                course.Packs.ForEach(p => p.Groups.ForEach(g => groupsSet.Add(g)));

                foreach (var group in groupsSet)
                {
                    groups.Add(new { Id = group.Id, Name = group.Name });

                    foreach(var student in group.Students)
                    {
                        DateTime? transactionDate = null;

                        var lastTransaction = student.Transactions.ToList().LastOrDefault();

                        if(lastTransaction != null)
                        {
                            transactionDate = lastTransaction.Date;
                        }

                        students.Add(new
                        {
                            Id = student.Id,
                            Name = student.Name,
                            Surname = student.Surname,
                            Patronymic = student.Patronymic,
                            GroupId = student.GroupId,
                            TransactionDate = transactionDate
                        });
                    }
                }

                foreach (var pack in course.Packs)
                {
                    packs.Add(new
                    {
                        Id = pack.Id,
                        CourseId = pack.CourseId,
                        Type = pack.PackTypeId
                    });

                    packToGroups.AddRange(pack.Groups.Select(g => new { GroupId = g.Id, PackId = pack.Id }));
                }

            }

            return new
            {
                Groups = groups,
                Students = students,

                Subjects = subjects,
                Terms = terms,
                Works = works,
                WorkStages = workStages,

                Courses = courses,
                Packs = packs,
                PackToGroups = packToGroups
            };
        }
        public static PackCommitContext From(HomeServerContext db, int packId)
        {
            var packLessons = db.Lessons.Where(l => l.PackId == packId).ToList();
            packLessons.ForEach(l => l.Pack = null);
            var packWorkProcs = db.WorkProcs.Where(wp => wp.PackId == packId).ToList();
            packWorkProcs.ForEach(wp => wp.Pack = null);

            var lessonsExtensions = packLessons.Select(l => new LessonExtension() { Entity = l }).ToList();
            lessonsExtensions.ForEach(le => le.Entity.Visits = null);

            var visitExtensions = new List<VisitExtension>();

            foreach (var lesson in packLessons)
            {
                visitExtensions.AddRange(lesson.Visits.Select(v => new VisitExtension()
                {
                    Entity = v,
                    LessonDate = lesson.Date,
                    PackId = packId
                }));
            }

            var workProcExtensions = new List<WorkProcExtension>();
            workProcExtensions = packWorkProcs.Select(wp => new WorkProcExtension() { Entity = wp }).ToList();
            workProcExtensions.ForEach(wpe => wpe.Entity.StudentWorkProcs = null);

            var studentWorkProcExtensions = new List<StudentWorkProcExtension>();
            var studentStageProcExtensions = new List<StudentStageProcExtension>();

            foreach (var workProc in packWorkProcs)
            {
                studentWorkProcExtensions.AddRange(workProc.StudentWorkProcs.Select(sw => new StudentWorkProcExtension()
                {
                    Entity = sw,
                    WorkId = sw.WorkProc.WorkId,
                    PackId = packId
                }));

                foreach (var studentStageProc in workProc.StudentWorkProcs)
                {
                    studentStageProcExtensions.AddRange(studentStageProc
                        .StudentStageProcs.Select(st => new StudentStageProcExtension()
                        {
                            Entity = st,
                            StudentId = studentStageProc.StudentId,
                            WorkId = workProc.WorkId,
                            PackId = packId
                        }));
                }
            }

            PackCommitContext packCommitContext = new PackCommitContext()
            {
                PackId = packId,
                LessonExtensions = lessonsExtensions,
                VisitExtensions = visitExtensions,
                WorkProcExtensions = workProcExtensions,
                StudentWorkProcExtensions = studentWorkProcExtensions,
                StudentStageProcExtensions = studentStageProcExtensions
            };

            return packCommitContext;
        }