public void parse(ParseContext context) throws IOException {
    if (!enabled) {
      context.parser().skipChildren();
      return;
    }
    XContentParser parser = context.parser();

    String currentFieldName = parser.currentName();
    XContentParser.Token token = parser.currentToken();
    if (token == XContentParser.Token.VALUE_NULL) {
      // the object is null ("obj1" : null), simply bail
      return;
    }

    Document restoreDoc = null;
    if (nested.isNested()) {
      Document nestedDoc = new Document();
      // pre add the uid field if possible (id was already provided)
      Fieldable uidField = context.doc().getFieldable(UidFieldMapper.NAME);
      if (uidField != null) {
        // we don't need to add it as a full uid field in nested docs, since we don't need
        // versioning
        // we also rely on this for UidField#loadVersion

        // this is a deeply nested field
        if (uidField.stringValue() != null) {
          nestedDoc.add(
              new Field(
                  UidFieldMapper.NAME,
                  uidField.stringValue(),
                  Field.Store.NO,
                  Field.Index.NOT_ANALYZED));
        } else {
          nestedDoc.add(
              new Field(
                  UidFieldMapper.NAME,
                  ((UidField) uidField).uid(),
                  Field.Store.NO,
                  Field.Index.NOT_ANALYZED));
        }
      }
      // the type of the nested doc starts with __, so we can identify that its a nested one in
      // filters
      // note, we don't prefix it with the type of the doc since it allows us to execute a nested
      // query
      // across types (for example, with similar nested objects)
      nestedDoc.add(
          new Field(
              TypeFieldMapper.NAME, nestedTypePath, Field.Store.NO, Field.Index.NOT_ANALYZED));
      restoreDoc = context.switchDoc(nestedDoc);
      context.addDoc(nestedDoc);
    }

    ContentPath.Type origPathType = context.path().pathType();
    context.path().pathType(pathType);

    // if we are at the end of the previous object, advance
    if (token == XContentParser.Token.END_OBJECT) {
      token = parser.nextToken();
    }
    if (token == XContentParser.Token.START_OBJECT) {
      // if we are just starting an OBJECT, advance, this is the object we are parsing, we need the
      // name first
      token = parser.nextToken();
    }

    while (token != XContentParser.Token.END_OBJECT) {
      if (token == XContentParser.Token.START_OBJECT) {
        serializeObject(context, currentFieldName);
      } else if (token == XContentParser.Token.START_ARRAY) {
        serializeArray(context, currentFieldName);
      } else if (token == XContentParser.Token.FIELD_NAME) {
        currentFieldName = parser.currentName();
      } else if (token == XContentParser.Token.VALUE_NULL) {
        serializeNullValue(context, currentFieldName);
      } else if (token == null) {
        throw new MapperParsingException(
            "object mapping for ["
                + name
                + "] tried to parse as object, but got EOF, has a concrete value been provided to it?");
      } else if (token.isValue()) {
        serializeValue(context, currentFieldName, token);
      }
      token = parser.nextToken();
    }
    // restore the enable path flag
    context.path().pathType(origPathType);
    if (nested.isNested()) {
      Document nestedDoc = context.switchDoc(restoreDoc);
      if (nested.isIncludeInParent()) {
        for (Fieldable field : nestedDoc.getFields()) {
          if (field.name().equals(UidFieldMapper.NAME)
              || field.name().equals(TypeFieldMapper.NAME)) {
            continue;
          } else {
            context.doc().add(field);
          }
        }
      }
      if (nested.isIncludeInRoot()) {
        // don't add it twice, if its included in parent, and we are handling the master doc...
        if (!(nested.isIncludeInParent() && context.doc() == context.rootDoc())) {
          for (Fieldable field : nestedDoc.getFields()) {
            if (field.name().equals(UidFieldMapper.NAME)
                || field.name().equals(TypeFieldMapper.NAME)) {
              continue;
            } else {
              context.rootDoc().add(field);
            }
          }
        }
      }
    }
  }