/**
   * Helper method used when we have a JSON Filter to use for potentially filtering out Map entries.
   *
   * @since 2.5
   */
  public void serializeFilteredFields(
      Map<?, ?> value,
      JsonGenerator gen,
      SerializerProvider provider,
      PropertyFilter filter,
      Object suppressableValue) // since 2.5
      throws IOException {
    final Set<String> ignored = _ignoredEntries;
    final MapProperty prop = new MapProperty(_valueTypeSerializer, _property);
    final boolean checkEmpty = (MARKER_FOR_EMPTY == suppressableValue);

    for (Map.Entry<?, ?> entry : value.entrySet()) {
      // First, serialize key; unless ignorable by key
      final Object keyElem = entry.getKey();
      if (ignored != null && ignored.contains(keyElem)) continue;

      JsonSerializer<Object> keySerializer;
      if (keyElem == null) {
        keySerializer = provider.findNullKeySerializer(_keyType, _property);
      } else {
        keySerializer = _keySerializer;
      }
      // or by value; nulls often suppressed
      final Object valueElem = entry.getValue();

      JsonSerializer<Object> valueSer;
      // And then value
      if (valueElem == null) {
        if (_suppressNulls) {
          continue;
        }
        valueSer = provider.getDefaultNullValueSerializer();
      } else {
        valueSer = _valueSerializer;
        if (valueSer == null) {
          valueSer = _findSerializer(provider, valueElem);
        }
        // also may need to skip non-empty values:
        if (checkEmpty) {
          if (valueSer.isEmpty(provider, valueElem)) {
            continue;
          }
        } else if (suppressableValue != null) {
          if (suppressableValue.equals(valueElem)) {
            continue;
          }
        }
      }
      // and with that, ask filter to handle it
      prop.reset(keyElem, keySerializer, valueSer);
      try {
        filter.serializeAsField(valueElem, gen, provider, prop);
      } catch (Exception e) {
        wrapAndThrow(provider, e, value, String.valueOf(keyElem));
      }
    }
  }
 /**
  * Optional - type declaration. This is a String which is used by the templates to instantiate
  * your types. There is typically special handling for different property types
  *
  * @return a string value used as the `dataType` field for model templates, `returnType` for api
  *     templates
  */
 @Override
 public String getTypeDeclaration(Property p) {
   if (p instanceof ArrayProperty) {
     ArrayProperty ap = (ArrayProperty) p;
     Property inner = ap.getItems();
     return "[" + getTypeDeclaration(inner) + "]";
   } else if (p instanceof MapProperty) {
     MapProperty mp = (MapProperty) p;
     Property inner = mp.getAdditionalProperties();
     return "Map.Map String " + getTypeDeclaration(inner);
   }
   return super.getTypeDeclaration(p);
 }
 @Override
 public String toDefaultValue(Property p) {
   if (p instanceof ArrayProperty) {
     final ArrayProperty ap = (ArrayProperty) p;
     final String pattern;
     if (fullJavaUtil) {
       pattern = "new java.util.ArrayList<%s>()";
     } else {
       pattern = "new ArrayList<%s>()";
     }
     return String.format(pattern, getTypeDeclaration(ap.getItems()));
   } else if (p instanceof MapProperty) {
     final MapProperty ap = (MapProperty) p;
     final String pattern;
     if (fullJavaUtil) {
       pattern = "new java.util.HashMap<String, %s>()";
     } else {
       pattern = "new HashMap<String, %s>()";
     }
     return String.format(pattern, getTypeDeclaration(ap.getAdditionalProperties()));
   } else if (p instanceof IntegerProperty) {
     IntegerProperty dp = (IntegerProperty) p;
     if (dp.getDefault() != null) {
       return dp.getDefault().toString();
     }
     return "null";
   } else if (p instanceof LongProperty) {
     LongProperty dp = (LongProperty) p;
     if (dp.getDefault() != null) {
       return dp.getDefault().toString() + "l";
     }
     return "null";
   } else if (p instanceof DoubleProperty) {
     DoubleProperty dp = (DoubleProperty) p;
     if (dp.getDefault() != null) {
       return dp.getDefault().toString() + "d";
     }
     return "null";
   } else if (p instanceof FloatProperty) {
     FloatProperty dp = (FloatProperty) p;
     if (dp.getDefault() != null) {
       return dp.getDefault().toString() + "f";
     }
     return "null";
   } else if (p instanceof BooleanProperty) {
     BooleanProperty bp = (BooleanProperty) p;
     if (bp.getDefault() != null) {
       return bp.getDefault().toString();
     }
     return "null";
   } else if (p instanceof StringProperty) {
     StringProperty sp = (StringProperty) p;
     if (sp.getDefault() != null) {
       String _default = sp.getDefault();
       if (sp.getEnum() == null) {
         return "\"" + escapeText(_default) + "\"";
       } else {
         // convert to enum var name later in postProcessModels
         return _default;
       }
     }
     return "null";
   }
   return super.toDefaultValue(p);
 }