public static BorrowedMaterial borrowedMaterialReceivedInPast(
		Student student, TeachingMaterial teachingMaterial) {
	BorrowedMaterial borrowedMaterial = new BorrowedMaterial.Builder(
			student, teachingMaterial, todayPlusDays(-25)).received(true)
			.build();
	return borrowedMaterial;
} public static Student studentInGrade(int grade) {
	Grade gradeEntity = new Grade.Builder(grade, "").build();
	gradeEntity.setId(grade);
	Student student = new Student.Builder(rInt(), rStr(), rStr(), null,
			gradeEntity).build();
	return student;
} public static TeachingMaterial teachingMaterialInFirstTermOfGrade(int grade) {
	TeachingMaterial teachingMaterial = new TeachingMaterial.Builder(
			category(), rStr(), null, todayPlusDays(-20)).fromGrade(grade)
			.fromTerm(Term.FIRST).toGrade(grade).toTerm(Term.FIRST).build();
	return teachingMaterial;
} public static TeachingMaterial teachingMaterialInSecondTermOfGrade(int grade) {
	TeachingMaterial teachingMaterial = new TeachingMaterial.Builder(
			category(), rStr(), null, todayPlusDays(-20)).fromGrade(grade)
			.fromTerm(Term.SECOND).toGrade(grade).toTerm(Term.SECOND)
			.build();
	return teachingMaterial;
} public static Date todayPlusDays(int days) {
	Calendar calendar = Calendar.getInstance();
	calendar.setTime(new Date());
	calendar.add(Calendar.DATE, days);
	return calendar.getTime();
} public class GuiceJUnitRunner extends BlockJUnit4ClassRunner {
	private Injector injector;

	/**
	 * Specifies the Guice {@link Module} classes which should be used when
	 * injecting a JUnit test class
	 */
	@Target(ElementType.TYPE)
	@Retention(RetentionPolicy.RUNTIME)
	@Inherited
	public @interface GuiceModules {
		public Class<? extends Module>[] value();
	}

	/**
	 * Initialise {@link Runner}, configure Guice using the {@link Module}s
	 * configured in the {@link GuiceModules} annotation, inject members into
	 * test class
	 * 
	 * @param testClass
	 *            JUnit test class
	 * @throws InitializationError
	 *             thrown when an error occurs during the initialisation of
	 *             Guice modules or injection of members
	 */
	public GuiceJUnitRunner(Class<?> testClass) throws InitializationError {
		super(testClass);
		Set<Class<? extends Module>> moduleClasses = getModuleClassesFor(testClass);
		injector = createInjectorFor(moduleClasses);
	}

	@Override
	public Object createTest() throws Exception {
		Object object = super.createTest();
		injector.injectMembers(object);
		return object;
	}

	/**
	 * Creates a Guice {@link Injector} with a given {@link Set} of
	 * {@link Module} classes
	 * 
	 * @param moduleClasses
	 *            {@link Set} of {@link Module} classes
	 * @return a Guice {@link Injector} with the specified modules
	 * @throws InitializationError
	 *             thrown when an error occurs instantiating the {@link Module}
	 *             class
	 */
	private Injector createInjectorFor(
			Set<Class<? extends Module>> moduleClasses)
			throws InitializationError {
		Set<Module> modules = new HashSet<>();
		for (Class<?> moduleClass : moduleClasses) {
			try {
				modules.add((Module) moduleClass.newInstance());
			} catch (InstantiationException | IllegalAccessException e) {
				throw new InitializationError(e);
			}
		}
		return Guice.createInjector(modules);
	}

	/**
	 * Reads the {@link Module} classes configured in a {@link GuiceModules}
	 * annotation of the test class
	 * 
	 * @param testClass
	 *            class with the {@link GuiceModules} annotation
	 * @return a {@link Set} of Guice {@link Module} classes
	 * @throws InitializationError
	 *             thrown when no {@link GuiceModules} annotation is present
	 */
	private Set<Class<? extends Module>> getModuleClassesFor(Class<?> testClass)
			throws InitializationError {
		GuiceModules annotation = testClass.getAnnotation(GuiceModules.class);
		if (annotation == null)
			throw new InitializationError(
					"Missing @GuiceModules annotation for unit test '"
							+ testClass.getName() + "'");
		return new HashSet<>(Arrays.asList(annotation.value()));
	}
} public class TestModuleWithoutSingletons extends AbstractModule {

	@Override
	protected void configure() {
		install(new JpaPersistModule("testPersistModule"));
		
		bind(new TypeLiteral<DAO<BorrowedMaterial>>() {}).to(new TypeLiteral<DAOImpl<BorrowedMaterial>>() {});
		bind(new TypeLiteral<DAO<Category>>() {}).to(new TypeLiteral<DAOImpl<Category>>() {});
		bind(new TypeLiteral<DAO<Dunning>>() {}).to(new TypeLiteral<DAOImpl<Dunning>>() {});
		bind(new TypeLiteral<DAO<Grade>>() {}).to(new TypeLiteral<DAOImpl<Grade>>() {});
		bind(new TypeLiteral<DAO<Parent>>() {}).to(new TypeLiteral<DAOImpl<Parent>>() {});
		bind(new TypeLiteral<DAO<SchoolYear>>() {}).to(new TypeLiteral<DAOImpl<SchoolYear>>() {});
		bind(new TypeLiteral<DAO<Student>>() {}).to(new TypeLiteral<DAOImpl<Student>>() {});
		bind(new TypeLiteral<DAO<TeachingMaterial>>() {}).to(new TypeLiteral<DAOImpl<TeachingMaterial>>() {});
		bind(new TypeLiteral<DAO<User>>() {}).to(new TypeLiteral<DAOImpl<User>>() {});
		bind(new TypeLiteral<DAO<SettingsEntry>>() {}).to(new TypeLiteral<DAOImpl<SettingsEntry>>() {});
	}
} public interface DAO<EntityType extends Entity> {

	/**
	 * Should an event be fired?
	 */
	public enum FireUpdateEvent { YES, NO }

	/**
	 * Persist the indicated entity to database, don't fire an update event
	 * 
	 * @param entity
	 * @return the primary key
	 */
	EntityType insert(EntityType entity);

	/**
	 * Persist the indicated entity to database, fire an update event when 
	 * {@link FireUpdateEvent.YES} is passed
	 * 
	 * @param entity
	 * @param fireUpdateEvent
	 * @return the primary key
	 */
	EntityType insert(EntityType entity, FireUpdateEvent fireUpdateEvent);
	
	/**
	 * Persist the indicated entity {@link Collection} to database, don't fire an update event
	 * 
	 * @param entity
	 * @return the primary key
	 */
	Collection<EntityType> insert(Collection<EntityType> entities);
	
	/**
	 * Persist the indicated entity {@link Collection} to database, fire an update event when 
	 * {@link FireUpdateEvent.YES} is passed
	 * 
	 * @param entity
	 * @param fireUpdateEvent
	 * @return the primary key
	 */
	Collection<EntityType> insert(Collection<EntityType> entities, FireUpdateEvent fireUpdateEvent);

	/**
	 * Update indicated entity to database, don't fire an update event
	 * 
	 * @param entity
	 */
	void update(EntityType entity);

	/**
	 * Update indicated entity to database, fire an update event when 
	 * {@link FireUpdateEvent.YES} is passed
	 * 
	 * @param entity
	 * @param fireUpdateEvent
	 */
	void update(EntityType entity, FireUpdateEvent fireUpdateEvent);

	/**
	 * Update indicated entity {@link Collection} to database, don't fire an update event
	 * 
	 * @param entity
	 */
	void update(Collection<EntityType> entities);
	
	/**
	 * Update indicated entity {@link Collection} to database, fire an update event when 
	 * {@link FireUpdateEvent.YES} is passed
	 * 
	 * @param entity
	 * @param fireUpdateEvent
	 */
	void update(Collection<EntityType> entities, FireUpdateEvent fireUpdateEvent);
	
	/**
	 * Delete indicated entity from database, don't fire an update event
	 * 
	 * @param entity
	 */
	void delete(EntityType entity);

	/**
	 * Delete indicated entity from database, fire an update event when 
	 * {@link FireUpdateEvent.YES} is passed
	 * 
	 * @param entity
	 * @param fireUpdateEvent
	 */
	void delete(EntityType entity, FireUpdateEvent fireUpdateEvent);

	/**
	 * Delete indicated entity {@link Collection} from database, don't fire an update event
	 * 
	 * @param entity
	 */
	void delete(Collection<EntityType> entities);
	
	/**
	 * Delete indicated entity {@link Collection} from database, fire an update event when 
	 * {@link FireUpdateEvent.YES} is passed
	 * 
	 * @param entity
	 * @param fireUpdateEvent
	 */
	void delete(Collection<EntityType> entities, FireUpdateEvent fireUpdateEvent);
	
	/**
	 * Return the entity class
	 * 
	 * @return entity
	 */
	Class<EntityType> getEntityClass();

	/**
	 * Get the entity manager
	 * 
	 * @return entity
	 */
	EntityManager getEntityManager();

	/**
	 * Retrieve an object using indicated ID
	 * 
	 * @param id
	 * @return entity
	 */
	EntityType find(final Object id);

	/**
	 * Retrieve all entities of the type indicated by the {@link DAO}
	 * 
	 * @return {@link Collection} of entities
	 */
	List<EntityType> findAll();

	/**
	 * Retrieve all entities of the type indicated by the {@link DAO} with the
	 * given {@link Criteria}
	 * 
	 * @param criteriaArray
	 *            - {@link Criterion}s, separated by commas
	 * @return {@link Collection} of entities
	 */
	List<EntityType> findAllWithCriteria(Criterion... criteriaArray);

	/**
	 * Retrieve all entities of the type indicated by the {@link DAO} with the
	 * given {@link Criteria} in the given {@link Order}
	 * 
	 * @param order
	 * 			  - {@link Order}
	 * @param criteriaArray
	 *            - {@link Criterion}s, separated by commas
	 * @return {@link Collection} of entities
	 */
	List<EntityType> findAllWithCriteria(Order order, Criterion... criteriaArray);
	
	/**
	 * Retrieve <b>a single entity</b> of the type indicated by the {@link DAO}
	 * with the given {@link Criteria}. Only use this method when you are sure
	 * there is only one entity retrieved from the database - this just frees
	 * you from the hassle of getting the first and only element out of a
	 * {@link Collection}
	 * 
	 * @param criteriaArray
	 *            - {@link Criterion}s, separated by commas
	 * @return <b>a single entity</b> if the amount of entities
	 *         found in the database is greater than 0, otherwise <i>null</i>
	 */
	EntityType findSingleWithCriteria(Criterion... criteriaArray);
	
	/**
	 * Retrieve <b>a single entity</b> of the type indicated by the {@link DAO}
	 * with the given {@link Criteria} in the given {@link Order}. 
	 * Only use this method when you are sure
	 * there is only one entity retrieved from the database - this just frees
	 * you from the hassle of getting the first and only element out of a
	 * {@link Collection}
	 * 
	 * @param order
	 * 			  - {@link Order}
	 * @param criteriaArray
	 *            - {@link Criterion}s, separated by commas
	 * @return <b>a single entity</b> if the amount of entities
	 *         found in the database is greater than 0, otherwise <i>null</i>
	 */
	EntityType findSingleWithCriteria(Order order, Criterion... criteriaArray);
	
	
	/**
	 * Fire an update event
	 */
	void fireUpdateEvent();
} @Entity
@Table(name="borrowedMaterial")
public class BorrowedMaterial implements de.dhbw.humbuch.model.entity.Entity, Serializable, Comparable<BorrowedMaterial> {
	private static final long serialVersionUID = -7956138735111492455L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	
	@ManyToOne(fetch=FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
	@JoinColumn(name="studentId", referencedColumnName="id")
	private Student student;
	
	@ManyToOne(fetch=FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
	@JoinColumn(name="teachingMaterialId", referencedColumnName="id")
	private TeachingMaterial teachingMaterial;
	
	private Date borrowFrom;
	private Date borrowUntil;
	private Date returnDate;
	private boolean received;
	
	/**
	 * Required by Hibernate.<p>
	 * Use the {@link Builder} instead.
	 * 
	 * @see Builder
	 */
	@Deprecated
	public BorrowedMaterial() {}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public Student getStudent() {
		return student;
	}

	public void setStudent(Student student) {
		this.student = student;
	}

	public TeachingMaterial getTeachingMaterial() {
		return teachingMaterial;
	}

	public void setTeachingMaterial(TeachingMaterial teachingMaterial) {
		this.teachingMaterial = teachingMaterial;
	}

	public Date getBorrowFrom() {
		return borrowFrom;
	}

	public void setBorrowFrom(Date borrowFrom) {
		this.borrowFrom = borrowFrom;
	}

	public Date getBorrowUntil() {
		return borrowUntil;
	}

	public void setBorrowUntil(Date borrowUntil) {
		this.borrowUntil = borrowUntil;
	}

	public Date getReturnDate() {
		return returnDate;
	}

	public void setReturnDate(Date returnDate) {
		this.returnDate = returnDate;
	}

	public boolean isReceived() {
		return received;
	}
	
	public boolean isReturned() {
		return getReturnDate() != null ? true : false;
	}
	
	public void setReceived(boolean received) {
		this.received = received;
	}

	public static class Builder {
		private final Student student;
		private final TeachingMaterial teachingMaterial;
		private final Date borrowFrom;
		
		private Date borrowUntil;
		private Date returnDate;
		private boolean received;
		
		public Builder(Student student, TeachingMaterial teachingMaterial, Date borrowFrom) {
			this.student = student;
			this.teachingMaterial = teachingMaterial;
			this.borrowFrom = borrowFrom;
		}
		
		public Builder borrowUntil(Date borrowUntil) {
			this.borrowUntil = borrowUntil;
			return this;
		}
		
		public Builder returnDate(Date returnDate) {
			this.returnDate = returnDate;
			return this;
		}
		
		public Builder received(boolean received) {
			this.received = received;
			return this;
		}
		
		public BorrowedMaterial build() {
			return new BorrowedMaterial(this);
		}
	}
	
	private BorrowedMaterial(Builder builder) {
		this.student = builder.student;
		this.teachingMaterial = builder.teachingMaterial;
		this.borrowFrom = builder.borrowFrom;
		
		this.borrowUntil = builder.borrowUntil;
		this.returnDate = builder.returnDate;
		this.received = builder.received;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof BorrowedMaterial))
			return false;
		BorrowedMaterial other = (BorrowedMaterial) obj;
		if (getId() != other.getId())
			return false;
		return true;
	}

