public static EmailStudentsViewModel Create(IRepository repository, ICeremonyService ceremonyService, string userId, List<string> templateNames )
        {
            Check.Require(repository != null, "Repository is required.");

            var viewModel = new EmailStudentsViewModel()
                                {
                                    Ceremonies = ceremonyService.GetCeremonies(userId, TermService.GetCurrent()),
                                    TemplateTypes = repository.OfType<TemplateType>().Queryable.Where(a => templateNames.Contains(a.Name)).ToList()
                                };

            return viewModel;
        }
        public ActionResult EmailStudents(EmailStudentsViewModel emailStudents, HttpPostedFileBase file)
        {
            ModelState.Clear();
            // get the template type
            var templateType = emailStudents.TemplateType;

            //if (templateType == null) // It looks like this can be optional. The two mass Email Templates don't look like they are actually used later on
            //{
            //    Message = "Invalid template type, please have the database checked.";
            //    return RedirectToAction("Index");
            //}

            if (emailStudents.Ceremony == null)
            {
                ModelState.AddModelError("Ceremony", "Ceremony is required.");
            }
            if (string.IsNullOrWhiteSpace(emailStudents.Subject))
            {
                ModelState.AddModelError("Subject", "Subject is required");
            }
            if (string.IsNullOrWhiteSpace(emailStudents.Body))
            {
                ModelState.AddModelError("Body", "Body is required.");
            }

            if (templateType != null && templateType.Name == StaticValues.Template_ElectronicTicketDistribution && emailStudents.EmailType != EmailStudentsViewModel.MassEmailType.Registered)
            {
                ModelState.AddModelError("EmailType", "The Student Population must be Registered when using the Electronic Ticket Distribution Template");
            }

            if (ModelState.IsValid)
            {
                Attachment attachment = null;

                if (file != null)
                {
                    var reader = new BinaryReader(file.InputStream);
                    var data = reader.ReadBytes(file.ContentLength);

                    attachment = new Attachment();
                    attachment.Contents = data;
                    attachment.ContentType = file.ContentType;
                    attachment.FileName = file.FileName;
                }

                // Those registered
                if (emailStudents.EmailType == EmailStudentsViewModel.MassEmailType.Registered)
                {
                    foreach (var participation in emailStudents.Ceremony.RegistrationParticipations.Where(a => !a.Cancelled))
                    {
                        var bodyText = _letterGenerator.GenerateEmailAllStudents(emailStudents.Ceremony, participation.Registration.Student, emailStudents.Body, templateType, participation.Registration, attachment, Request, Url);

                        var eq = new EmailQueue(participation.Registration.Student, null, emailStudents.Subject, bodyText, false);
                        eq.Registration = participation.Registration;
                        eq.RegistrationParticipation = participation;

                        if (attachment != null)
                        {
                            eq.Attachment = attachment;
                        }

                        Repository.OfType<EmailQueue>().EnsurePersistent(eq);
                    }
                }
                // Those eligible but not registered
                else if (emailStudents.EmailType == EmailStudentsViewModel.MassEmailType.Eligible || emailStudents.EmailType == EmailStudentsViewModel.MassEmailType.AllEligible)
                {
                    var students = emailStudents.Ceremony.Majors.SelectMany(a => a.Students).Where(a => a.TermCode == emailStudents.Ceremony.TermCode);

                    // filter out students who have registered, only trying to send to students who are eligible and not registered
                    if (emailStudents.EmailType == EmailStudentsViewModel.MassEmailType.Eligible)
                    {
                        students = students.Where(a => !emailStudents.Ceremony.RegistrationParticipations.Select(x => x.Registration.Student).Contains(a)).ToList();
                    }

                    foreach (var student in students)
                    {
                        var bodyText = _letterGenerator.GenerateEmailAllStudents(emailStudents.Ceremony, student, emailStudents.Body, templateType, null, attachment, Request, Url);

                        var eq = new EmailQueue(student, null, emailStudents.Subject, bodyText, false);
                        if (attachment != null)
                        {
                            eq.Attachment = attachment;
                        }
                        Repository.OfType<EmailQueue>().EnsurePersistent(eq);
                    }
                }

                else if(emailStudents.EmailType == EmailStudentsViewModel.MassEmailType.ExtraTicketDenied)
                {
                    var useTemplate = emailStudents.Ceremony.Templates.FirstOrDefault(a => a.TemplateType == templateType && a.IsActive);
                    foreach (var participation in emailStudents.Ceremony.RegistrationParticipations.Where(a => a.ExtraTicketPetition != null && a.ExtraTicketPetition.IsApproved == false))
                    {
                        //var bodyText = _letterGenerator.GenerateEmailAllStudents(emailStudents.Ceremony, participation.Registration.Student, emailStudents.Body, templateType, participation.Registration);
                        var bodyText = _letterGenerator.GenerateExtraTicketRequestPetitionDecision(participation, useTemplate, attachment, Request, Url, emailStudents.Body);//(emailStudents.Ceremony, participation.Registration.Student, emailStudents.Body, templateType, participation.Registration);

                        var eq = new EmailQueue(participation.Registration.Student, null, emailStudents.Subject, bodyText, false);
                        eq.Registration = participation.Registration;
                        eq.RegistrationParticipation = participation;

                        if (attachment != null)
                        {
                            eq.Attachment = attachment;
                        }

                        Repository.OfType<EmailQueue>().EnsurePersistent(eq);
                    }
                }

                Message = "Emails have been queued.";
                return RedirectToAction("Index");
            }

            var viewModel = EmailStudentsViewModel.Create(Repository, _ceremonyService, CurrentUser.Identity.Name, _massEmailTemplates);
            viewModel.Ceremony = emailStudents.Ceremony;
            viewModel.Subject = emailStudents.Subject;
            viewModel.Body = emailStudents.Body;
            viewModel.TemplateType = emailStudents.TemplateType;
            return View(viewModel);
        }