/**
   * Gson invokes this call-back method during serialization when it encounters a field of the
   * specified type.
   *
   * <p>
   *
   * <p>In the implementation of this call-back method, you should consider invoking {@link
   * com.google.gson.JsonSerializationContext#serialize(Object, java.lang.reflect.Type)} method to
   * create JsonElements for any non-trivial field of the {@code wrappedStack} object. However, you
   * should never invoke it on the {@code wrappedStack} object itself since that will cause an
   * infinite loop (Gson will call your call-back method again).
   *
   * @param wrappedStack the object that needs to be converted to Json.
   * @param typeOfSrc the actual type (fully genericized version) of the source object.
   * @param context
   * @return a JsonElement corresponding to the specified object.
   */
  @Override
  public JsonElement serialize(
      WrappedStack wrappedStack, Type typeOfSrc, JsonSerializationContext context) {
    JsonObject jsonWrappedStack = new JsonObject();

    Gson gson = new Gson();

    jsonWrappedStack.addProperty("type", wrappedStack.objectType);
    jsonWrappedStack.addProperty("stackSize", wrappedStack.stackSize);

    if (wrappedStack.wrappedStack instanceof ItemStack) {
      JsonItemStack jsonItemStack = new JsonItemStack();
      jsonItemStack.itemName =
          Item.itemRegistry.getNameForObject(((ItemStack) wrappedStack.wrappedStack).getItem());
      jsonItemStack.itemDamage = ((ItemStack) wrappedStack.wrappedStack).getItemDamage();
      if (((ItemStack) wrappedStack.wrappedStack).stackTagCompound != null) {
        jsonItemStack.itemNBTTagCompound = ((ItemStack) wrappedStack.wrappedStack).stackTagCompound;
      }
      jsonWrappedStack.add(
          "objectData",
          JsonItemStack.jsonSerializer.toJsonTree(jsonItemStack, JsonItemStack.class));
    } else if (wrappedStack.wrappedStack instanceof OreStack) {
      jsonWrappedStack.add(
          "objectData", gson.toJsonTree(wrappedStack.wrappedStack, OreStack.class));
    } else if (wrappedStack.wrappedStack instanceof FluidStack) {
      JsonFluidStack jsonFluidStack = new JsonFluidStack((FluidStack) wrappedStack.wrappedStack);
      jsonWrappedStack.add(
          "objectData",
          JsonFluidStack.jsonSerializer.toJsonTree(jsonFluidStack, JsonFluidStack.class));
    }

    return jsonWrappedStack;
  }
  @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;
  }