@Override
  protected void parseCreateField(ParseContext context, List<Field> fields) throws IOException {
    if (fieldType().indexOptions() == IndexOptions.NONE
        && !fieldType().stored()
        && !fieldType().hasDocValues()) {
      return;
    }

    Boolean value = context.parseExternalValue(Boolean.class);
    if (value == null) {
      XContentParser.Token token = context.parser().currentToken();
      if (token == XContentParser.Token.VALUE_NULL) {
        if (fieldType().nullValue() != null) {
          value = fieldType().nullValue();
        }
      } else {
        value = context.parser().booleanValue();
      }
    }

    if (value == null) {
      return;
    }
    fields.add(new Field(fieldType().names().indexName(), value ? "T" : "F", fieldType()));
    if (fieldType().hasDocValues()) {
      fields.add(new SortedNumericDocValuesField(fieldType().names().indexName(), value ? 1 : 0));
    }
  }
  @Override
  public Mapper parse(ParseContext context) throws IOException {
    ContentPath.Type origPathType = context.path().pathType();
    context.path().pathType(pathType);
    context.path().add(simpleName());

    GeoPoint sparse = context.parseExternalValue(GeoPoint.class);

    if (sparse != null) {
      parse(context, sparse, null);
    } else {
      sparse = new GeoPoint();
      XContentParser.Token token = context.parser().currentToken();
      if (token == XContentParser.Token.START_ARRAY) {
        token = context.parser().nextToken();
        if (token == XContentParser.Token.START_ARRAY) {
          // its an array of array of lon/lat [ [1.2, 1.3], [1.4, 1.5] ]
          while (token != XContentParser.Token.END_ARRAY) {
            parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
            token = context.parser().nextToken();
          }
        } else {
          // its an array of other possible values
          if (token == XContentParser.Token.VALUE_NUMBER) {
            double lon = context.parser().doubleValue();
            token = context.parser().nextToken();
            double lat = context.parser().doubleValue();
            while ((token = context.parser().nextToken()) != XContentParser.Token.END_ARRAY) ;
            parse(context, sparse.reset(lat, lon), null);
          } else {
            while (token != XContentParser.Token.END_ARRAY) {
              if (token == XContentParser.Token.VALUE_STRING) {
                parsePointFromString(context, sparse, context.parser().text());
              } else {
                parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
              }
              token = context.parser().nextToken();
            }
          }
        }
      } else if (token == XContentParser.Token.VALUE_STRING) {
        parsePointFromString(context, sparse, context.parser().text());
      } else if (token != XContentParser.Token.VALUE_NULL) {
        parse(context, GeoUtils.parseGeoPoint(context.parser(), sparse), null);
      }
    }

    context.path().remove();
    context.path().pathType(origPathType);
    return null;
  }
 @Override
 public Mapper parse(ParseContext context) throws IOException {
   try {
     Shape shape = context.parseExternalValue(Shape.class);
     if (shape == null) {
       ShapeBuilder shapeBuilder = ShapeBuilder.parse(context.parser(), this);
       if (shapeBuilder == null) {
         return null;
       }
       shape = shapeBuilder.build();
     }
     if (fieldType().pointsOnly() && !(shape instanceof Point)) {
       throw new MapperParsingException(
           "[{"
               + fieldType().names().fullName()
               + "}] is configured for points only but a "
               + ((shape instanceof JtsGeometry)
                   ? ((JtsGeometry) shape).getGeom().getGeometryType()
                   : shape.getClass())
               + " was found");
     }
     Field[] fields = fieldType().defaultStrategy().createIndexableFields(shape);
     if (fields == null || fields.length == 0) {
       return null;
     }
     for (Field field : fields) {
       if (!customBoost()) {
         field.setBoost(fieldType().boost());
       }
       context.doc().add(field);
     }
   } catch (Exception e) {
     throw new MapperParsingException(
         "failed to parse [" + fieldType().names().fullName() + "]", e);
   }
   return null;
 }