	@Override
	public int compareTo(BorrowedMaterial o) {
		int compareResult = getTeachingMaterial().compareTo(o.getTeachingMaterial());
		if(compareResult != 0) {
			return compareResult;
		}
		
		return Integer.compare(hashCode(), o.hashCode());
	}
	
} @Entity
@Table(name="schoolYear")
public class SchoolYear implements de.dhbw.humbuch.model.entity.Entity, Serializable, Comparable<SchoolYear> {
	private static final long serialVersionUID = -3752454317452902743L;

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private int id;
	
	private String year;
	private Date fromDate;
	private Date toDate;
	private Date endFirstTerm;
	private Date beginSecondTerm;
	
	/**
	 * Required by Hibernate.<p>
	 * Use the {@link Builder} instead.
	 * 
	 * @see Builder
	 */
	@Deprecated
	public SchoolYear() {}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getYear() {
		return year;
	}

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

	public Date getFromDate() {
		return fromDate;
	}

	public void setFromDate(Date fromDate) {
		this.fromDate = fromDate;
	}

	public Date getToDate() {
		return toDate;
	}

	public void setToDate(Date toDate) {
		this.toDate = toDate;
	}

	public Date getEndFirstTerm() {
		return endFirstTerm;
	}

	public void setEndFirstTerm(Date endFirstTerm) {
		this.endFirstTerm = endFirstTerm;
	}

