/// <summary>
		/// Regenerates the question.
		/// </summary>
		private async Task RegenerateQuestionAsync(
			GeneratedQuestionTemplate generatedQuestionTemplate,
			int seed,
			UserQuestionData userQuestionData)
		{
			var result = await _questionGenerator.GenerateQuestionAsync
			(
				generatedQuestionTemplate,
				seed
			);

			userQuestionData.Seed = seed;
			userQuestionData.CachedQuestionData = result.SerializedQuestion;
			userQuestionData.CachedQuestionDataTime = _timeProvider.UtcNow;
		}
		/// <summary>
		/// Returns the last question submission, if any.
		/// </summary>
		private QuestionSubmission GetLastQuestionSubmission(
			UserQuestionData userQuestionData)
		{
			if (userQuestionData.LastQuestionSubmission == null)
				return null;

			try
			{
				return _jsonSerializer
					.Deserialize<QuestionSubmission>(userQuestionData.LastQuestionSubmission);
			}
			catch
			{
				return null;
			}
		}
		/// <summary>
		/// Ensures a user question data object exists for the given question
		/// (for the current user).
		/// </summary>
		private async Task<UserQuestionData> EnsureUserQuestionDataAsync(
			int userId,
			Question question)
		{
			var generatedQuestion = question as GeneratedQuestionTemplate;
			var userQuestionData = await _dbContext.UserQuestionData
				.SingleOrDefaultAsync
				(
					   s => s.UserId == userId
					&& s.QuestionId == question.Id
				);

			if (userQuestionData == null)
			{
				userQuestionData = new UserQuestionData()
				{
					UserId = userId,
					QuestionId = question.Id
				};

				if (generatedQuestion != null)
				{
					var seed = _randomNumberProvider.NextInt();
					await RegenerateQuestionAsync(generatedQuestion, seed, userQuestionData);
				}

				_dbContext.UserQuestionData.Add(userQuestionData);
			}
			else if (generatedQuestion != null 
				&& generatedQuestion.DateModified > userQuestionData.CachedQuestionDataTime)
			{
				await RegenerateQuestionAsync
				(
					generatedQuestion,
					userQuestionData.Seed ?? _randomNumberProvider.NextInt(),
					userQuestionData
				);
			}

			await _dbContext.SaveChangesAsync();

			return userQuestionData;
		}
        /// <summary>
        /// Adds a question submission to the database.
        /// </summary>
        public TestDatabaseBuilder AddQuestionSubmission(
            string classroomName,
            string questionCategoryName,
            string questionName,
            string userName,
            string submissionContents,
            double score = 0.0,
            DateTime? dateSubmitted = null,
            int? seed = null,
            string cachedQuestionData = null)
        {
            var question = _buildContext.Questions
                .Where(q => q.QuestionCategory.Classroom.Name == classroomName)
                .Where(q => q.QuestionCategory.Name == questionCategoryName)
                .Single(q => q.Name == questionName);

            var user = _buildContext.Users
                .Single(u => u.UserName == userName);

            var userQuestionData = _buildContext.UserQuestionData
                .Where(uqd => uqd.User == user)
                .SingleOrDefault(uqd => uqd.Question == question);

            if (userQuestionData == null)
            {
                userQuestionData = new UserQuestionData()
                {
                    UserId = user.Id,
                    QuestionId = question.Id,
                    LastQuestionSubmission = submissionContents,
                    CachedQuestionData = cachedQuestionData,
                    CachedQuestionDataTime = dateSubmitted,
                    Seed = seed
                };

                _buildContext.UserQuestionData.Add(userQuestionData);
            }
            else
            {
                userQuestionData.LastQuestionSubmission = submissionContents;
                userQuestionData.CachedQuestionData = cachedQuestionData;
                userQuestionData.CachedQuestionDataTime = dateSubmitted;
                userQuestionData.Seed = seed;

                _buildContext.UserQuestionData.Update(userQuestionData);
            }

            var userQuestionSubmission = new UserQuestionSubmission()
            {
                DateSubmitted = dateSubmitted ?? DateTime.MinValue,
                UserQuestionData = userQuestionData,
                Score = score
            };

            _buildContext.UserQuestionSubmissions.Add(userQuestionSubmission);
            _buildContext.SaveChanges();

            return this;
        }