/**
   * Writes a single node to the output. Does not recurse on child nodes, and does not write the
   * number of children.
   */
  protected void writeSingleNode(AbstractDataTreeNode node, IPath path) throws IOException {
    /* write the node name */
    String name = node.getName();
    if (name == null) {
      name = ""; // $NON-NLS-1$
    }
    output.writeUTF(name);

    /* write the node type */
    writeNumber(node.type());

    /* maybe write the data */
    if (node.hasData()) {
      Object data = node.getData();

      /**
       * Write a flag indicating whether or not the data field is null. Zero means data is null,
       * non-zero means data is present
       */
      if (data == null) {
        writeNumber(0);
      } else {
        writeNumber(1);
        flatener.writeData(path, node.getData(), output);
      }
    }
  }
  /**
   * Writes the subtree rooted at the given node.
   *
   * @param node The subtree to write.
   * @param path The path of the current node.
   * @param depth The depth of the subtree to write.
   */
  protected void writeNode(AbstractDataTreeNode node, IPath path, int depth) throws IOException {
    int type = node.type();

    /* write the node name */
    String name = node.getName();
    if (name == null) {
      name = ""; // $NON-NLS-1$
    }
    output.writeUTF(name);

    /* write the node type */
    writeNumber(type);

    /* maybe write the data */
    if (node.hasData()) {
      Object data = node.getData();

      /**
       * Write a flag indicating whether or not the data field is null. Zero means data is null,
       * non-zero means data is present
       */
      if (data == null) {
        writeNumber(0);
      } else {
        writeNumber(1);
        flatener.writeData(path, node.getData(), output);
      }
    }

    /* maybe write the children */
    if (depth > 0 || depth == D_INFINITE) {
      AbstractDataTreeNode[] children = node.getChildren();

      /* write the number of children */
      writeNumber(children.length);

      /* write the children */
      int newDepth = (depth == D_INFINITE) ? D_INFINITE : depth - 1;
      for (int i = 0, imax = children.length; i < imax; i++) {
        writeNode(children[i], path.append(children[i].getName()), newDepth);
      }
    } else {
      /* write the number of children */
      writeNumber(0);
    }
  }