	public Date getBeginSecondTerm() {
		return beginSecondTerm;
	}

	public void setBeginSecondTerm(Date beginSecondTerm) {
		this.beginSecondTerm = beginSecondTerm;
	}
	
	public Date getEndOf(Term term) {
		return term == Term.FIRST ? getEndFirstTerm() : getToDate();
	}
	
	public Term getRecentlyActiveTerm() {
		return getBeginSecondTerm().after(new Date()) ? Term.FIRST : Term.SECOND;
	}
	
	public boolean isActive() {
		Date today = new Date();
		return getFromDate().before(today) && getToDate().after(today) ? true : false;
	}
	
	public enum Term {
		FIRST("1. Halbjahr"),
		SECOND("2. Halbjahr");
		
		private String value;
		
		private Term(String value) {
			this.value = value;
		}
		
		@Override
		public String toString() {
			return value;
		}
	}
	
	public static class Builder {
		private final String year;
		private final Date fromDate;
		private final Date toDate;
		
		private Date endFirstTerm;
		private Date beginSecondTerm;
		
		public Builder(String year, Date fromDate, Date toDate) {
			this.year = year;
			this.fromDate = fromDate;
			this.toDate = toDate;
		}
		
		public Builder endFirstTerm(Date endFirstTerm) {
			this.endFirstTerm = endFirstTerm;
			return this;
		}
		
