/**
   * Writes an entity's metadata.
   *
   * @param data Metadata objects to write.
   * @throws IOException If an I/O error occurs.
   */
  public void writeMetadata(WatchableObject data[]) throws IOException {
    for (WatchableObject obj : data) {
      int header = (obj.getType() << 5 | obj.getId() & 0x1f) & 0xff;
      this.writeByte(header);
      switch (obj.getType()) {
        case Constants.StandardProtocol.WatchableObjectIds.BYTE:
          this.writeByte((Byte) obj.getValue());
          break;
        case Constants.StandardProtocol.WatchableObjectIds.SHORT:
          this.writeShort((Short) obj.getValue());
          break;
        case Constants.StandardProtocol.WatchableObjectIds.INT:
          this.writeInt((Integer) obj.getValue());
          break;
        case Constants.StandardProtocol.WatchableObjectIds.FLOAT:
          this.writeFloat((Float) obj.getValue());
          break;
        case Constants.StandardProtocol.WatchableObjectIds.STRING:
          this.writeString((String) obj.getValue());
          break;
        case Constants.StandardProtocol.WatchableObjectIds.ITEM_STACK:
          this.writeItem((StandardItemStack) obj.getValue());
          break;
        case Constants.StandardProtocol.WatchableObjectIds.COORDINATES:
          this.writeCoordinates((Coordinates) obj.getValue());
          break;
      }
    }

    this.writeByte(127);
  }