public static class Product extends Node<ProductStates> {

    private static final Set<ProductStates> PRODUCT_STATES =
        new HashSet<>(Arrays.asList(ProductStates.values()));

    @Override
    public Set<ProductStates> getStates() {
      return PRODUCT_STATES;
    }

    @Override
    public double getPriorProbablility(ProductStates state) {
      return 1.0 / PRODUCT_STATES.size();
    }
  }
  public static class UserProductNegativeVotePotential
      extends Potential<UserStates, ProductStates> {

    private static final double[][] POTENTIAL_VALUE =
        new double[UserStates.values().length][ProductStates.values().length];

    static {
      POTENTIAL_VALUE[UserStates.HONEST.ordinal()][ProductStates.GOOD.ordinal()] = EPSILON;
      POTENTIAL_VALUE[UserStates.HONEST.ordinal()][ProductStates.BAD.ordinal()] = 1 - EPSILON;
      POTENTIAL_VALUE[UserStates.FRAUD.ordinal()][ProductStates.GOOD.ordinal()] = 1 - (2 * EPSILON);
      POTENTIAL_VALUE[UserStates.FRAUD.ordinal()][ProductStates.BAD.ordinal()] = 2 * EPSILON;
    }

    @Override
    public double getValue(UserStates userState, ProductStates productState) {
      return POTENTIAL_VALUE[userState.ordinal()][productState.ordinal()];
    }
  }
 @Override
 public double getValue(UserStates userState, ProductStates productState) {
   return POTENTIAL_VALUE[userState.ordinal()][productState.ordinal()];
 }