Source:
<code>private void writeMeetingAssignmentList(List<MeetingAssignment> meetingAssignmentList) { String[] filteredConstraintNames = Arrays.stream(MeetingSchedulingConstraints.values()) .map(MeetingSchedulingConstraints::getConstraintName) <START> .toArray(String[]::new); <END> int mergeStart = -1; int previousMeetingRemainingTimeGrains = 0; boolean mergingPreviousMeetingList = false; for (TimeGrain timeGrain : solution.getTimeGrainList()) { List<MeetingAssignment> timeGrainMeetingAssignmentList = meetingAssignmentList.stream() .filter(meetingAssignment -> meetingAssignment.getStartingTimeGrain() == timeGrain) .collect(toList()); if (timeGrainMeetingAssignmentList.isEmpty() && mergingPreviousMeetingList && previousMeetingRemainingTimeGrains > 0) { previousMeetingRemainingTimeGrains--; nextCell(); } else { if (mergingPreviousMeetingList && mergeStart < currentColumnNumber) { currentSheet.addMergedRegion(new CellRangeAddress(currentRowNumber, currentRowNumber, mergeStart, currentColumnNumber)); } nextMeetingAssignmentListCell(timeGrainMeetingAssignmentList, meetingAssignment -> meetingAssignment.getMeeting().getTopic() + "\n " + meetingAssignment.getMeeting().getSpeakerList(). stream().map(Person::getFullName).collect(joining(", ")), filteredConstraintNames); mergingPreviousMeetingList = !timeGrainMeetingAssignmentList.isEmpty(); mergeStart = currentColumnNumber; previousMeetingRemainingTimeGrains = getLongestDurationInGrains(timeGrainMeetingAssignmentList) - 1; } } if (mergingPreviousMeetingList && mergeStart < currentColumnNumber) { currentSheet.addMergedRegion(new CellRangeAddress(currentRowNumber, currentRowNumber, mergeStart, currentColumnNumber)); } }</code><technical_language>I easier change signature of nextMeetingAssignmentListCell() accept a Collection. Currently, values set is converted array then, nextMeetingAssignmentListCell() method, converted array list. Collection interface - conversion :)</technical_language>

Target:
private void writeMeetingAssignmentList(List<MeetingAssignment> meetingAssignmentList) { String[] filteredConstraintNames = { ROOM_CONFLICT, DONT_GO_IN_OVERTIME, REQUIRED_ATTENDANCE_CONFLICT, REQUIRED_ROOM_CAPACITY, START_AND_END_ON_SAME_DAY, REQUIRED_AND_PREFERRED_ATTENDANCE_CONFLICT, PREFERRED_ATTENDANCE_CONFLICT, DO_ALL_MEETINGS_AS_SOON_AS_POSSIBLE, ONE_TIME_GRAIN_BREAK_BETWEEN_TWO_CONSECUTIVE_MEETINGS, OVERLAPPING_MEETINGS, ASSIGN_LARGER_ROOMS_FIRST, ROOM_STABILITY }; int mergeStart = -1; int previousMeetingRemainingTimeGrains = 0; boolean mergingPreviousMeetingList = false; for (TimeGrain timeGrain : solution.getTimeGrainList()) { List<MeetingAssignment> timeGrainMeetingAssignmentList = meetingAssignmentList.stream() .filter(meetingAssignment -> meetingAssignment.getStartingTimeGrain() == timeGrain) .collect(toList()); if (timeGrainMeetingAssignmentList.isEmpty() && mergingPreviousMeetingList && previousMeetingRemainingTimeGrains > 0) { previousMeetingRemainingTimeGrains--; nextCell(); } else { if (mergingPreviousMeetingList && mergeStart < currentColumnNumber) { currentSheet.addMergedRegion(new CellRangeAddress(currentRowNumber, currentRowNumber, mergeStart, currentColumnNumber)); } nextMeetingAssignmentListCell(timeGrainMeetingAssignmentList, meetingAssignment -> meetingAssignment.getMeeting().getTopic() + "\n " + meetingAssignment.getMeeting().getSpeakerList(). stream().map(Person::getFullName).collect(joining(", ")), Arrays.asList(filteredConstraintNames)); mergingPreviousMeetingList = !timeGrainMeetingAssignmentList.isEmpty(); mergeStart = currentColumnNumber; previousMeetingRemainingTimeGrains = getLongestDurationInGrains(timeGrainMeetingAssignmentList) - 1; } } if (mergingPreviousMeetingList && mergeStart < currentColumnNumber) { currentSheet.addMergedRegion(new CellRangeAddress(currentRowNumber, currentRowNumber, mergeStart, currentColumnNumber)); } }