public void csvTableForClasses(
      PrintWriter out,
      ClassAssignmentProxy classAssignment,
      ExamAssignmentProxy examAssignment,
      ClassAssignmentsReportForm form,
      SessionContext context)
      throws Exception {
    setVisibleColumns(form);

    Collection classes = (Collection) form.getClasses();

    if (isShowTimetable()) {
      boolean hasTimetable = false;
      if (context.hasPermission(Right.ClassAssignments) && classAssignment != null) {
        if (classAssignment instanceof CachedClassAssignmentProxy) {
          ((CachedClassAssignmentProxy) classAssignment).setCache(classes);
        }
        for (Iterator i = classes.iterator(); i.hasNext(); ) {
          Object[] o = (Object[]) i.next();
          Class_ clazz = (Class_) o[0];
          if (classAssignment.getAssignment(clazz) != null) {
            hasTimetable = true;
            break;
          }
        }
      }
      setDisplayTimetable(hasTimetable);
    }
    setUserSettings(context.getUser());

    if (examAssignment != null
        || Exam.hasTimetable(context.getUser().getCurrentAcademicSessionId())) {
      setShowExam(true);
      setShowExamTimetable(true);
      setShowExamName(false);
    }
    setShowInstructor(true);
    if (StudentClassEnrollment.sessionHasEnrollments(
        context.getUser().getCurrentAcademicSessionId())) {
      setShowDemand(true);
    }

    iFile = new CSVFile();

    int ct = 0;
    Iterator it = classes.iterator();
    SubjectArea subjectArea = null;
    String prevLabel = null;
    while (it.hasNext()) {
      Object[] o = (Object[]) it.next();
      Class_ c = (Class_) o[0];
      CourseOffering co = (CourseOffering) o[1];
      if (subjectArea == null
          || !subjectArea.getUniqueId().equals(co.getSubjectArea().getUniqueId())) {
        if (iFile.getLines() != null) iFile.addLine();

        subjectArea = co.getSubjectArea();
        ct = 0;

        iFile.addLine(labelForTable(subjectArea));
        csvBuildTableHeader(context.getUser().getCurrentAcademicSessionId());
      }

      csvBuildClassRow(classAssignment, examAssignment, ++ct, co, c, "", context, prevLabel);
      prevLabel = c.getClassLabel(co);
    }

    save(out);
  }