private Point parsePoint(int dimension, CoordinateReferenceSystem crs)
      throws XmlPullParserException, IOException, NoSuchAuthorityCodeException, FactoryException {

    parser.require(START_TAG, GML.NAMESPACE, GML.Point.getLocalPart());

    crs = crs(crs);

    Point geom;
    parser.nextTag();
    parser.require(START_TAG, GML.NAMESPACE, null);
    Coordinate point;
    if (GML.pos.getLocalPart().equals(parser.getName())) {
      Coordinate[] coords = parseCoordList(dimension, crs);
      point = coords[0];
      parser.nextTag();
    } else if (GML.coordinates.getLocalPart().equals(parser.getName())) {
      Coordinate[] coords = parseCoordinates(dimension, crs);
      point = coords[0];
      parser.nextTag();
    } else if (GML.coord.getLocalPart().equals(parser.getName())) {
      point = parseCoord();
      parser.nextTag();
    } else {
      throw new IllegalStateException("Unknown coordinate element for Point: " + parser.getName());
    }

    parser.require(END_TAG, GML.NAMESPACE, GML.Point.getLocalPart());

    geom = geomFac.createPoint(point);
    geom.setUserData(crs);
    return geom;
  }
  /**
   * Parses a MultiPoint.
   *
   * <p>Precondition: parser positioned at a {@link GML#MultiPoint MultiPoint} start tag
   *
   * <p>Postcondition: parser positioned at the {@link GML#MultiPoint MultiPoint} end tag of the
   * starting tag
   *
   * @throws IOException
   * @throws XmlPullParserException
   * @throws IOException
   * @throws XmlPullParserException
   * @throws FactoryException
   * @throws NoSuchAuthorityCodeException
   * @throws FactoryException
   * @throws NoSuchAuthorityCodeException
   */
  private Geometry parseMultiPoint(int dimension, CoordinateReferenceSystem crs)
      throws XmlPullParserException, IOException, NoSuchAuthorityCodeException, FactoryException {
    Geometry geom;
    parser.nextTag();
    final QName memberTag = new QName(parser.getNamespace(), parser.getName());
    List<Point> points = new ArrayList<Point>(4);
    if (GML.pointMembers.equals(memberTag)) {
      while (true) {
        parser.nextTag();
        if (END_TAG == parser.getEventType()
            && GML.pointMembers.getLocalPart().equals(parser.getName())) {
          // we're done
          break;
        }
        Point p = parsePoint(dimension, crs);
        points.add(p);
      }
      parser.nextTag();
    } else if (GML.pointMember.equals(memberTag)) {
      while (true) {
        parser.nextTag();
        parser.require(START_TAG, GML.NAMESPACE, GML.Point.getLocalPart());

        Point p = parsePoint(dimension, crs);
        points.add(p);
        parser.nextTag();
        parser.require(END_TAG, GML.NAMESPACE, GML.pointMember.getLocalPart());
        parser.nextTag();
        if (END_TAG == parser.getEventType()
            && GML.MultiPoint.getLocalPart().equals(parser.getName())) {
          // we're done
          break;
        }
      }
    }
    parser.require(END_TAG, GML.NAMESPACE, GML.MultiPoint.getLocalPart());

    geom = geomFac.createMultiPoint(points.toArray(new Point[points.size()]));
    return geom;
  }