@SuppressWarnings({"unchecked"})
  private static void extractRawValues(
      List values, Map<String, Object> part, String[] pathElements, int index) {
    if (index == pathElements.length) {
      return;
    }

    String key = pathElements[index];
    Object currentValue = part.get(key);
    int nextIndex = index + 1;
    while (currentValue == null && nextIndex != pathElements.length) {
      key += "." + pathElements[nextIndex];
      currentValue = part.get(key);
      nextIndex++;
    }

    if (currentValue == null) {
      return;
    }

    if (currentValue instanceof Map) {
      extractRawValues(values, (Map<String, Object>) currentValue, pathElements, nextIndex);
    } else if (currentValue instanceof List) {
      extractRawValues(values, (List) currentValue, pathElements, nextIndex);
    } else {
      values.add(currentValue);
    }
  }
  public void testExtractRawValue() throws Exception {
    XContentBuilder builder =
        XContentFactory.jsonBuilder().startObject().field("test", "value").endObject();

    Map<String, Object> map;
    try (XContentParser parser =
        XContentFactory.xContent(XContentType.JSON).createParser(builder.string())) {
      map = parser.map();
    }
    assertThat(XContentMapValues.extractRawValues("test", map).get(0).toString(), equalTo("value"));

    builder = XContentFactory.jsonBuilder().startObject().field("test.me", "value").endObject();

    try (XContentParser parser =
        XContentFactory.xContent(XContentType.JSON).createParser(builder.string())) {
      map = parser.map();
    }
    assertThat(
        XContentMapValues.extractRawValues("test.me", map).get(0).toString(), equalTo("value"));

    builder =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("path1")
            .startObject("path2")
            .field("test", "value")
            .endObject()
            .endObject()
            .endObject();

    try (XContentParser parser =
        XContentFactory.xContent(XContentType.JSON).createParser(builder.string())) {
      map = parser.map();
    }
    assertThat(
        XContentMapValues.extractRawValues("path1.path2.test", map).get(0).toString(),
        equalTo("value"));

    builder =
        XContentFactory.jsonBuilder()
            .startObject()
            .startObject("path1.xxx")
            .startObject("path2.yyy")
            .field("test", "value")
            .endObject()
            .endObject()
            .endObject();

    try (XContentParser parser =
        XContentFactory.xContent(XContentType.JSON).createParser(builder.string())) {
      map = parser.map();
    }
    assertThat(
        XContentMapValues.extractRawValues("path1.xxx.path2.yyy.test", map).get(0).toString(),
        equalTo("value"));
  }
 @SuppressWarnings({"unchecked"})
 private static void extractRawValues(
     List values, List<Object> part, String[] pathElements, int index) {
   for (Object value : part) {
     if (value == null) {
       continue;
     }
     if (value instanceof Map) {
       extractRawValues(values, (Map<String, Object>) value, pathElements, index);
     } else if (value instanceof List) {
       extractRawValues(values, (List) value, pathElements, index);
     } else {
       values.add(value);
     }
   }
 }
 /**
  * Extracts raw values (string, int, and so on) based on the path provided returning all of them
  * as a single list.
  */
 public static List<Object> extractRawValues(String path, Map<String, Object> map) {
   List<Object> values = new ArrayList<>();
   String[] pathElements = path.split("\\.");
   if (pathElements.length == 0) {
     return values;
   }
   extractRawValues(values, map, pathElements, 0);
   return values;
 }
 /**
  * Returns the values associated with the path. Those are "low" level values, and it can handle
  * path expression where an array/list is navigated within.
  */
 public List<Object> extractRawValues(String path) {
   return XContentMapValues.extractRawValues(path, loadSourceIfNeeded());
 }