class QuotaServer {

  public static <T extends Enum<T>> QuotaServer<T> createFromConfiguration(
      String quotaPrefix, Class<T> enumClass) {
    checkState(Configuration.isInitialized(), "configuration not initialized yet");
    checkNotNull(enumClass);
    T[] enumValues = enumClass.getEnumConstants();
    checkNotNull(enumValues, "class " + enumClass + " is not an enum class");
    double defaultQps =
        Configuration.getValue(
                String.format(CONFIG_QUOTA_SERVER_DEFAULT_QPS_FORMAT, quotaPrefix),
                DEFAULT_QPS,
                Configuration.DOUBLE_PARSER)
            .get();
    QuotaServer.Builder<T, QuotaServer<T>> builder =
        new QuotaServer.Builder<T, QuotaServer<T>>(enumClass);
    for (T operation : enumValues) {
      String configKey = String.format(CONFIG_QUOTA_SERVER_ENUM_KEY_FORMAT, quotaPrefix, operation);
      ConfigValue<Double> qps =
          Configuration.getValue(configKey, defaultQps, Configuration.DOUBLE_PARSER);
      if (qps.get() <= 0) {
        throw new InvalidConfigurationException(
            "QPS for " + configKey + " can not be 0 or negative. Configured as " + qps.get());
      }
      builder.addQuota(operation, qps.get());
    }
    return builder.build();
  }

  private  QuotaServer(Builder<T, ? extends QuotaServer<T>> builder);

}