public ActionResult EditByFormType(int id, string formType, FormCollection form)
        {
            IDictionary<int, SimpleQuestion> simple = SimpleQuestion.FromForm(form);
            if (0 == simple.Count)
            {
                // Do something...
            }

            ViewBag.Id = id;
            ViewBag.FormType = formType;

            using (UnitOfWork uow = DebriefDataService.StartTransaction())
            {
                var writeRepo = new DebriefRepository<Debriefing>(uow.Session);

                var debrief = writeRepo.FindBy(id);
                if (null == debrief)
                {
                    return View("NotFound");
                }
                if (debrief.IsReadOnly())
                {
                    return RedirectToAction("ByFormType", new { id = id, formType = formType });
                }
                string gearCode = DebriefingExtensions.GearCodeFromVesselType(debrief.Vessel.VesselType);

                var questions = QuestionsForDebrief(debrief, formType);

                // Iterate though questions associated with this form type
                // LINQ for NHibernate prevents us from doing more within the LINQ query --
                // it really only works for something that can be directly translated to SQL
                // Not that there's anything wrong with that...
                foreach (var question in questions)
                {
                    if (simple.ContainsKey(question.Number))
                    {
                        LOGGER.DebugFormat("Found question# {0}", question.Number);
                        SimpleQuestion sq = simple[question.Number];
                        Evaluation eval =
                            debrief.Evaluations.FirstOrDefault(e => e.QuestionNumber == question.Number) ??
                            new Evaluation()
                            {
                                QuestionNumber = question.Number,
                            };
                        if (null == eval.Debriefing)
                        {
                            LOGGER.Debug("Adding new evaluation");
                            debrief.AddEvaluation(eval);
                        }
                        eval.Notes = sq.Notes;
                        LOGGER.DebugFormat("Encoding value [{0}] with Constraint {1}", sq.Answer, question.Constraint);
                        eval.Encode(question.Constraint, sq.Answer);
                    }
                }

                try
                {
                    writeRepo.Update(debrief);
                    uow.Commit();
                }
                catch (Exception ex)
                {
                    Flash("Failed to update debriefing.  Please contact technical support.");
                    LOGGER.Error("Failed to update debriefing", ex);
                    return EditByFormType(id, formType);
                }
            }
            return RedirectToAction("Details", new { id = id });
        }
        public static void FillDependentObjects(this Debriefing debrief, DebriefingHeaderViewModel dhvm, ISession session)
        {
            if (null != debrief && null != dhvm && null != session)
            {
                if (dhvm.VesselId != default(int))
                {
                    var vesselRepo = new DebriefRepository<Vessel>(session);
                    debrief.Vessel = vesselRepo.FindBy(dhvm.VesselId);
                }

                var staffRepo = new DebriefRepository<FieldStaff>(session);
                debrief.Observer = staffRepo.FindBy(dhvm.ObserverCode);
                debrief.Debriefer = staffRepo.FindBy(dhvm.DebrieferCode);

                var portRepo = new DebriefRepository<Port>(session);
                debrief.DeparturePort = portRepo.FindBy(dhvm.DeparturePortId);
                debrief.ReturnPort = portRepo.FindBy(dhvm.ReturnPortId);
            }
        }
        public ActionResult Edit(int id, DebriefingHeaderViewModel dhvm)
        {
            using (UnitOfWork uow = DebriefDataService.StartTransaction())
            {
                var writeRepo = new DebriefRepository<Debriefing>(uow.Session);

                var debrief = writeRepo.FindBy(id);
                if (null == debrief)
                {
                    return View("NotFound");
                }

                debrief.FillFromHeader(dhvm);

                // If the version or gear code changes, there's the possibility that any existing
                // answers are invalid.  Either the question numbers have changed or the form types
                // are different (no way to give PS-1 form feedback for a long line trip!)
                // This is handled by clearing out any existing evaluations and re-creating the list based
                // on the new gear code and version.
                // If there is no existing user input, this happens without any required user interaction.
                // If there _is_ user input, then we require a positive action to delete the existing data.
                if (debrief.GearCode != dhvm.GearCode || debrief.Version.Value.ToString() != dhvm.Version)
                {
                    bool hasAnswers = debrief.HasFilledEvaluation();
                    if (!hasAnswers || (hasAnswers && "YES".Equals(dhvm.PositiveActionResponse, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        // Delete existing evaluations
                        debrief.Evaluations.Clear();
                        // Create new set of evaluations
                        var questions = QuestionsForDebrief(debrief);
                        foreach (var question in questions)
                        {
                            debrief.AddEvaluation(new Evaluation()
                            {
                                QuestionNumber = question.Number
                            });
                        }
                    }
                    else
                    {
                        Flash("Change to gear type and/or version can't be made without a positive action");
                        return View(dhvm);
                    }
                }

                // Fill in full blown objects
                debrief.FillDependentObjects(dhvm, uow.Session);

                try
                {
                    writeRepo.Update(debrief);
                    uow.Commit();
                }
                catch (Exception ex)
                {
                    Flash("Failed to update briefing.  Please contact IT");
                    LOGGER.Error(String.Format("Failed to update briefing with Id {0}", id), ex);
                    return View(dhvm);
                }
            }
            return RedirectToAction("Index");
        }