class AbstractRecommender implements IRecommender {

	@Override
	public void train(List<OrderItem> orderItems, List<Order> orders) {
		long tic = System.currentTimeMillis();
		totalProducts = new HashSet<>();
		// first create order mapping unorderized
		Map<Long, OrderItemSet> unOrderizeditemSets = new HashMap<>();
		for (OrderItem orderItem : orderItems) {
			if (!unOrderizeditemSets.containsKey(orderItem.getOrderId())) {
				unOrderizeditemSets.put(orderItem.getOrderId(), new OrderItemSet());
				unOrderizeditemSets.get(orderItem.getOrderId()).setOrderId(orderItem.getOrderId());
			}
			unOrderizeditemSets.get(orderItem.getOrderId()).getOrderset().put(orderItem.getProductId(),
					orderItem.getQuantity());
			// see, if we already have our item
			if (!totalProducts.contains(orderItem.getProductId())) {
				// if not known yet -> add
				totalProducts.add(orderItem.getProductId());
			}
		}
		// now map each id with the corresponding order
		Map<Order, OrderItemSet> itemSets = new HashMap<>();
		for (Long orderid : unOrderizeditemSets.keySet()) {
			Order realOrder = findOrder(orders, orderid);
			itemSets.put(realOrder, unOrderizeditemSets.get(orderid));
		}
		userItemSets = new HashMap<>();
		for (Order order : itemSets.keySet()) {
			if (!userItemSets.containsKey(order.getUserId())) {
				userItemSets.put(order.getUserId(), new HashSet<OrderItemSet>());
			}
			itemSets.get(order).setUserId(order.getUserId());
			userItemSets.get(order.getUserId()).add(itemSets.get(order));
		}
		userBuyingMatrix = createUserBuyingMatrix(userItemSets);
		executePreprocessing();
		LOG.info("Training recommender finished. Training took: " + (System.currentTimeMillis() - tic) + "ms.");
		trainingFinished = true;
	}

}