### Question:
JsonTreeTraversal { public static <T extends JsonTreeVisitor> T traverseJsonTree(JsonNode node, T visitor) { traverseJsonTree(node, null, new ArrayList<>(), visitor); return visitor; }  static T traverseJsonTree(JsonNode node, T visitor);  }### Answer:
@Test public void canTraverseValueNodesInOrder() throws IOException { String yaml = "" + "object:\n" + " field1: 234\n" + " field2: value2\n" + " arrayField:\n" + " - arrayValue1\n" + " - 757\n" + " - arrayObjectValue: 1234\n"; JsonNode rootNode = new ObjectMapper(new YAMLFactory()).readTree(yaml); List<Call> calls = new ArrayList<>(); traverseJsonTree(rootNode, (node, parent, path) -> calls.add(new Call(node, parent, path))); MatcherAssert.assertThat(calls.get(0).path, contains(pathElements("object", "field1"))); assertThat(calls.get(0).node, is(instanceOf(IntNode.class))); assertThat(calls.get(0).node.intValue(), is(234)); MatcherAssert.assertThat(calls.get(0).parent, IsOptional.matches(instanceOf(ObjectNode.class))); MatcherAssert.assertThat(calls.get(1).path, contains(pathElements("object", "field2"))); assertThat(calls.get(1).node, is(instanceOf(TextNode.class))); assertThat(calls.get(1).node.textValue(), is("value2")); MatcherAssert.assertThat(calls.get(1).parent, IsOptional.matches(instanceOf(ObjectNode.class))); MatcherAssert.assertThat(calls.get(2).path, contains(pathElements("object", "arrayField", 0))); assertThat(calls.get(2).node, is(instanceOf(TextNode.class))); assertThat(calls.get(2).node.textValue(), is("arrayValue1")); MatcherAssert.assertThat(calls.get(2).parent, IsOptional.matches(instanceOf(ArrayNode.class))); MatcherAssert.assertThat(calls.get(3).path, contains(pathElements("object", "arrayField", 1))); assertThat(calls.get(3).node, is(instanceOf(IntNode.class))); assertThat(calls.get(3).node.intValue(), is(757)); MatcherAssert.assertThat(calls.get(3).parent, IsOptional.matches(instanceOf(ArrayNode.class))); MatcherAssert.assertThat(calls.get(4).path, contains(pathElements("object", "arrayField", 2, "arrayObjectValue"))); assertThat(calls.get(4).node, is(instanceOf(IntNode.class))); assertThat(calls.get(4).node.intValue(), is(1234)); MatcherAssert.assertThat(calls.get(4).parent, IsOptional.matches(instanceOf(ObjectNode.class))); }