@Override
  public ValueSource parse(FunctionQParser fp) throws SyntaxError {
    String fieldName = fp.parseId();
    SchemaField field = fp.getReq().getSchema().getField(fieldName);
    FieldType type = field.getType();
    if (!(type instanceof MultiPointDocValuesField))
      throw new SyntaxError(
          "This function only supports fields of type "
              + MultiPointDocValuesField.class.getName()
              + ", not "
              + type.getClass().getName());
    MultiPointDocValuesField mpdvFieldType = (MultiPointDocValuesField) type;

    double[] parsedLatLong = null;
    try {
      parsedLatLong = ParseUtils.parseLatitudeLongitude(fp.parseArg());
    } catch (InvalidShapeException e) {
      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
    }

    double y = parsedLatLong[0];
    double x = parsedLatLong[1];

    SpatialContext ctx = mpdvFieldType.getCtx();
    Point point = ctx.makePoint(x, y);

    String score = fp.getLocalParams().get("score", "distance");
    ValueSource valueSource = new MultiPointDistanceValueSource(fieldName, point, ctx);

    if ("distance".equals(score)) {
      return valueSource;
    } else if ("recipDistance".equals(score)) {
      int shift = fp.getLocalParams().getInt("shift", 100);
      int maxScore = fp.getLocalParams().getInt("maxScore", 10);
      return new ReciprocalFloatFunction(valueSource, maxScore, shift, shift);
    } else {
      throw new SolrException(
          SolrException.ErrorCode.BAD_REQUEST,
          "'score' local-param must be one of 'distance', or 'recipDistance'");
    }
  }