gt:             for(HatPart hatPart : hatParts)
context: package me.ichun.mods.hats.common.world;
  
  import me.ichun.mods.hats.common.hats.HatHandler;
  import net.minecraft.nbt.CompoundNBT;
  import net.minecraft.util.Direction;
  import net.minecraft.util.ResourceLocation;
  import net.minecraft.world.storage.WorldSavedData;
  import net.minecraftforge.common.capabilities.Capability;
  import net.minecraftforge.common.capabilities.CapabilityInject;
  import net.minecraftforge.common.capabilities.ICapabilitySerializable;
  import net.minecraftforge.common.util.LazyOptional;
  
  import javax.annotation.Nonnull;
  import javax.annotation.Nullable;
  import java.util.*;
  
  public class HatsSavedData extends WorldSavedData
  {
      public static final String ID = "hats_save";
      public HashMap<UUID, PlayerHatData> playerHats = new HashMap<>();
  
      public HatsSavedData()
      {
          super(ID);
      }
  
      @Override
      public void read(CompoundNBT tag)
      {
          playerHats.clear();
  
          int count = tag.getInt("count");
          for(int i = 0; i < count; i++)
          {
              PlayerHatData playerData = new PlayerHatData();
              playerData.read(tag.getCompound("hats_" + i));
  
              playerHats.put(playerData.owner, playerData);
          }
      }
  
      @Override
      public CompoundNBT write(CompoundNBT tag)
      {
          tag.putInt("count", playerHats.size());
  
          int i = 0;
          for(Map.Entry<UUID, PlayerHatData> entry : playerHats.entrySet())
          {
              tag.put("hats_" + i, entry.getValue().write(new CompoundNBT()));
              i++;
          }
  
          return tag;
      }
  
      public static class PlayerHatData
      {
          public UUID owner;
          public int tokenCount;
          public ArrayList<HatPart> hatParts = new ArrayList<>();
  
          public PlayerHatData(){}
  
          public PlayerHatData(UUID owner)
          {
              this.owner = owner;
          }
  
          public void read(CompoundNBT tag)
          {
              hatParts.clear();
  
              owner = tag.getUniqueId("owner");
  
              tokenCount = tag.getInt("tokenCount");
  
              int count = tag.getInt("partCount");
  
              for(int i = 0; i < count; i++)
              {
                  CompoundNBT hatTag = tag.getCompound("hat_" + i);
                  HatPart part = new HatPart();
                  part.read(hatTag);
  
                  if(!part.name.isEmpty())
                  {
                      hatParts.add(part);
                  }
              }
          }
  
          public CompoundNBT write(CompoundNBT tag)
          {
              tag.putUniqueId("owner", owner);
  
              tag.putInt("tokenCount", tokenCount);
  
              tag.putInt("partCount", hatParts.size());
  
              for(int i = 0; i < hatParts.size(); i++)
              {
                  HatPart part = hatParts.get(i);
  
                  tag.put("hat_" + i, part.write(new CompoundNBT()));
              }
  
              return tag;
          }
      }
  
      public static class HatPart
              implements Comparable<HatPart>
      {
          @CapabilityInject(HatPart.class)
          public static Capability<HatPart> CAPABILITY_INSTANCE;
          public static final ResourceLocation CAPABILITY_IDENTIFIER = new ResourceLocation("hats", "capability_hat");
  
          public String name = "";
          public int count = -1;
          public boolean isFavourite;
          public boolean isNew;
          public boolean isShowing;
          public float[] colouriser = new float[] { 0F, 0F, 0F, 0F }; //0 0 0 0 = no change to colours. goes up to 1 1 1 1 for black & invisible
          public float[] hsbiser = new float[] { 0F, 0F, 0F }; //0 0 0 = no change to colours. goes up to 1 1 1 HSB
          public boolean enchanted = false;
          public ArrayList<HatPart> hatParts = new ArrayList<>(); //yay infinite recursion
  
          public HatPart(){}
  
          public HatPart(String s)
          {
              name = s;
              count = 1;
          }
  
          public HatPart setNew()
          {
              isNew = true;
              return this;
          }
  
          public void copy(HatPart part)
          {
              name = part.name;
              count = part.count;
              isFavourite = part.isFavourite;
              isShowing = part.isShowing;
              isNew = part.isNew;
              colouriser = part.colouriser.clone();
              hsbiser = part.hsbiser.clone();
              enchanted = part.enchanted;
  
              hatParts.clear();
              for(HatPart hatPart : part.hatParts)
              {
                  hatParts.add(hatPart.createCopy());
              }
          }
  
          public HatPart createCopy()
          {
              HatPart part = new HatPart();
              part.copy(this);
              return part;
          }
  
          public HatPart createRandom(Random random)
          {
              HatPart part = new HatPart();
              part.copy(this);
  
              part.randomize(random);
  
              return part;
          }
  
          public HatPart get(HatPart part)
          {
              if(part.name.equals(name))
              {
                  return this;
              }
  
              for(HatPart hatPart : hatParts)
              {
                  HatPart accPart = hatPart.get(part);
                  if(accPart != null)
                  {
                      return accPart;
                  }
              }
  
              return null;
          }
  
          public boolean remove(HatPart part)
          {
              if(hatParts.removeIf(hatPart -> part.name.equals(hatPart.name)))
              {
                  return true;
              }
              else
              {
                  for(HatPart hatPart : hatParts)
                  {
                      if(hatPart.remove(part))
                      {
                          return true;
                      }
                  }
              }
              return false;
          }
  
          public void randomize(Random random)
          {
              this.count = 1;
              this.isShowing = true;
  
              for(int i = hatParts.size() - 1; i >= 0; i--)
              {
                  if(random.nextBoolean()) //you LOST the coin toss
                  {
                      hatParts.remove(i);
                  }
              }
  
              for(HatPart hatPart : hatParts)
              {
                  hatPart.randomize(random);
              }
          }
  
          public boolean isAHat()
          {
              return !name.isEmpty() && count >= 0;
          }
  
          public boolean hasNew()
          {
              boolean newStuff = isNew;
              if(!isNew)
              {
                  for(HatPart hatPart : hatParts)
                  {
                      newStuff = newStuff | hatPart.hasNew();
                  }
              }
              return newStuff;
          }
  
          public HatPart setNoNew()
          {
              isNew = false;
  