@Override
	public double predict(int userID, int itemID) {

		double prediction = 0;

		if (data.getAverageUserRatings().get(userID) != null) {
			prediction = data.getAverageUserRatings().get(userID);
		}

		ArrayList<Double> similaritiesList = new ArrayList<Double>();
		ArrayList<Double> ratingsList = new ArrayList<Double>();
		ArrayList<Double> averageList = new ArrayList<Double>();

		// If item has not been rated yet, return the user's average rating
		// over all items
		if (itemSimilarities.get(itemID) == null) {
			return prediction;
		}

		for (Map.Entry<Integer, Double> item : itemSimilarities.get(itemID)
				.entrySet()) {

			if (data.getUserItemRatings().get(userID).get(item.getKey()) != null) {
				similaritiesList.add(item.getValue());
				ratingsList.add(data.getUserItemRatings().get(userID)
						.get(item.getKey()));
				averageList.add(data.getAverageItemRatings()
						.get(item.getKey()));

			}
		}

		if (pMetric.equals("weighted")) {
			prediction = Prediction.calculateWeightedSum(similaritiesList,
					ratingsList);
		} else if (pMetric.equals("adjusted")) {
			prediction = Prediction.calculateAdjustedSum(data
					.getAverageItemRatings().get(itemID), averageList,
					ratingsList);
		} else if (pMetric.equals("adjweighted")) {
			prediction = Prediction.calculateAdjustedWeightedSum(data
					.getAverageItemRatings().get(itemID), averageList,
					ratingsList, similaritiesList);
		}

		if (prediction == 0) {
			return data.getAverageItemRatings().get(itemID);
		}

		return prediction;
	}