Program: 91928
Project: 91928
Buggy source:
/** 
 * Parses an <strong>optional</strong> metadata elements and close. This include elements like   {@code "SCOPE"},   {@code "ID"} (WKT 2) or {@code "AUTHORITY"} (WKT 1).This WKT 1 element has the following pattern: {@preformat textAUTHORITY["<name>", "<code>"]}<div class="section">Fallback</div> The name is a mandatory property, but some invalid WKT with an empty string exist. In such case, we will use the name of the enclosed datum. Indeed, it is not uncommon to have the same name for a geographic CRS and its geodetic datum.
 * @param parent   The parent element.
 * @param name     The name of the parent object being parsed.
 * @param fallback The fallback to use if {@code name} is empty.
 * @return A properties map with the parent name and the optional authority code.
 * @throws ParseException if an element can not be parsed.
 */
@SuppressWarnings("String_Node_Str") private Map<String,Object> parseMetadataAndClose(final Element parent,final String name,final IdentifiedObject fallback) throws ParseException {
  properties.clear();
  properties.put(IdentifiedObject.NAME_KEY,(name.isEmpty() && fallback != null) ? fallback.getName() : name);
  Element element;
  while ((element=parent.pullElement(OPTIONAL,ID_KEYWORDS)) != null) {
    final String codeSpace=element.pullString("String_Node_Str");
    final String code=element.pullObject("String_Node_Str").toString();
    final Object version=element.pullOptional(Object.class);
    final Element citation=element.pullElement(OPTIONAL,WKTKeywords.Citation);
    final String authority;
    if (citation != null) {
      authority=citation.pullString("String_Node_Str");
      citation.close(ignoredElements);
    }
 else {
      authority=codeSpace;
    }
    final Element uri=element.pullElement(OPTIONAL,WKTKeywords.URI);
    if (uri != null) {
      uri.pullString("String_Node_Str");
      uri.close(ignoredElements);
    }
    element.close(ignoredElements);
    final ImmutableIdentifier id=new ImmutableIdentifier(Citations.fromName(authority),codeSpace,code,(version != null) ? version.toString() : null,null);
    final Object previous=properties.put(IdentifiedObject.IDENTIFIERS_KEY,id);
    if (previous != null) {
      Identifier[] identifiers;
      if (previous instanceof Identifier) {
        identifiers=new Identifier[]{(Identifier)previous,id};
      }
 else {
        identifiers=(Identifier[])previous;
        final int n=identifiers.length;
        identifiers=Arrays.copyOf(identifiers,n + 1);
        identifiers[n]=id;
      }
      properties.put(IdentifiedObject.IDENTIFIERS_KEY,identifiers);
    }
  }
  if (!parent.isEmpty()) {
    element=parent.pullElement(OPTIONAL,WKTKeywords.Scope);
    if (element != null) {
      properties.put(ReferenceSystem.SCOPE_KEY,element.pullString("String_Node_Str"));
      element.close(ignoredElements);
    }
    DefaultExtent extent=null;
    while ((element=parent.pullElement(OPTIONAL,WKTKeywords.Area)) != null) {
      final String area=element.pullString("String_Node_Str");
      element.close(ignoredElements);
      if (extent == null)       extent=new DefaultExtent();
      extent.getGeographicElements().add(new DefaultGeographicDescription(area));
    }
    while ((element=parent.pullElement(OPTIONAL,WKTKeywords.BBox)) != null) {
      final double southBoundLatitude=element.pullDouble("String_Node_Str");
      final double westBoundLongitude=element.pullDouble("String_Node_Str");
      final double northBoundLatitude=element.pullDouble("String_Node_Str");
      final double eastBoundLongitude=element.pullDouble("String_Node_Str");
      element.close(ignoredElements);
      if (extent == null)       extent=new DefaultExtent();
      extent.getGeographicElements().add(new DefaultGeographicBoundingBox(westBoundLongitude,eastBoundLongitude,southBoundLatitude,northBoundLatitude));
    }
    while ((element=parent.pullElement(OPTIONAL,WKTKeywords.VerticalExtent)) != null) {
      final double minimum=element.pullDouble("String_Node_Str");
      final double maximum=element.pullDouble("String_Node_Str");
      Unit<Length> unit=parseScaledUnit(element,WKTKeywords.LengthUnit,SI.METRE);
      element.close(ignoredElements);
      if (unit == null)       unit=SI.METRE;
      if (extent == null)       extent=new DefaultExtent();
      verticalElements=new VerticalInfo(verticalElements,extent,minimum,maximum,unit).resolve(verticalCRS);
    }
    while ((element=parent.pullElement(OPTIONAL,WKTKeywords.TimeExtent)) != null) {
      if (element.peekValue() instanceof String) {
        element.pullString("String_Node_Str");
        element.pullString("String_Node_Str");
        element.close(ignoredElements);
        warning(Errors.formatInternational(Errors.Keys.UnsupportedType_1,"String_Node_Str"),null);
      }
 else {
        final Date startTime=element.pullDate("String_Node_Str");
        final Date endTime=element.pullDate("String_Node_Str");
        element.close(ignoredElements);
        try {
          final DefaultTemporalExtent t=new DefaultTemporalExtent();
          t.setBounds(startTime,endTime);
          if (extent == null)           extent=new DefaultExtent();
          extent.getTemporalElements().add(t);
        }
 catch (        UnsupportedOperationException e) {
          warning(parent,element,e);
        }
      }
    }
    element=parent.pullElement(OPTIONAL,WKTKeywords.Remark);
    if (element != null) {
      properties.put(IdentifiedObject.REMARKS_KEY,element.pullString("String_Node_Str"));
      element.close(ignoredElements);
    }
  }
  parent.close(ignoredElements);
  return properties;
}

