public Solution readSolution() throws IOException, JDOMException {
// Note: javax.xml is terrible. JDom is much much easier.
Element schedulingPeriodElement = document.getRootElement();
assertElementName(schedulingPeriodElement, "SchedulingPeriod");
NurseRoster nurseRoster = new NurseRoster();
nurseRoster.setId(0L);
nurseRoster.setCode(schedulingPeriodElement.getAttribute("ID").getValue());
generateShiftDateList(nurseRoster,
schedulingPeriodElement.getChild("StartDate"),
schedulingPeriodElement.getChild("EndDate"));
readSkillList(nurseRoster, schedulingPeriodElement.getChild("Skills"));
readShiftTypeList(nurseRoster, schedulingPeriodElement.getChild("ShiftTypes"));
generateShiftList(nurseRoster);
readPatternList(nurseRoster, schedulingPeriodElement.getChild("Patterns"));
readContractList(nurseRoster, schedulingPeriodElement.getChild("Contracts"));
readEmployeeList(nurseRoster, schedulingPeriodElement.getChild("Employees"));
readRequiredEmployeeSizes(nurseRoster, schedulingPeriodElement.getChild("CoverRequirements"));
readDayOffRequestList(nurseRoster, schedulingPeriodElement.getChild("DayOffRequests"));
readDayOnRequestList(nurseRoster, schedulingPeriodElement.getChild("DayOnRequests"));
readShiftOffRequestList(nurseRoster, schedulingPeriodElement.getChild("ShiftOffRequests"));
readShiftOnRequestList(nurseRoster, schedulingPeriodElement.getChild("ShiftOnRequests"));
createShiftAssignmentList(nurseRoster);
logger.info("NurseRoster {} with {} skills, {} shiftTypes, {} patterns, {} contracts, {} employees," +
" {} shiftDates, {} shifts and {} requests.",
new Object[]{nurseRoster.getCode(),
nurseRoster.getSkillList().size(),
nurseRoster.getShiftTypeList().size(),
nurseRoster.getPatternList().size(),
nurseRoster.getContractList().size(),
nurseRoster.getEmployeeList().size(),
nurseRoster.getShiftDateList().size(),
nurseRoster.getShiftList().size(),
nurseRoster.getDayOffRequestList().size() + nurseRoster.getDayOnRequestList().size()
+ nurseRoster.getShiftOffRequestList().size() + nurseRoster.getShiftOnRequestList().size()
});
BigInteger possibleSolutionSize = BigInteger.valueOf(nurseRoster.getEmployeeList().size()).pow(
nurseRoster.getShiftList().size());
String flooredPossibleSolutionSize = "10^" + (possibleSolutionSize.toString().length() - 1);
logger.info("NurseRoster with flooredPossibleSolutionSize ({}) and possibleSolutionSize ({}).",
flooredPossibleSolutionSize, possibleSolutionSize);
return nurseRoster;
}