		public Builder beginSecondTerm(Date beginSecondTerm) {
			this.beginSecondTerm = beginSecondTerm;
			return this;
		}
		
		public SchoolYear build() {
			return new SchoolYear(this);
		}
	}
	
	private SchoolYear(Builder builder) {
		this.year = builder.year;
		this.fromDate = builder.fromDate;
		this.toDate = builder.toDate;

		this.endFirstTerm = builder.endFirstTerm;
		this.beginSecondTerm = builder.beginSecondTerm;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof SchoolYear))
			return false;
		SchoolYear other = (SchoolYear) obj;
		if (getId() != other.getId())
			return false;
		return true;
	}

	@Override
	public int compareTo(SchoolYear o) {
		int compareResult = getFromDate().compareTo(o.getFromDate());
		if(compareResult != 0) {
			return compareResult;
		}
		
		return Integer.compare(hashCode(), o.hashCode());
	}
	
} public class TestPersistenceInitialiser {
	private final static Logger LOG = LoggerFactory
			.getLogger(TestPersistenceInitialiser.class);

	@Inject
	public TestPersistenceInitialiser(PersistService persistService) {
		try {
			persistService.start();
			LOG.info("persistService started...");
		} catch (IllegalStateException e) {
			LOG.info("persistService already started...");
		}
	}
}
import static de.dhbw.humbuch.test.TestUtils.borrowedMaterialReceivedInPast;
import static de.dhbw.humbuch.test.TestUtils.studentInGrade;
import static de.dhbw.humbuch.test.TestUtils.teachingMaterialInFirstTermOfGrade;
import static de.dhbw.humbuch.test.TestUtils.teachingMaterialInSecondTermOfGrade;
import static de.dhbw.humbuch.test.TestUtils.todayPlusDays;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.EntityManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.inject.Inject;
import com.google.inject.Provider;
import de.dhbw.humbuch.guice.GuiceJUnitRunner;
import de.dhbw.humbuch.guice.GuiceJUnitRunner.GuiceModules;
import de.dhbw.humbuch.guice.TestModuleWithoutSingletons;
import de.dhbw.humbuch.model.DAO;
import de.dhbw.humbuch.model.entity.BorrowedMaterial;
import de.dhbw.humbuch.model.entity.SchoolYear;
import de.dhbw.humbuch.model.entity.TestPersistenceInitialiser;
package de.dhbw.humbuch.viewmodel;







@RunWith(GuiceJUnitRunner.class)
@GuiceModules({ TestModuleWithoutSingletons.class })
public class ReturnViewModelTest extends BaseTest {

	private ReturnViewModel vm;
	private DAO<SchoolYear> daoSchoolYear;