code: @Override
      public final void printClientConfig(final JSONWriter json, final Template template) throws JSONException {
          try {
              Set<Class> printed = new HashSet<>();
              final Value exampleValue = createValue(template);
              json.key(JSON_NAME).value(this.configName);
              json.key(JSON_ATTRIBUTE_TYPE).value(getValueType().getSimpleName());
              final Class<?> valueType = exampleValue.getClass();
  
              json.key(JSON_CLIENT_PARAMS);
              json.object();
              printClientConfigForType(json, exampleValue, valueType, this.defaults, printed);
              json.endObject();
  
              Optional<JSONObject> clientOptions = getClientInfo();
              clientOptions.ifPresent(jsonObject -> json.key(JSON_CLIENT_INFO).value(jsonObject));
          } catch (Throwable e) {
              // Note: If this test fails and you just added a new attribute, make
              // sure to set defaults in AbstractMapfishSpringTest.configureAttributeForTesting
              throw new Error("Error printing the clientConfig of: " + getValueType().getName(), e);
          }
      }
docs: Uses reflection on the object created by {@link #createValue(Template)} to
  create the options.
  <p></p>
  The public final fields are written as the field name as the key and the value as the value.
  <p></p>
  The public (non-final) mandatory fields are written as part of clientParams and are written with the
  field name as the key and the field type as the value.
  <p></p>
  The public (non-final) {@link HasDefaultValue} fields are written as part of
  clientOptions and are written with the field name as the key and an object as a value with a type
  property with the type and a default property containing the default value.
  
  @param json the json writer to write to
  @param template the template that this attribute is part of
  @throws JSONException