// Private function used by POST Edit method. It is the major part of that method,
        // since it is responsible for the actual edition of an existing RegularTask (and its Answer).
        // This function returns a proper ActionResult depending whether the action was successful 
        // or failed at some point.
        private ActionResult EditTaskInternal(RegularTask regulartask, Subject sub, int isAnswerChanged,
            string answerType, string valueAns, string textAns, IList<string> multiChoiceList,
            IList<string> multiAnswerList, ICollection<string> singleChoiceList, int singleCorrectNo)
        {
            // First let's see if the answer for the task is being changed or not.
            // If it's not then we have an easy case to deal with.
            if (isAnswerChanged == 0)
            {
                UpdateSubjectTime(sub);

                regulartask.CorrectAnswers = 0;
                regulartask.Attempts = 0;
                db.Entry(regulartask).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Details", "Subject", new { id = regulartask.SubjectID });
            }

            // Variable holding answer that belongs to the task
            var ans = db.Answers.Find(regulartask.ID);

            // And now let's cope with the case when the answer is being changed as well as the task.
            switch (answerType)
            {
                case Answer.SINGLE_VALUE_ANSWER:
                    if (String.IsNullOrEmpty(valueAns))
                    {
                        // In this case we want to reload the Edit page with the original RegularTask
                        return ReloadPageWithStatement(db.RegularTasks.Find(regulartask.ID), answerType, sub.Name, sub.ID);
                    }

                    if (ans.className() == answerType)
                    {
                        // We don't have to create a completely new Answer, only update the current one
                        ((SingleValueAnswer)ans).Value = valueAns;
                        db.Entry(ans).State = EntityState.Modified;
                    }
                    else
                    {
                        // Delete previous answer and create new SingleValueAnswer
                        removeOldChoices(ans.className(), regulartask.ID);
                        db.Answers.Remove(ans);
                        db.SaveChanges();

                        var singleValueAnswer = new SingleValueAnswer(valueAns) { TaskID = regulartask.ID };
                        db.SingleValueAnswers.Add(singleValueAnswer);
                    }

                    break;
                case Answer.TEXT_ANSWER:
                    if (String.IsNullOrEmpty(textAns))
                    {
                        // In this case we want to reload the Edit page with the original RegularTask
                        return ReloadPageWithStatement(db.RegularTasks.Find(regulartask.ID), answerType, sub.Name, sub.ID);
                    }

                    if (ans.className() == answerType)
                    {
                        // We don't have to create a completely new Answer, only update the current one
                        ((TextAnswer)ans).Text = textAns;
                        db.Entry(ans).State = EntityState.Modified;
                    }
                    else
                    {
                        // Delete previous answer and create new TextAnswer
                        removeOldChoices(ans.className(), regulartask.ID);
                        db.Answers.Remove(ans);
                        db.SaveChanges();

                        var textAnswer = new TextAnswer(textAns) { TaskID = regulartask.ID };
                        db.TextAnswers.Add(textAnswer);
                    }

                    break;
                case Answer.SINGLE_CHOICE_ANSWER:
                    if (singleCorrectNo >= singleChoiceList.Count || singleCorrectNo < 0)
                    {
                        throw new RetryLimitExceededException("The number of the correct Choice for SingleChoiceAnswer is beyond valid range.");
                    }

                    // Case when we haven't got any valid Choices for the SingleChoiceAnswer or some choices are empty
                    if (singleChoiceList.Count == 0 || singleChoiceList.Count(String.IsNullOrEmpty) != 0)
                    {
                        // In this case we want to reload the Edit page with the original RegularTask
                        return ReloadPageWithStatement(db.RegularTasks.Find(regulartask.ID), answerType, sub.Name, sub.ID);
                    }

                    if (ans.className() == answerType)
                    {
                        // We don't have to create a completely new Answer, only update the current one
                        ((SingleChoiceAnswer)ans).CorrectAnswer = singleCorrectNo;
                        db.Entry(ans).State = EntityState.Modified;

                        // Let's remove old choices ...
                        removeOldChoices(ans.className(), regulartask.ID);

                        // ... and add new ones
                        foreach (var singleChoice in singleChoiceList.Select(s => new SingleChoice(s) { SingleChoiceAnswerID = regulartask.ID }))
                        {
                            singleChoice.SingleChoiceAnswerID = regulartask.ID;
                            db.SingleChoices.Add(singleChoice);
                        }
                    }
                    else
                    {
                        // Delete previous answer and create new SingleChoiceAnswer
                        removeOldChoices(ans.className(), regulartask.ID);
                        db.Answers.Remove(ans);
                        db.SaveChanges();

                        var singleChoiceAnswer = new SingleChoiceAnswer(singleCorrectNo) { TaskID = regulartask.ID };
                        db.SingleChoiceAnswers.Add(singleChoiceAnswer);

                        foreach (var singleChoice in singleChoiceList.Select(s => new SingleChoice(s) { SingleChoiceAnswerID = regulartask.ID }))
                        {
                            db.SingleChoices.Add(singleChoice);
                        }
                    }

                    break;
                case Answer.MULTIPLE_CHOICE_ANSWER:
                    if (multiChoiceList.Count != multiAnswerList.Count)
                    {
                        throw new RetryLimitExceededException("The number of Options doesn't equal the number of true-false answers.");
                    }

                    // Case when we haven't got any valid Choices for the MultiChoiceAnswer
                    if (multiChoiceList.Count(t => !String.IsNullOrEmpty(t)) == 0)
                    {
                        // In this case we want to reload the Edit page with the original RegularTask
                        return ReloadPageWithStatement(db.RegularTasks.Find(regulartask.ID), answerType, sub.Name, sub.ID);
                    }

                    if (ans.className() == answerType)
                    {
                        // We don't have to create a completely new Answer, only update the current one
                        // Let's remove old choices ...
                        removeOldChoices(ans.className(), regulartask.ID);

                        // ... and add new ones
                        for (var i = 0; i < multiChoiceList.Count; i++)
                        {
                            // No safety check whether the values send by POST are valid ones ('True' and 'False' are valid).
                            // Every invalid value will be interpreted as 'False'
                            var tempAns = (multiAnswerList[i].Equals("True", StringComparison.OrdinalIgnoreCase));
                            var multiChoice = new MultiChoice(multiChoiceList[i], tempAns) { MultipleChoiceAnswerID = regulartask.ID };
                            db.MultiChoices.Add(multiChoice);
                        }
                    }
                    else
                    {
                        // Delete previous answer and create new MultipleChoiceAnswer
                        removeOldChoices(ans.className(), regulartask.ID);
                        db.Answers.Remove(ans);
                        db.SaveChanges();

                        var multiChoiceAnswer = new MultipleChoiceAnswer { TaskID = regulartask.ID };
                        db.MultipleChoiceAnswers.Add(multiChoiceAnswer);

                        for (var i = 0; i < multiChoiceList.Count; i++)
                        {
                            // No safety check whether the values send by POST are valid ones ('True' and 'False' are valid).
                            // Every invalid value will be interpreted as 'False'
                            var tempAns = (multiAnswerList[i].Equals("True", StringComparison.OrdinalIgnoreCase));
                            var multiChoice = new MultiChoice(multiChoiceList[i], tempAns) { MultipleChoiceAnswerID = regulartask.ID };
                            db.MultiChoices.Add(multiChoice);
                        }
                    }

                    break;
            }

            UpdateSubjectTime(sub);

            regulartask.CorrectAnswers = 0;
            regulartask.Attempts = 0;
            db.Entry(regulartask).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Details", "Subject", new { id = regulartask.SubjectID });
        }
        // Private function used by POST Create method. It is the major part of that method,
        // since it is responsible for the actual creation of a new RegularTask with its Answer
        // and inserting those objects into the database. This function returns a proper ActionResult
        // depending whether the creation/insertion was successful or failed at some point.
        private ActionResult CreateTaskInternal(RegularTask regulartask, string subjectName, int subjectId,
            string answerType, string valueAns, string textAns, IList<string> multiChoiceList,
            IList<string> multiAnswerList, ICollection<string> singleChoiceList, int singleCorrectNo)
        {
            switch (answerType)
            {
                case Answer.SINGLE_VALUE_ANSWER:
                    if (String.IsNullOrEmpty(valueAns))
                    {
                        return ReloadPageWithStatement(regulartask, answerType, subjectName, subjectId);
                    }

                    // Create new SingleValueAnswer
                    var singleValueAnswer = new SingleValueAnswer(valueAns);
                    db.SingleValueAnswers.Add(singleValueAnswer);

                    break;
                case Answer.TEXT_ANSWER:
                    if (String.IsNullOrEmpty(textAns))
                    {
                        return ReloadPageWithStatement(regulartask, answerType, subjectName, subjectId);
                    }

                    // Create new TextAnswer
                    var textAnswer = new TextAnswer(textAns);
                    db.TextAnswers.Add(textAnswer);

                    break;
                case Answer.SINGLE_CHOICE_ANSWER:
                    if (singleCorrectNo >= singleChoiceList.Count || singleCorrectNo < 0)
                    {
                        throw new RetryLimitExceededException("The number of the correct Choice for SingleChoiceAnswer is beyond valid range.");
                    }

                    // Case when we haven't got any valid Choices for the SingleChoiceAnswer or some choices are empty
                    if (singleChoiceList.Count == 0 || singleChoiceList.Count(String.IsNullOrEmpty) != 0)
                    {
                        return ReloadPageWithStatement(regulartask, answerType, subjectName, subjectId);
                    }

                    // Create new SingleChoiceAnswer
                    var singleChoiceAnswer = new SingleChoiceAnswer(singleCorrectNo);
                    db.SingleChoiceAnswers.Add(singleChoiceAnswer);

                    foreach (var singleChoice in singleChoiceList.Select(s => new SingleChoice(s)))
                    {
                        db.SingleChoices.Add(singleChoice);
                    }

                    break;
                case Answer.MULTIPLE_CHOICE_ANSWER:
                    if (multiChoiceList.Count != multiAnswerList.Count)
                    {
                        throw new RetryLimitExceededException("The number of Options doesn't equal the number of true-false answers.");
                    }

                    // Case when we haven't got any valid Choices for the MultiChoiceAnswer
                    if (multiChoiceList.Count(t => !String.IsNullOrEmpty(t)) == 0)
                    {
                        return ReloadPageWithStatement(regulartask, answerType, subjectName, subjectId);
                    }

                    // Create new MultiChoiceAnswer
                    var multiChoiceAnswer = new MultipleChoiceAnswer();
                    db.MultipleChoiceAnswers.Add(multiChoiceAnswer);

                    for (var i = 0; i < multiChoiceList.Count; i++)
                    {
                        // No safety check whether the values send by POST are valid ones ('True' and 'False' are valid).
                        // Every invalid value will be interpreted as 'False'
                        var tempAns = (multiAnswerList[i].Equals("True", StringComparison.OrdinalIgnoreCase));
                        var multiChoice = new MultiChoice(multiChoiceList[i], tempAns);
                        db.MultiChoices.Add(multiChoice);
                    }

                    break;
                default:
                    // No answer has been selected - let's remind the user that he has to pick one
                    return ReloadPageWithStatement(regulartask, answerType, subjectName, subjectId);
            }

            UpdateSubjectTime(db.Subjects.Find(regulartask.SubjectID));

            regulartask.CorrectAnswers = 0;
            regulartask.Attempts = 0;
            db.RegularTasks.Add(regulartask);
            db.SaveChanges();
            return RedirectToAction("Details", "Subject", new { id = subjectId });
        }