public static List<MetadataObject> read(DataInputStream stream)
            throws IOException {
        
        ArrayList<MetadataObject> data = null;

        for (byte id = stream.readByte(); id != 127; id = stream.readByte()) {
            if (data == null) {
                data = new ArrayList<MetadataObject>();
            }

            MetadataObject entry = null;
            int type = (id & 0xE1) >> 5;
            int mask = id & 0x1F;

            switch (type) {
                case 0: // Byte
                    entry = new MetadataObject(type, mask,
                            Byte.valueOf(stream.readByte()));
                    break;
                case 1: // Short
                    entry = new MetadataObject(type, mask,
                            Short.valueOf(stream.readShort()));
                    break;
                case 2: // Integer
                    entry = new MetadataObject(type, mask,
                            Integer.valueOf(stream.readInt()));
                    break;
                case 3: // Float
                    entry = new MetadataObject(type, mask,
                            Float.valueOf(stream.readFloat()));
                    break;
                case 4: // String
                    entry = new MetadataObject(type, mask,
                            stream.readUTF());
                    break;
                case 5: // Item
                    short itemType = stream.readShort();
                    byte itemCount = stream.readByte();
                    short itemDamage = stream.readShort();
    
                    entry = new MetadataObject(type, mask,
                            new ItemStack(itemType, itemCount, itemDamage));
                case 6: // Position
                    int x = stream.readInt();
                    int y = stream.readInt();
                    int z = stream.readInt();
    
                    entry = new MetadataObject(type, mask,
                            new BlockPosition(x, y, z));

                default:
                    throw new UnsupportedOperationException("Unknown metadata type: " + type);
            }

            data.add(entry);
        }

        return data;
    }