Program: 92029
Project: 92029
Buggy source:
/** 
 * Parses a   {@code "GeodeticCRS"} (WKT 2) element. The syntax is given by<a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#49">WKT 2 specification §8</a>. The legacy WKT 1 specification had two elements for this: {@preformat text}GEOGCS["<name>", <datum>, <prime meridian>, <angular unit>   ,<twin axes>} {,<authority>}] } and  {@preformat text}GEOCCS["<name>", <datum>, <prime meridian>, <linear unit>  ,<axis> ,<axis> ,<axis>} {,<authority>}] }
 * @param mode   {@link #FIRST},   {@link #OPTIONAL} or {@link #MANDATORY}.
 * @param parent The parent element.
 * @param csType The default coordinate system type, or {@code null} if unknown.Should be non-null only when parsing a  {@link GeneralDerivedCRS#getBaseCRS()} component.
 * @return The {@code "GeodeticCRS"} element as a {@link GeographicCRS} or {@link GeocentricCRS} object.
 * @throws ParseException if the {@code "GeodeticCRS"} element can not be parsed.
 * @see org.apache.sis.referencing.crs.DefaultGeographicCRS#formatTo(Formatter)
 * @see org.apache.sis.referencing.crs.DefaultGeocentricCRS#formatTo(Formatter)
 */
private SingleCRS parseGeodeticCRS(final int mode,final Element parent,String csType) throws ParseException {
  final Element element=parent.pullElement(mode,(csType != null) ? new String[]{WKTKeywords.BaseGeodCRS,WKTKeywords.GeogCS} : new String[]{WKTKeywords.GeodeticCRS,WKTKeywords.GeogCS,WKTKeywords.GeodCRS,WKTKeywords.GeocCS});
  if (element == null) {
    return null;
  }
  final boolean isWKT1;
  final Unit<Angle> angularUnit;
  Unit<?> defaultUnit;
  final int dimension;
switch (element.getKeywordIndex()) {
default :
{
      isWKT1=false;
      defaultUnit=parseUnit(element);
      angularUnit=Units.isAngular(defaultUnit) ? defaultUnit.asType(Angle.class) : NonSI.DEGREE_ANGLE;
      dimension=2;
      if (defaultUnit == null) {
        if (WKTKeywords.ellipsoidal.equals(csType)) {
          defaultUnit=NonSI.DEGREE_ANGLE;
        }
      }
      break;
    }
case 1:
{
    isWKT1=true;
    csType=WKTKeywords.ellipsoidal;
    angularUnit=parseScaledUnit(element,WKTKeywords.AngleUnit,SI.RADIAN);
    defaultUnit=angularUnit;
    dimension=2;
    break;
  }
case 3:
{
  isWKT1=true;
  csType=WKTKeywords.Cartesian;
  angularUnit=NonSI.DEGREE_ANGLE;
  defaultUnit=parseScaledUnit(element,WKTKeywords.LengthUnit,SI.METRE);
  dimension=3;
  break;
}
}
final String name=element.pullString("String_Node_Str");
GeodeticDatum datum=null;
SingleCRS baseCRS=null;
Conversion fromBase=null;
if (!isWKT1 && csType == null) {
fromBase=parseDerivingConversion(OPTIONAL,element,WKTKeywords.DerivingConversion,SI.METRE,angularUnit);
if (fromBase != null) {
baseCRS=parseGeodeticCRS(MANDATORY,element,WKTKeywords.ellipsoidal);
}
}
if (baseCRS == null) {
final PrimeMeridian meridian=parsePrimeMeridian(OPTIONAL,element,isWKT1,angularUnit);
datum=parseDatum(MANDATORY,element,meridian);
}
final CoordinateSystem cs;
try {
cs=parseCoordinateSystem(element,csType,dimension,isWKT1,defaultUnit,datum);
final Map<String,?> properties=parseMetadataAndClose(element,name,datum);
if (baseCRS != null) {
return crsFactory.createDerivedCRS(properties,baseCRS,fromBase,cs);
}
if (cs instanceof EllipsoidalCS) {
return crsFactory.createGeographicCRS(properties,datum,(EllipsoidalCS)cs);
}
if (cs instanceof CartesianCS) {
return crsFactory.createGeocentricCRS(properties,datum,referencing.upgradeGeocentricCS((CartesianCS)cs));
}
if (cs instanceof SphericalCS) {
return crsFactory.createGeocentricCRS(properties,datum,(SphericalCS)cs);
}
}
 catch (FactoryException exception) {
throw element.parseFailed(exception);
}
throw new LocalizedParseException(errorLocale,Errors.Keys.IllegalCoordinateSystem_1,new Object[]{cs.getClass()},element.offset);
}

