/**
   * Produce a FeedbackResponseCommentSearchResultBundle from the Results<ScoredDocument>
   * collection. The list of InstructorAttributes is used to filter out the search result.
   */
  public FeedbackResponseCommentSearchResultBundle fromResults(
      Results<ScoredDocument> results, List<InstructorAttributes> instructors) {
    if (results == null) {
      return this;
    }

    // get instructor's information
    instructorEmails = new HashSet<String>();
    instructorCourseIdList = new HashSet<String>();
    for (InstructorAttributes ins : instructors) {
      instructorEmails.add(ins.email);
      instructorCourseIdList.add(ins.courseId);
    }

    cursor = results.getCursor();
    List<ScoredDocument> filteredResults = filterOutCourseId(results, instructors);
    for (ScoredDocument doc : filteredResults) {
      // get FeedbackResponseComment from results
      FeedbackResponseCommentAttributes comment =
          JsonUtils.fromJson(
              doc.getOnlyField(Const.SearchDocumentField.FEEDBACK_RESPONSE_COMMENT_ATTRIBUTE)
                  .getText(),
              FeedbackResponseCommentAttributes.class);
      if (frcLogic.getFeedbackResponseComment(comment.getId()) == null) {
        frcLogic.deleteDocument(comment);
        continue;
      }
      comment.sendingState = CommentSendingState.SENT;
      List<FeedbackResponseCommentAttributes> commentList =
          comments.get(comment.feedbackResponseId);
      if (commentList == null) {
        commentList = new ArrayList<FeedbackResponseCommentAttributes>();
        comments.put(comment.feedbackResponseId, commentList);
      }
      commentList.add(comment);

      // get related response from results
      FeedbackResponseAttributes response =
          JsonUtils.fromJson(
              doc.getOnlyField(Const.SearchDocumentField.FEEDBACK_RESPONSE_ATTRIBUTE).getText(),
              FeedbackResponseAttributes.class);
      if (frLogic.getFeedbackResponse(response.getId()) == null) {
        frcLogic.deleteDocument(comment);
        continue;
      }
      List<FeedbackResponseAttributes> responseList = responses.get(response.feedbackQuestionId);
      if (responseList == null) {
        responseList = new ArrayList<FeedbackResponseAttributes>();
        responses.put(response.feedbackQuestionId, responseList);
      }
      if (!isAdded.contains(response.getId())) {
        isAdded.add(response.getId());
        responseList.add(response);
      }

      // get related question from results
      FeedbackQuestionAttributes question =
          JsonUtils.fromJson(
              doc.getOnlyField(Const.SearchDocumentField.FEEDBACK_QUESTION_ATTRIBUTE).getText(),
              FeedbackQuestionAttributes.class);
      if (fqLogic.getFeedbackQuestion(question.getId()) == null) {
        frcLogic.deleteDocument(comment);
        continue;
      }
      List<FeedbackQuestionAttributes> questionList = questions.get(question.feedbackSessionName);
      if (questionList == null) {
        questionList = new ArrayList<FeedbackQuestionAttributes>();
        questions.put(question.feedbackSessionName, questionList);
      }
      if (!isAdded.contains(question.getId())) {
        isAdded.add(question.getId());
        questionList.add(question);
      }

      // get related session from results
      FeedbackSessionAttributes session =
          JsonUtils.fromJson(
              doc.getOnlyField(Const.SearchDocumentField.FEEDBACK_SESSION_ATTRIBUTE).getText(),
              FeedbackSessionAttributes.class);
      if (fsLogic.getFeedbackSession(session.getSessionName(), session.getCourseId()) == null) {
        frcLogic.deleteDocument(comment);
        continue;
      }
      if (!isAdded.contains(session.getFeedbackSessionName())) {
        isAdded.add(session.getFeedbackSessionName());
        sessions.put(session.getSessionName(), session);
      }

      // get giver and recipient names
      String responseGiverName =
          extractContentFromQuotedString(
              doc.getOnlyField(Const.SearchDocumentField.FEEDBACK_RESPONSE_GIVER_NAME).getText());
      responseGiverTable.put(response.getId(), getFilteredGiverName(response, responseGiverName));

      String responseRecipientName =
          extractContentFromQuotedString(
              doc.getOnlyField(Const.SearchDocumentField.FEEDBACK_RESPONSE_RECEIVER_NAME)
                  .getText());
      responseRecipientTable.put(
          response.getId(), getFilteredRecipientName(response, responseRecipientName));

      String commentGiverName =
          extractContentFromQuotedString(
              doc.getOnlyField(Const.SearchDocumentField.FEEDBACK_RESPONSE_COMMENT_GIVER_NAME)
                  .getText());
      commentGiverTable.put(
          comment.getId().toString(),
          getFilteredCommentGiverName(response, comment, commentGiverName));
      numberOfCommentFound++;
    }

    for (List<FeedbackQuestionAttributes> questions : this.questions.values()) {
      Collections.sort(questions);
    }

    for (List<FeedbackResponseAttributes> responses : this.responses.values()) {
      FeedbackResponseAttributes.sortFeedbackResponses(responses);
    }

    for (List<FeedbackResponseCommentAttributes> responseComments : this.comments.values()) {
      FeedbackResponseCommentAttributes.sortFeedbackResponseCommentsByCreationTime(
          responseComments);
    }

    return this;
  }