@Override
  public JsonElement serialize(
      WrappedStack wrappedStack, Type type, JsonSerializationContext context) {
    JsonObject jsonWrappedStack = new JsonObject();

    Gson gsonWrappedStack = new Gson();

    jsonWrappedStack.addProperty("className", wrappedStack.className);
    jsonWrappedStack.addProperty("stackSize", wrappedStack.stackSize);

    if (wrappedStack.wrappedStack instanceof ItemStack) {
      JsonItemStack jsonItemStack = new JsonItemStack();
      jsonItemStack.itemID = ((ItemStack) wrappedStack.wrappedStack).itemID;
      jsonItemStack.itemDamage = ((ItemStack) wrappedStack.wrappedStack).getItemDamage();
      jsonItemStack.stackSize = ((ItemStack) wrappedStack.wrappedStack).stackSize;
      if (((ItemStack) wrappedStack.wrappedStack).stackTagCompound != null) {
        try {
          jsonItemStack.compressedStackTagCompound =
              CompressedStreamTools.compress(
                  ((ItemStack) wrappedStack.wrappedStack).stackTagCompound);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      jsonWrappedStack.add(
          "wrappedStack", gsonWrappedStack.toJsonTree(jsonItemStack, JsonItemStack.class));
    } else if (wrappedStack.wrappedStack instanceof OreStack) {
      jsonWrappedStack.add(
          "wrappedStack", gsonWrappedStack.toJsonTree(wrappedStack.wrappedStack, OreStack.class));
    } else if (wrappedStack.wrappedStack instanceof EnergyStack) {
      jsonWrappedStack.add(
          "wrappedStack",
          gsonWrappedStack.toJsonTree(wrappedStack.wrappedStack, EnergyStack.class));
    } else if (wrappedStack.wrappedStack instanceof FluidStack) {
      jsonWrappedStack.add(
          "wrappedStack", gsonWrappedStack.toJsonTree(wrappedStack.wrappedStack, FluidStack.class));
    }

    return jsonWrappedStack;
  }