Fixed version (ground truth):
/** 
 * Parses a   {@code "GeodeticCRS"} (WKT 2) element. The syntax is given by<a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#49">WKT 2 specification §8</a>. The legacy WKT 1 specification had two elements for this: {@preformat text}GEOGCS["<name>", <datum>, <prime meridian>, <angular unit>   ,<twin axes>} {,<authority>}] } and  {@preformat text}GEOCCS["<name>", <datum>, <prime meridian>, <linear unit>  ,<axis> ,<axis> ,<axis>} {,<authority>}] }
 * @param mode      {@link #FIRST},   {@link #OPTIONAL} or {@link #MANDATORY}.
 * @param parent    The parent element.
 * @param dimension The minimal number of dimensions (usually 2).
 * @param csType    The default coordinate system type, or {@code null} if unknown.Should be non-null only when parsing a  {@link GeneralDerivedCRS#getBaseCRS()} component.
 * @return The {@code "GeodeticCRS"} element as a {@link GeographicCRS} or {@link GeocentricCRS} object.
 * @throws ParseException if the {@code "GeodeticCRS"} element can not be parsed.
 * @see org.apache.sis.referencing.crs.DefaultGeographicCRS#formatTo(Formatter)
 * @see org.apache.sis.referencing.crs.DefaultGeocentricCRS#formatTo(Formatter)
 */
private SingleCRS parseGeodeticCRS(final int mode,final Element parent,int dimension,String csType) throws ParseException {
  final Element element=parent.pullElement(mode,(csType != null) ? new String[]{WKTKeywords.BaseGeodCRS,WKTKeywords.GeogCS} : new String[]{WKTKeywords.GeodeticCRS,WKTKeywords.GeogCS,WKTKeywords.GeodCRS,WKTKeywords.GeocCS});
  if (element == null) {
    return null;
  }
  final boolean isWKT1;
  final Unit<Angle> angularUnit;
  Unit<?> defaultUnit;
switch (element.getKeywordIndex()) {
default :
{
      isWKT1=false;
      defaultUnit=parseUnit(element);
      angularUnit=Units.isAngular(defaultUnit) ? defaultUnit.asType(Angle.class) : NonSI.DEGREE_ANGLE;
      if (defaultUnit == null) {
        if (WKTKeywords.ellipsoidal.equals(csType)) {
          defaultUnit=NonSI.DEGREE_ANGLE;
        }
      }
      break;
    }
case 1:
{
    isWKT1=true;
    csType=WKTKeywords.ellipsoidal;
    angularUnit=parseScaledUnit(element,WKTKeywords.AngleUnit,SI.RADIAN);
    defaultUnit=angularUnit;
    dimension=2;
    break;
  }
case 3:
{
  isWKT1=true;
  csType=WKTKeywords.Cartesian;
  angularUnit=NonSI.DEGREE_ANGLE;
  defaultUnit=parseScaledUnit(element,WKTKeywords.LengthUnit,SI.METRE);
  dimension=3;
  break;
}
}
final String name=element.pullString("String_Node_Str");
GeodeticDatum datum=null;
SingleCRS baseCRS=null;
Conversion fromBase=null;
if (!isWKT1 && csType == null) {
fromBase=parseDerivingConversion(OPTIONAL,element,WKTKeywords.DerivingConversion,toLinear(defaultUnit),angularUnit);
if (fromBase != null) {
baseCRS=parseGeodeticCRS(MANDATORY,element,getSourceDimensions(fromBase.getMethod()),WKTKeywords.ellipsoidal);
}
}
if (baseCRS == null) {
final PrimeMeridian meridian=parsePrimeMeridian(OPTIONAL,element,isWKT1,angularUnit);
datum=parseDatum(MANDATORY,element,meridian);
}
final CoordinateSystem cs;
try {
cs=parseCoordinateSystem(element,csType,dimension,isWKT1,defaultUnit,datum);
final Map<String,?> properties=parseMetadataAndClose(element,name,datum);
if (baseCRS != null) {
return crsFactory.createDerivedCRS(properties,baseCRS,fromBase,cs);
}
if (cs instanceof EllipsoidalCS) {
return crsFactory.createGeographicCRS(properties,datum,(EllipsoidalCS)cs);
}
if (cs instanceof CartesianCS) {
return crsFactory.createGeocentricCRS(properties,datum,referencing.upgradeGeocentricCS((CartesianCS)cs));
}
if (cs instanceof SphericalCS) {
return crsFactory.createGeocentricCRS(properties,datum,(SphericalCS)cs);
}
}
 catch (FactoryException exception) {
throw element.parseFailed(exception);
}
throw element.illegalCS(cs);
}