Fixed version (ground truth):
/** 
 * Parses an <strong>optional</strong> metadata elements and close. This include elements like   {@code "SCOPE"},   {@code "ID"} (WKT 2) or {@code "AUTHORITY"} (WKT 1).This WKT 1 element has the following pattern: {@preformat wktAUTHORITY["<name>", "<code>"]}<div class="section">Fallback</div> The name is a mandatory property, but some invalid WKT with an empty string exist. In such case, we will use the name of the enclosed datum. Indeed, it is not uncommon to have the same name for a geographic CRS and its geodetic datum.
 * @param parent   The parent element.
 * @param name     The name of the parent object being parsed.
 * @param fallback The fallback to use if {@code name} is empty.
 * @return A properties map with the parent name and the optional authority code.
 * @throws ParseException if an element can not be parsed.
 */
@SuppressWarnings("String_Node_Str") private Map<String,Object> parseMetadataAndClose(final Element parent,final String name,final IdentifiedObject fallback) throws ParseException {
  properties.clear();
  properties.put(IdentifiedObject.NAME_KEY,(name.isEmpty() && fallback != null) ? fallback.getName() : name);
  Element element;
  while ((element=parent.pullElement(OPTIONAL,ID_KEYWORDS)) != null) {
    final String codeSpace=element.pullString("String_Node_Str");
    final String code=element.pullObject("String_Node_Str").toString();
    final Object version=element.pullOptional(Object.class);
    final Element citation=element.pullElement(OPTIONAL,WKTKeywords.Citation);
    final String authority;
    if (citation != null) {
      authority=citation.pullString("String_Node_Str");
      citation.close(ignoredElements);
    }
 else {
      authority=codeSpace;
    }
    final Element uri=element.pullElement(OPTIONAL,WKTKeywords.URI);
    if (uri != null) {
      uri.pullString("String_Node_Str");
      uri.close(ignoredElements);
    }
    element.close(ignoredElements);
    final ImmutableIdentifier id=new ImmutableIdentifier(Citations.fromName(authority),codeSpace,code,(version != null) ? version.toString() : null,null);
    final Object previous=properties.put(IdentifiedObject.IDENTIFIERS_KEY,id);
    if (previous != null) {
      Identifier[] identifiers;
      if (previous instanceof Identifier) {
        identifiers=new Identifier[]{(Identifier)previous,id};
      }
 else {
        identifiers=(Identifier[])previous;
        final int n=identifiers.length;
        identifiers=Arrays.copyOf(identifiers,n + 1);
        identifiers[n]=id;
      }
      properties.put(IdentifiedObject.IDENTIFIERS_KEY,identifiers);
    }
  }
  if (!parent.isEmpty()) {
    element=parent.pullElement(OPTIONAL,WKTKeywords.Scope);
    if (element != null) {
      properties.put(ReferenceSystem.SCOPE_KEY,element.pullString("String_Node_Str"));
      element.close(ignoredElements);
    }
    DefaultExtent extent=null;
    while ((element=parent.pullElement(OPTIONAL,WKTKeywords.Area)) != null) {
      final String area=element.pullString("String_Node_Str");
      element.close(ignoredElements);
      if (extent == null) {
        extent=new DefaultExtent(area,null,null,null);
      }
 else {
        extent.getGeographicElements().add(new DefaultGeographicDescription(area));
      }
    }
    while ((element=parent.pullElement(OPTIONAL,WKTKeywords.BBox)) != null) {
      final double southBoundLatitude=element.pullDouble("String_Node_Str");
      final double westBoundLongitude=element.pullDouble("String_Node_Str");
      final double northBoundLatitude=element.pullDouble("String_Node_Str");
      final double eastBoundLongitude=element.pullDouble("String_Node_Str");
      element.close(ignoredElements);
      if (extent == null)       extent=new DefaultExtent();
      extent.getGeographicElements().add(new DefaultGeographicBoundingBox(westBoundLongitude,eastBoundLongitude,southBoundLatitude,northBoundLatitude));
    }
    while ((element=parent.pullElement(OPTIONAL,WKTKeywords.VerticalExtent)) != null) {
      final double minimum=element.pullDouble("String_Node_Str");
      final double maximum=element.pullDouble("String_Node_Str");
      Unit<Length> unit=parseScaledUnit(element,WKTKeywords.LengthUnit,SI.METRE);
      element.close(ignoredElements);
      if (unit == null)       unit=SI.METRE;
      if (extent == null)       extent=new DefaultExtent();
      verticalElements=new VerticalInfo(verticalElements,extent,minimum,maximum,unit).resolve(verticalCRS);
    }
    while ((element=parent.pullElement(OPTIONAL,WKTKeywords.TimeExtent)) != null) {
      if (element.peekValue() instanceof String) {
        element.pullString("String_Node_Str");
        element.pullString("String_Node_Str");
        element.close(ignoredElements);
        warning(parent,element,Errors.formatInternational(Errors.Keys.UnsupportedType_1,"String_Node_Str"),null);
      }
 else {
        final Date startTime=element.pullDate("String_Node_Str");
        final Date endTime=element.pullDate("String_Node_Str");
        element.close(ignoredElements);
        try {
          final DefaultTemporalExtent t=new DefaultTemporalExtent();
          t.setBounds(startTime,endTime);
          if (extent == null)           extent=new DefaultExtent();
          extent.getTemporalElements().add(t);
        }
 catch (        UnsupportedOperationException e) {
          warning(parent,element,null,e);
        }
      }
    }
    if (extent != null) {
      properties.put(ReferenceSystem.DOMAIN_OF_VALIDITY_KEY,extent);
    }
    element=parent.pullElement(OPTIONAL,WKTKeywords.Remark);
    if (element != null) {
      properties.put(IdentifiedObject.REMARKS_KEY,element.pullString("String_Node_Str"));
      element.close(ignoredElements);
    }
  }
  parent.close(ignoredElements);
  return properties;
}