public class Utils {
	
	private static final PublicHolidays publicHolidays;
	static {
		publicHolidays=new PublicHolidays();
	}

	public static boolean isWeekend(int day, int startWeekDay) {
		int sundayBeginningDayNumber=(day-1+startWeekDay-1)%7;
		if(sundayBeginningDayNumber==0 || sundayBeginningDayNumber==6) {
			return true;
		} else {
			return false;
		}
	}
	
	public static boolean isWorkday(int day, int startWeekDay) {
		return !isWeekend(day, startWeekDay);
	}	
	
	public static boolean isPublicHolidays(int year, int month, int day) {
		return publicHolidays.isHolidays(year, month, day);		
	}
	
	public static int getWeekdayNumber(int day, int startWeekDay) {
		return (day-1+startWeekDay-1)%7;
	}
	
	public static String getDayLetter(int day, int startWeekDay, RiaMessages i18n) {
		switch(getWeekdayNumber(day, startWeekDay)) {
		case 0:
			return i18n.sundayLetter();
		case 1:
			return i18n.mondayLetter();
		case 2:
			return i18n.tuesdayLetter();
		case 3:
			return i18n.wednesdayLetter();
		case 4:
			return i18n.thursdayLetter();
		case 5:
			return i18n.fridayLetter();
		case 6:
			return i18n.saturdayLetter();
		}
		return "";
	}
	
