public static <T> T weightedRandomChoice(Map<T, ? extends Number> map, Random r) {
		double sum = sum(map.values());
		T out = null;
		double selection = sum * r.nextDouble();
		double leftBoundary = 0;
		for (T key : map.keySet()) {
			out = key;
			double rightBoundary = leftBoundary + map.get(key).doubleValue();
			if (selection >= leftBoundary && selection < rightBoundary) {
				return out;
			}
			leftBoundary = rightBoundary;
		}
		return out;
	}