class DirectionApiLogic {

	public BestTransportResult getBestTransportInTime(String origin, String destination,
			ReadableInstant departureTime) {
		EnumMap<TravelMode, DirectionsRoute> routesOfTravelModes = new EnumMap<>(TravelMode.class);
		routesOfTravelModes.put(TravelMode.DRIVING, findBestRoute(
				this.calls.fromToWithDepartureTime(origin, destination, TravelMode.DRIVING, departureTime)));
		routesOfTravelModes.put(TravelMode.TRANSIT, findBestArrivalTime(
				this.calls.fromToWithDepartureTime(origin, destination, TravelMode.TRANSIT, departureTime)));
		routesOfTravelModes.put(TravelMode.BICYCLING, findBestRoute(
				this.calls.fromToWithDepartureTime(origin, destination, TravelMode.BICYCLING, departureTime)));
		long bestTime = Long.MAX_VALUE;
		TravelMode bestTravelMode = null;
		long time;
		if (routesOfTravelModes.get(TravelMode.DRIVING) != null) {
			time = new DateTime(departureTime)
					.plusSeconds(Math.toIntExact(
							routesOfTravelModes.get(TravelMode.DRIVING).legs[0].durationInTraffic.inSeconds))
					.getMillis();
			if (bestTime > time) {
				bestTravelMode = TravelMode.DRIVING;
				bestTime = time;
			}
		}
		if (routesOfTravelModes.get(TravelMode.TRANSIT) != null) {
			time = routesOfTravelModes.get(TravelMode.TRANSIT).legs[0].arrivalTime.getMillis();
			if (bestTime > time) {
				bestTravelMode = TravelMode.TRANSIT;
				bestTime = time;
			}
		}
		if (routesOfTravelModes.get(TravelMode.BICYCLING) != null) {
			time = new DateTime(departureTime)
					.plusSeconds(
							Math.toIntExact(routesOfTravelModes.get(TravelMode.BICYCLING).legs[0].duration.inSeconds))
					.getMillis();
			if (bestTime > time) {
				bestTravelMode = TravelMode.BICYCLING;
			}
		}
		if (bestTravelMode != null) {
			return new BestTransportResult(bestTravelMode, routesOfTravelModes.get(bestTravelMode));
		}
		return null;
	}

}