private <T> void checkParameterValidity(
            String paramName,
            T paramValue,
            Class<T> paramType
    ) {
        //double unbounded
        if (Arrays.binarySearch(DOUBLE_UNBOUNDED, paramName) >= 0) {
            if (!paramType.equals(Double.class)) {
                throw new IllegalArgumentException(
                        "Invalid value this parameter, it must be an "
                                + Double.class.getCanonicalName());
            }
        } else if (Arrays.binarySearch(POSITIVE_DOUBLE, paramName) >= 0) {
            if (!paramType.equals(Double.class)) {
                throw new IllegalArgumentException(
                        "Invalid value this parameter, it must be an "
                                + Double.class.getCanonicalName());
            } else {
                Double value = (Double) paramValue;
                require(0.0 <= value,
                        "Invalid value for " + paramName + " : '" + paramValue + "'");
            }
            //probability
        } else if (Arrays.binarySearch(POSITIVE_INTEGER, paramName) >= 0) {
            if (!paramType.equals(Integer.class)) {
                throw new IllegalArgumentException(
                        "Invalid value this parameter, it must be a "
                                + Integer.class.getCanonicalName() + " class");
            } else {
                Integer value = (Integer) paramValue;
                require(0 <= value,
                        "Invalid value for " + paramName + " : '" + paramValue + "'");
            }
        } else if (Arrays.binarySearch(BOOLEAN, paramName) >= 0) {
            if (!paramType.equals(Boolean.class)) {
                throw new IllegalArgumentException(
                        "Invalid value this parameter, it must be a "
                                + Boolean.class.getCanonicalName() + " class");
            }
        } else {
            throw new IllegalArgumentException("Invalid parameter name : " + paramName);
        }
    }