@Override
  public void spawnServerSide(
      EntityPlayerMP player, NBTTagCompound dataFromClient, NBTTagCompound rewardData) {
    byte baseRotation =
        dataFromClient.getBoolean(ROTATE_KEY) ? dataFromClient.getByte(BASEROTATION_KEY) : -1;
    NBTTagList list = dataFromClient.getTagList(SHAPES_KEY, COMPOUND);
    for (int i = 0; i < list.tagCount(); i++) {
      NBTTagCompound shapeNbt = list.getCompoundTagAt(i);

      ArrayList<NBTTagCompound> blockDataList = new ArrayList<>();
      NBTTagList blockDataNbt = shapeNbt.getTagList(BLOCKDATA_KEY, COMPOUND);
      for (int j = 0; j < blockDataNbt.tagCount(); j++)
        blockDataList.add(blockDataNbt.getCompoundTagAt(j));

      applyShape(Shapes.loadShape(shapeNbt), player, blockDataList, baseRotation);
    }
  }
  @Override
  public NBTTagCompound getExample() {
    NBTTagCompound root = new NBTTagCompound();
    NBTTagList shapesList = new NBTTagList();

    // Sphere
    {
      NBTTagCompound shapeNbt =
          Shapes.storeShape(new Sphere(10).setHollow(true).setReplaceableOnly(true));

      NBTTagList blockDataNbt = new NBTTagList();
      {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 35);
        compound.setInteger(WEIGHT_KEY, 5);
        blockDataNbt.appendTag(compound);
      }
      {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 35);
        compound.setInteger(META_KEY, 5);
        blockDataNbt.appendTag(compound);
      }

      shapeNbt.setTag(BLOCKDATA_KEY, blockDataNbt);

      shapesList.appendTag(shapeNbt);
    }

    // Box
    {
      NBTTagCompound shapeNbt =
          Shapes.storeShape(new Box(new PointI(-2, -3, 5), 5, 2, 3).setReplaceableOnly(true));

      NBTTagList blockDataNbt = new NBTTagList();
      {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 98);
        blockDataNbt.appendTag(compound);
      }
      {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 98);
        compound.setInteger(META_KEY, 1);
        blockDataNbt.appendTag(compound);
      }
      {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 98);
        compound.setInteger(META_KEY, 2);
        blockDataNbt.appendTag(compound);
      }
      {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 98);
        compound.setInteger(META_KEY, 3);
        blockDataNbt.appendTag(compound);
      }
      shapeNbt.setTag(BLOCKDATA_KEY, blockDataNbt);

      shapesList.appendTag(shapeNbt);
    }

    // Cylinder
    {
      NBTTagCompound shapeNbt = Shapes.storeShape(new Cylinder(new PointI(0, 3, 0), 12));

      NBTTagList blockDataNbt = new NBTTagList();
      {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 99);
        compound.setInteger(META_KEY, 14);
        blockDataNbt.appendTag(compound);
      }
      {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 100);
        compound.setInteger(META_KEY, 14);
        blockDataNbt.appendTag(compound);
      }
      shapeNbt.setTag(BLOCKDATA_KEY, blockDataNbt);

      shapesList.appendTag(shapeNbt);
    }

    // Pillar
    {
      NBTTagCompound shapeNbt = Shapes.storeShape(new Pillar(new PointI(-2, 0, -6), 15));

      NBTTagList blockDataNbt = new NBTTagList();
      for (int meta = 0; meta < 16; meta++) {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 159);
        compound.setInteger(META_KEY, meta);
        blockDataNbt.appendTag(compound);
      }
      shapeNbt.setTag(BLOCKDATA_KEY, blockDataNbt);

      shapesList.appendTag(shapeNbt);
    }

    // Point
    {
      NBTTagCompound shapeNbt = Shapes.storeShape(new PointI(0, 0, 0));

      NBTTagList blockDataNbt = new NBTTagList();
      {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 54);

        TileEntityChest chest = new TileEntityChest();
        chest.setInventorySlotContents(13, new ItemStack(Items.golden_apple));
        NBTTagCompound chestNbt = new NBTTagCompound();
        chest.writeToNBT(chestNbt);
        compound.setTag(TEDATA_KEY, chestNbt);

        blockDataNbt.appendTag(compound);
      }
      shapeNbt.setTag(BLOCKDATA_KEY, blockDataNbt);

      shapesList.appendTag(shapeNbt);
    }

    // Point
    {
      NBTTagCompound shapeNbt = Shapes.storeShape(new PointI(-1, -2, -1));

      NBTTagList blockDataNbt = new NBTTagList();
      for (Object mob : EntityList.entityEggs.keySet()) {
        NBTTagCompound compound = new NBTTagCompound();
        compound.setInteger(BLOCKID_KEY, 52);

        TileEntityMobSpawner mobSpawner = new TileEntityMobSpawner();
        mobSpawner.func_145881_a().setEntityName(EntityList.getStringFromID((Integer) mob));
        NBTTagCompound spawnerNbt = new NBTTagCompound();
        mobSpawner.writeToNBT(spawnerNbt);

        // Removes some clutter, not really necessary though
        spawnerNbt.removeTag("x");
        spawnerNbt.removeTag("y");
        spawnerNbt.removeTag("z");

        compound.setTag(TEDATA_KEY, spawnerNbt);

        blockDataNbt.appendTag(compound);
      }
      shapeNbt.setTag(BLOCKDATA_KEY, blockDataNbt);

      shapesList.appendTag(shapeNbt);
    }

    root.setTag(SHAPES_KEY, shapesList);
    return root;
  }