class TimeFrameImpl implements TimeFrame {

	@Override
	public boolean isDerivableFrom(TimeFrame tf) {
		TimeFrameImpl other = (TimeFrameImpl)tf;
		boolean retVal = false;
		
		PeriodType otherType = other.getPeriod().getPeriodType();
		PeriodType thisType = period.getPeriodType();
        int otherDuration = other.getPeriod().size();
        int thisDuration = getPeriod().size();
        
		if(equals(other)) {
			retVal = true;
		}else{
		    if(((otherType == thisType && otherType != PeriodType.WEEK && (otherDuration == thisDuration || (thisDuration % otherDuration == 0 && other.startDate.isEqual(startDate) && areEqualOrNull(other.endDate, endDate)))) || 
		        (otherType.isLowerThan(thisType) && otherType != PeriodType.WEEK  && otherDuration == 1))) {
		        retVal = true;
            }
    		
		    //Use the highest resolution type to create comparison resolution instances.
		    //(i.e. July being > May is more significant than 4:30 > 2:00)
		    PeriodType resolutionDeterminer = otherType.isLowerThan(thisType) ? thisType : otherType;
    		if(resolutionDeterminer.resolutionInstant(other.startDate).isAfter(resolutionDeterminer.resolutionInstant(startDate))) {
    			retVal = false;
    		}
    		
    		if((other.endDate != null && endDate == null) || ((other.endDate != null && endDate != null) && 
    		    resolutionDeterminer.resolutionInstant(other.endDate).isAfter(resolutionDeterminer.resolutionInstant(endDate)))) {
    		    retVal = false;
    		}
		}
		
		return retVal;
	}

	public  TimeFrameImpl(Period period, DateTime startDate, DateTime endDate);

}