/**
  * Writes the given marshaling tree to the given marshal target.
  *
  * <p>Any contained {@link RawObjectNode} will be marshaled in the same way as by {@link
  * #marshal(Object, Collection, MarshalTarget)}.
  *
  * <p>This method performs the equivalent of the following steps:
  *
  * <ul>
  *   <li>find the appropriate marshaler, either the one returned by {@link
  *       ObjectNode#getMarshaler()} if it is non-null, or otherwise the one returned by {@link
  *       #findMarshaler(Object, Collection)},
  *   <li>create a marshal context using {@link #create(Marshaler, Collection, MarshalTarget)},
  *   <li>process the marshaling tree using {@link #acceptTree(ObjectNode)}.
  * </ul>
  *
  * @param tree marshaling tree that needs to be transformed and marshaled
  * @param marshalers collection of {@link Marshaler} instances to choose from when a marshaler
  *     invokes {@link MarshalContext#writeObject(Object, Key)} recursively
  * @param marshalTarget marshal target for elementary marshal operations
  * @throws MarshalingException if a marshaling error occurs
  * @throws IOException if an I/O error occurs
  */
 public static void processMarshalingTree(
     ObjectNode tree, Collection<? extends Marshaler<?>> marshalers, MarshalTarget marshalTarget)
     throws IOException {
   Objects.requireNonNull(tree);
   Objects.requireNonNull(marshalers);
   Objects.requireNonNull(marshalTarget);
   Marshaler<?> marshaler = findMarshalerForObjectNode(tree, marshalers);
   try (DelegatingMarshalContext marshalContext = create(marshaler, marshalers, marshalTarget)) {
     marshalContext.acceptTree(tree);
   }
 }
 private IOException writeObjectNode(ObjectNode objectNode, @Nullable Key key) {
   assert key != null;
   try (DelegatingMarshalContext childContext =
       new DelegatingMarshalContext(
           key,
           marshalTarget.resolve(key),
           findMarshalerForObjectNode(objectNode, marshalers),
           marshalers,
           DelegatingMarshalContext.this)) {
     newKeyForObject(key);
     childContext.acceptTree(objectNode);
     return null;
   } catch (IOException exception) {
     return exception;
   }
 }