	public static void shuffleArray(Employee[] array) {
		Random random = new Random();
		for (int i = array.length - 1; i > 0; i--) {
			int index = random.nextInt(i + 1);
			Employee a = array[index];
			array[index] = array[i];
			array[i] = a;
		}
	}	
} public interface ShiftSolverConstants {

	String CODENAME="ShiftSolver";
	
	boolean DEBUG=false;
	
	// roles
	int ROOT=0;
	int ROLE_EDITOR=1;
	int ROLE_SPORTAK=2;
	int ROLE_STAFFER=3;
	int ROLE_ANYBODY = 4;
	
	// types
	int NO_SHIFT = 0;	
	int SHIFT_MORNING=1;
	int SHIFT_MORNING_6=2;
	int SHIFT_MORNING_7=4;
	int SHIFT_MORNING_8=8;
	int SHIFT_AFTERNOON=16;
	int SHIFT_NIGHT=32;
	
	// URLs                                                        
    String BASE_URL = "http://shiftsolver.appspot.com";
    String GRAVATAR_BASE_URL = "http://www.gravatar.com/avatar/";
	
	// HTML
	String CONTAINER_TITLE_LOGO="solverTitleLogo";
	String CONTAINER_STATUS_LINE="solverStatusLineContainer";
	String CONTAINER_MENU="solverLeftMenuContainer";
	String CONTAINER_PAGE_TITLE= "pageTitleContainer";
	String CONTAINER_HOME="solverHomeContainer";	
	String CONTAINER_SETTINGS="solverSettingsContainer";	
	String CONTAINER_EMPLOYEES_TABLE="solverEmployeesTableContainer";
	String CONTAINER_EMPLOYEE_EDITOR="solverEmployeeEditorContainer";
	String CONTAINER_DLOUHAN_TABLE="solverDlouhanTableContainer";
	String CONTAINER_DLOUHAN_EDITOR="solverDlouhanEditorContainer";
	String CONTAINER_SOLUTION_TABLE="solverSolutionTableContainer";
	String CONTAINER_SOLUTION_VIEW="solverSolutionViewContainer";	
	String CONTAINER_SOLVER_PROGRESS="solverProgressContainer";	
	String CONTAINER_SOLVER_NO_SOLUTION="solverNoSolution";	
	String CONTAINER_PRINT_BUTTON="solverPrintButton";
	
	// CSS
	String CSS_NOTHING_STYLE="s2-statusNothing";
	String CSS_HELP_STYLE="s2-statusHelp";
	String CSS_INFO_STYLE="s2-statusInfo";
	String CSS_PROGRESS_STYLE="s2-statusProgress";
	String CSS_ERROR_STYLE="s2-statusError";
	
	String CSS_SHIFT_FREE="s2-shiftFree";
	String CSS_SHIFT_NA="s2-shiftNa";
	String CSS_SHIFT_VACATIONS="s2-shiftVacations";
	String CSS_SHIFT_MORNING="s2-shiftMorning";
	String CSS_SHIFT_AFTERNOON="s2-shiftAfternoon";
	String CSS_SHIFT_NIGHT="s2-shiftNight";
} public class ShiftSolverLogger implements ShiftSolverConstants {

	private static PrintStream out;
	
	static {
		// nop
		out=null;		
	}
	
	public static void init(PrintStream printStream) {
		out=printStream;
	}
	
	public static void debug(String message) {
		if(DEBUG) {
			GWT.log(message);			
		}
		if(out!=null) out.println(message);
	}

	public static boolean isJUnitMode() {
		return out!=null;
	}
} public class DayPreference implements Serializable {
	private static final long serialVersionUID = 1302160963964962116L;

	private String key;
	
	private int year;
	private int month;
	private int day;
	
	// three state preferences: NO, I CANNOT MAKE IT (bool) / YES PLEASE, I WANT IT (bool) / I DONT CARE (nothing)
	
	private boolean isHoliDay;
	
	private boolean noDay;
	private boolean noMorning6; // 6 AM or entire day
	private boolean noMorning7;
	private boolean noMorning8;
	private boolean noAfternoon;
	private boolean noNight;

	private boolean yesDay;
	private boolean yesMorning6;
	private boolean yesMorning7;
	private boolean yesMorning8;
	private boolean yesAfternoon;
	private boolean yesNight;
	
	public DayPreference() {		
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		this.month = month;
	}

	public int getDay() {
		return day;
	}

	public void setDay(int day) {
		this.day = day;
	}

	public boolean isNoDay() {
		return noDay;
	}

	public void setNoDay(boolean noDay) {
		this.noDay = noDay;
	}

	public boolean isNoMorning6() {
		return noMorning6 || noDay;
	}

	public void setNoMorning6(boolean noMorning6) {
		this.noMorning6 = noMorning6;
	}

	public boolean isNoMorning7() {
		return noMorning7 || noDay;
	}

	public void setNoMorning7(boolean noMorning7) {
		this.noMorning7 = noMorning7;
	}

	public boolean isNoMorning8() {
		return noMorning8 || noDay;
	}

	public void setNoMorning8(boolean noMorning8) {
		this.noMorning8 = noMorning8;
	}

	public boolean isNoAfternoon() {
		return noAfternoon || noDay;
	}

	public void setNoAfternoon(boolean noAfternoon) {
		this.noAfternoon = noAfternoon;
	}

	public boolean isYesNight() {
		return yesNight;
	}

	public void setYesNight(boolean yesNight) {
		this.yesNight = yesNight;
	}
	
	public boolean isNoNight() {
		return noNight || noDay;
	}

	public void setNoNight(boolean noNight) {
		this.noNight = noNight;
	}

	public boolean isYesDay() {
		return yesDay;
	}

	public void setYesDay(boolean yesDay) {
		this.yesDay = yesDay;
	}

	public boolean isYesMorning6() {
		return yesMorning6;
	}

	public void setYesMorning6(boolean yesMorning6) {
		this.yesMorning6 = yesMorning6;
	}

	public boolean isYesMorning7() {
		return yesMorning7;
	}

	public void setYesMorning7(boolean yesMorning7) {
		this.yesMorning7 = yesMorning7;
	}

	public boolean isYesMorning8() {
		return yesMorning8;
	}

	public void setYesMorning8(boolean yesMorning8) {
		this.yesMorning8 = yesMorning8;
	}

	public boolean isYesAfternoon() {
		return yesAfternoon;
	}

	public void setYesAfternoon(boolean yesAfternoon) {
		this.yesAfternoon = yesAfternoon;
	}

	public boolean isHoliDay() {
		return isHoliDay;
	}

	public void setHoliDay(boolean isHoliDay) {
		this.isHoliDay = isHoliDay;
		if(isHoliDay) setNoDay(true);
	}	
} public class DaySolution implements Serializable  {
	private static final long serialVersionUID = -2908720137028791233L;

	private String key;
	
	int day;
	boolean isWorkday;
	int weekday;
	WorkdayMorningShift workdayMorningShift;
	WorkdayAfternoonShift workdayAfternoonShift;
	WeekendMorningShift weekendMorningShift;
	WeekendAfternoonShift weekendAfternoonShift;
	NightShift nightShift;
		
	public DaySolution() {
	}
	
	public DaySolution(int day, int weekday, boolean isWorkday) {
		this.day=day;
		this.weekday=weekday;
		this.isWorkday=isWorkday;
	}
	
	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public int getDay() {
		return day;
	}

	public void setDay(int day) {
		this.day = day;
	}

	public boolean isWorkday() {
		return isWorkday;
	}

	public void setWorkday(boolean isWorkday) {
		this.isWorkday = isWorkday;
	}

	public WorkdayAfternoonShift getWorkdayAfternoonShift() {
		return workdayAfternoonShift;
	}

	public WorkdayMorningShift getWorkdayMorningShift() {
		return workdayMorningShift;
	}
	
	public void setWorkdayAfternoonShift(WorkdayAfternoonShift workdayAfternoonShift) {
		this.workdayAfternoonShift = workdayAfternoonShift;
	}

	public WeekendMorningShift getWeekendMorningShift() {
		return weekendMorningShift;
	}

	public void setWeekendMorningShift(WeekendMorningShift weekendMorningShift) {
		this.weekendMorningShift = weekendMorningShift;
	}

	public WeekendAfternoonShift getWeekendAfternoonShift() {
		return weekendAfternoonShift;
	}

	public void setWeekendAfternoonShift(WeekendAfternoonShift weekendAfternoonShift) {
		this.weekendAfternoonShift = weekendAfternoonShift;
	}

	public NightShift getNightShift() {
		return nightShift;
	}

	public void setNightShift(NightShift nightShift) {
		this.nightShift = nightShift;
	}

	public boolean isEmployeeAllocatedToday(String employeeKey) {
		return getShiftTypeForEmployee(employeeKey)>0;
	}
	
	public int getShiftTypeForEmployee(String employeeKey) {
		int result=0, shift;
		
		if(nightShift!=null) {
			if((shift=nightShift.isEmployeeAllocated(employeeKey))>0) {
				result=shift|result;
			}
		}
		
		if(isWorkday) {
			if(workdayMorningShift!=null) {
				if((shift=workdayMorningShift.isEmployeeAllocated(employeeKey))>0) {
					result=shift|result;
				}
			}
			if(workdayAfternoonShift!=null) {
				if((shift=workdayAfternoonShift.isEmployeeAllocated(employeeKey))>0) {
					result=shift|result;
				}
			}
		} else {
			if(weekendMorningShift!=null) {
				if((shift=weekendMorningShift.isEmployeeAllocated(employeeKey))>0) {
					result=shift|result;
				}
			}
			if(weekendAfternoonShift!=null) {
				if((shift=weekendAfternoonShift.isEmployeeAllocated(employeeKey))>0) {
					result=shift|result;
				}
			}
		}
		return result;
	}

	public void setWorkdayMorningShift(WorkdayMorningShift workdayMorningShift) {
		this.workdayMorningShift=workdayMorningShift;
	}

	public int getWeekday() {
		return weekday;
	}
} public class Employee implements Serializable  {
	private static final long serialVersionUID = 3788399085593900403L;

	private String key;
	private long modified;
	private String modifiedPretty;
	private String firstname;
	private String familyname;
	private String email;
	private int birthdayYear;
	private int birthdayMonth;
	private int birthdayDay;
	private boolean female;
	private boolean editor;
	private boolean sportak;
	private boolean mortak;
	private boolean fulltime;
		
	public Employee() {		
	}
	
	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}
	
	public long getModified() {
		return modified;
	}

	public void setModified(long modified) {
		this.modified = modified;
	}

	public String getModifiedPretty() {
		return modifiedPretty;
	}

	public void setModifiedPretty(String modifiedPretty) {
		this.modifiedPretty = modifiedPretty;
	}

	public String getFirstname() {
		return firstname;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}

	public String getFamilyname() {
		return familyname;
	}

	public void setFamilyname(String familyname) {
		this.familyname = familyname;
	}

	public String getFullName() {
		return (getFirstname()!=null?getFirstname():"")+" "+(getFamilyname()!=null?getFamilyname():"");
	}
	
	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public boolean isFemale() {
		return female;
	}
	
	public void setFemale(boolean female) {
		this.female = female;
	}
	
	public boolean isEditor() {
		return editor;
	}
	
	public void setEditor(boolean editor) {
		this.editor = editor;
	}
	
	public boolean isSportak() {
		return sportak;
	}
	
	public void setSportak(boolean sportak) {
		this.sportak = sportak;
	}
	
	public boolean isFulltime() {
		return fulltime;
	}
	
	public void setFulltime(boolean fulltime) {
		this.fulltime = fulltime;
	}

	public int getBirthdayYear() {
		return birthdayYear;
	}

	public void setBirthdayYear(int birthdayYear) {
		this.birthdayYear = birthdayYear;
	}

	public int getBirthdayMonth() {
		return birthdayMonth;
	}

	public void setBirthdayMonth(int birthdayMonth) {
		this.birthdayMonth = birthdayMonth;
	}

	public int getBirthdayDay() {
		return birthdayDay;
	}

	public void setBirthdayDay(int birthdayDay) {
		this.birthdayDay = birthdayDay;
	}

	public boolean isMortak() {
		return mortak;
	}

	public void setMortak(boolean mortak) {
		this.mortak = mortak;
	}
} public class EmployeePreferences implements Serializable  {
	private static final long serialVersionUID = 7779646494294778098L;

	private String key;
	
	private int shiftsLimit;
	private List<DayPreference> preferences;
	
	public EmployeePreferences() {
		preferences=new ArrayList<DayPreference>();
	}

	public EmployeePreferences(int shiftsLimit) {
		this();
		this.shiftsLimit=shiftsLimit;
	}
	
	public void addPreference(DayPreference preference) {
		preferences.add(preference);
	}
	
	public List<DayPreference> getPreferences() {
		return preferences;
	}

	public void setPreferences(List<DayPreference> preferences) {
		this.preferences = preferences;
	}

	public int getShiftsLimit() {
		return shiftsLimit;
	}

	public void setShiftsLimit(int shiftsLimit) {
		this.shiftsLimit = shiftsLimit;
	}
	
	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public DayPreference getPreferencesForDay(int day) {
		for(DayPreference dayPreference:preferences) {
			if(day == dayPreference.getDay()) {
				return dayPreference;
			}
		}
		return null;
	}
} public class Holder<T> implements Serializable {
	private static final long serialVersionUID = -1312032921161292850L;

	private T v;
	
	public Holder() {
	}
	
	public Holder(T v) {
		this.v=v;
	}

	public T get() {
		return v;
	}

	public void set(T v) {
		this.v = v;
	}
} public class Job implements Serializable {
	private static final long serialVersionUID = 5771885426390872948L;
	
	public String key;
	public int shiftsLimit;
	public int shifts;
	
	public Job() {		
	}

	public Job(int shifts, int shiftsLimit) {
		this.shifts=shifts;
		this.shiftsLimit=shiftsLimit;
	}

	public int getShiftsLimit() {
		return shiftsLimit;
	}

	public void setShiftsLimit(int shiftsLimit) {
		this.shiftsLimit = shiftsLimit;
	}

	public int getShifts() {
		return shifts;
	}

	public void setShifts(int shifts) {
		this.shifts = shifts;
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}
} public class PeriodPreferences implements Serializable  {
	private static final long serialVersionUID = 8785936718601939671L;

	private String key;
	private long modified;
	private String modifiedPretty;
	private int startWeekDay;
	private int monthDays;
	private int monthWorkDays;
	private int year;
	private int month;
	private Map<String,EmployeePreferences> employeeToPreferences;
	private String lastMonthEditor;
	
	public PeriodPreferences() {		
	}
	
	public PeriodPreferences(int year, int month) {
		employeeToPreferences=new HashMap<String,EmployeePreferences>();
		this.year=year;
		this.month=month;
	}
	
	public String getKey() {
		return key;
	}
	
	public void setKey(String key) {
		this.key = key;
	}
	
	public long getModified() {
		return modified;
	}

	public void setModified(long modified) {
		this.modified = modified;
	}

	public String getModifiedPretty() {
		return modifiedPretty;
	}

	public void setModifiedPretty(String modifiedPretty) {
		this.modifiedPretty = modifiedPretty;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		this.month = month;
	}
	
	public int getStartWeekDay() {
		return startWeekDay;
	}

	public void setStartWeekDay(int startWeekDay) {
		this.startWeekDay = startWeekDay;
	}
	
	public int getMonthDays() {
		return monthDays;
	}

	public void setMonthDays(int monthDays) {
		this.monthDays = monthDays;
	}

	public void addEmployeePreferences(String employeeKey, EmployeePreferences preferences) {
		employeeToPreferences.put(employeeKey, preferences);
	}
	
	public Map<String, EmployeePreferences> getEmployeeToPreferences() {
		return employeeToPreferences;
	}

	public void setEmployeeToPreferences(Map<String, EmployeePreferences> employeeToPreferences) {
		this.employeeToPreferences = employeeToPreferences;
	}

	public int getMonthWorkDays() {
		return monthWorkDays;
	}

	public void setMonthWorkDays(int monthWorkDays) {
		this.monthWorkDays = monthWorkDays;
	}

	public String getLastMonthEditor() {
		return lastMonthEditor;
	}

	public void setLastMonthEditor(String lastMonthEditor) {
		this.lastMonthEditor = lastMonthEditor;
	}
} public class PeriodSolution implements Serializable {
	private static final long serialVersionUID = 7586400671035292788L;

	private String key;
	private long modified;
	private String modifiedPretty;
	private String periodPreferencesKey;
	private int year;
	private int month;
	private Map<String, Job> employeeJobs;
	private List<DaySolution> days;
	
	public PeriodSolution() {
		this.days=new ArrayList<DaySolution>();
		this.employeeJobs=new HashMap<String,Job>();
	}
	
	public PeriodSolution(int year, int month) {
		this();
		this.year=year;
		this.month=month;
	}
	
	public long getModified() {
		return modified;
	}

	public void setModified(long modified) {
		this.modified = modified;
	}

	public String getModifiedPretty() {
		return modifiedPretty;
	}

	public void setModifiedPretty(String modifiedPretty) {
		this.modifiedPretty = modifiedPretty;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		this.month = month;
	}

	public List<DaySolution> getDays() {
		return days;
	}

	public void setDays(List<DaySolution> days) {
		this.days = days;
	}
	
	public void addDaySolution(DaySolution daySolution) {
		this.days.add(daySolution);
	}
	
	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public String getPeriodPreferencesKey() {
		return periodPreferencesKey;
	}

	public void setPeriodPreferencesKey(String periodPreferencesKey) {
		this.periodPreferencesKey = periodPreferencesKey;
	}

	public Map<String, Job> getEmployeeJobs() {
		return employeeJobs;
	}

	public void setEmployeeJobs(Map<String, Job> employeeJobs) {
		this.employeeJobs = employeeJobs;
	}

	public void addEmployeeJob(String employeeKey, Job job) {
		this.employeeJobs.put(employeeKey, job);
	}

	// TODO inefficient iterations > create map
	public DaySolution getSolutionForDay(int i) {
		if(days!=null && days.size()>=i) {
			for(DaySolution ds:days) {
				if(ds.getDay()==i) {
					return ds;
				}
			}
		}
		return null;
	}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.mindforger.shiftsolver.client.Utils;
import com.mindforger.shiftsolver.shared.ShiftSolverConstants;
import com.mindforger.shiftsolver.shared.ShiftSolverLogger;
import com.mindforger.shiftsolver.shared.model.DayPreference;
import com.mindforger.shiftsolver.shared.model.DaySolution;
import com.mindforger.shiftsolver.shared.model.Employee;
import com.mindforger.shiftsolver.shared.model.EmployeePreferences;
import com.mindforger.shiftsolver.shared.model.Holder;
import com.mindforger.shiftsolver.shared.model.Job;
import com.mindforger.shiftsolver.shared.model.PeriodPreferences;
import com.mindforger.shiftsolver.shared.model.PeriodSolution;
	}

	public boolean hasCapacity(int day, int shiftType) {
		return hasCapacity(day, shiftType, 1, false);
	}
	
	public boolean hasCapacity(int day, int shiftType, int capacityNeeded, boolean editorWeekendContinuity) {
		if(employee.isFulltime() && nights>=2 && shiftType==ShiftSolverConstants.SHIFT_NIGHT) {
			return false;
		}
		
		if(shiftsOnDays.size()>0) {
			int yesterday=day-1;
			int lastDayOnDuty=shiftsOnDays.get(shiftsOnDays.size()-1);
			int lastDayType=shiftTypesOnDays.get(shiftTypesOnDays.size()-1);
			if(lastDayOnDuty==yesterday) {				
				if(enforceNightToAfternoon) {
					if(lastDayType == ShiftSolverConstants.SHIFT_NIGHT) {
						if(shiftType == ShiftSolverConstants.SHIFT_AFTERNOON || shiftType == ShiftSolverConstants.SHIFT_NIGHT) {
							// OK
						} else {
							return false;
						}
					}
				}
				if(enforceAfternoonTo8am) {
					if(lastDayType == ShiftSolverConstants.SHIFT_AFTERNOON) {
						if(shiftType == ShiftSolverConstants.SHIFT_MORNING ||
						   shiftType == ShiftSolverConstants.SHIFT_MORNING_8 || 
						   shiftType == ShiftSolverConstants.SHIFT_AFTERNOON || 
						   shiftType == ShiftSolverConstants.SHIFT_NIGHT) {
						// OK
						} else {
							if(editorWeekendContinuity) {
								// OK
							} else {
								return false;							
							}
						}
					}
				}
			}
			
			// RULE: at most 1 shift/day
			if(lastDayOnDuty!=day || editorWeekendContinuity) {
				// RULE: at most 5 consecutive days at work (last 4 days connected to today)
				if(hadShiftsLast5Days(day)) {
					return false;
				}
				return hasCapacity(capacityNeeded);
			} else {
				return false;
			}
		} else {
			return hasCapacity(capacityNeeded);
		}
	}

	public boolean hadShiftYesterday(int day) {
		int count=0;
		if(shiftsOnDays.size()>0) {
			for(Integer i:shiftsOnDays) {
				if(day-1==i) {
					count++;
				}
			}
		}		
		return count>0;		
	}
	
	public boolean hadShiftToday(int day) {
		int count=0;
		if(shiftsOnDays.size()>0) {
			for(Integer i:shiftsOnDays) {
				if(day==i) {
					count++;
				}
			}
		}		
		return count>0;
	}

	public boolean hadMoreThanOneShiftToday(int day) {
		int count=0;
		if(shiftsOnDays.size()>0) {
			for(Integer i:shiftsOnDays) {
				if(day==i) {
					count++;
				}
			}
		}		
		return count>1;
	}
	
	public boolean hadShiftsLast5Days(int day) {
		if(shiftsOnDays.size()>=5) {
			int lastIndex=shiftsOnDays.size()-1;
			int lastDay=shiftsOnDays.get(lastIndex);
			if(lastDay==(day-1)
				 &&
			   shiftsOnDays.get(lastIndex-1)==(lastDay-1)
				 &&
			   shiftsOnDays.get(lastIndex-2)==(lastDay-2)
				 &&
			   shiftsOnDays.get(lastIndex-3)==(lastDay-3) 
				 &&
			   shiftsOnDays.get(lastIndex-4)==(lastDay-4)) 
			{
				return true;
			}
		}
		return false;
	}

	private boolean hasCapacity(int capacityNeeded) {
		return shiftsToGet>0 && shiftsToGet>=(shifts+capacityNeeded);
	}

	public static List<EmployeeAllocation> calculateEmployeeAllocationsAndFixJobs(
			PeriodPreferences preferences,
			PeriodSolution solution,