private static void mapEntity(
      XContentBuilder xContentBuilder,
      Class clazz,
      boolean isRootObject,
      String idFieldName,
      String nestedObjectFieldName)
      throws IOException {

    java.lang.reflect.Field[] fields = clazz.getDeclaredFields();

    if (!isRootObject && isAnyPropertyAnnotatedAsField(fields)) {
      xContentBuilder
          .startObject(nestedObjectFieldName)
          .field(FIELD_TYPE, TYPE_VALUE_OBJECT)
          .startObject(FIELD_PROPERTIES);
    }

    for (java.lang.reflect.Field field : fields) {

      if (field.isAnnotationPresent(Transient.class)) {
        continue;
      }

      if (isEntity(field) && !isInIgnoreFields(field)) {
        mapEntity(xContentBuilder, field.getType(), false, EMPTY, field.getName());
      }

      Field singleField = field.getAnnotation(Field.class);
      MultiField multiField = field.getAnnotation(MultiField.class);
      GeoPointField geoPoint = field.getAnnotation(GeoPointField.class);

      if (field.getType() == GeoPoint.class || geoPoint != null) {
        applyGeoPointFieldMapping(xContentBuilder, field);
      }

      if (isRootObject && singleField != null && isIdField(field, idFieldName)) {
        applyDefaultIdFieldMapping(xContentBuilder, field);
      } else if (multiField != null) {
        addMultiFieldMapping(xContentBuilder, field, multiField);
      } else if (singleField != null) {
        addSingleFieldMapping(xContentBuilder, field, singleField);
      }
    }

    if (!isRootObject && isAnyPropertyAnnotatedAsField(fields)) {
      xContentBuilder.endObject().endObject();
    }
  }
 private static boolean isInIgnoreFields(java.lang.reflect.Field field) {
   Field fieldAnnotation = field.getAnnotation(Field.class);
   if (null != fieldAnnotation) {
     String[] ignoreFields = fieldAnnotation.ignoreFields();
     return Arrays.asList(ignoreFields).contains(field.getName());
   }
   return false;
 }