package net.minecraft.client.resources.model;

import net.minecraft.client.renderer.block.model.multipart.Selector;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.client.renderer.blockentity.EnchantTableRenderer;
import net.minecraft.client.renderer.blockentity.ConduitRenderer;
import net.minecraft.client.renderer.blockentity.BellRenderer;
import java.util.HashSet;
import java.util.stream.Stream;
import java.io.InputStream;
import net.minecraft.client.renderer.block.model.MultiVariant;
import net.minecraft.client.renderer.block.model.multipart.MultiPart;
import com.google.common.collect.ImmutableList;
import java.util.function.Supplier;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.server.packs.resources.Resource;
import java.io.Reader;
import java.io.Closeable;
import org.apache.commons.io.IOUtils;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.io.StringReader;
import java.io.FileNotFoundException;
import java.util.Objects;
import net.minecraft.world.level.block.state.properties.Property;
import java.util.function.Predicate;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import java.util.Iterator;
import java.util.function.Function;
import java.util.Collection;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import net.minecraft.core.Registry;
import net.minecraft.client.renderer.block.BlockModelShaper;
import java.io.IOException;
import net.minecraft.Util;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import net.minecraft.util.profiling.ProfilerFiller;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.client.renderer.texture.TextureAtlas;
import com.mojang.datafixers.util.Pair;
import com.mojang.math.Transformation;
import org.apache.commons.lang3.tuple.Triple;
import net.minecraft.client.renderer.block.model.BlockModelDefinition;
import net.minecraft.client.color.block.BlockColors;
import javax.annotation.Nullable;
import net.minecraft.client.renderer.texture.AtlasSet;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.client.renderer.block.model.ItemModelGenerator;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.client.renderer.block.model.BlockModel;
import com.google.common.base.Splitter;
import java.util.Map;
import com.google.common.annotations.VisibleForTesting;
import org.apache.logging.log4j.Logger;
import java.util.Set;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.resources.ResourceLocation;
import java.util.List;

public class ModelBakery {
    public static final Material FIRE_0;
    public static final Material FIRE_1;
    public static final Material LAVA_FLOW;
    public static final Material WATER_FLOW;
    public static final Material WATER_OVERLAY;
    public static final Material BANNER_BASE;
    public static final Material SHIELD_BASE;
    public static final Material NO_PATTERN_SHIELD;
    public static final List<ResourceLocation> DESTROY_STAGES;
    public static final List<ResourceLocation> BREAKING_LOCATIONS;
    public static final List<RenderType> DESTROY_TYPES;
    private static final Set<Material> UNREFERENCED_TEXTURES;
    private static final Logger LOGGER;
    public static final ModelResourceLocation MISSING_MODEL_LOCATION;
    private static final String MISSING_MODEL_LOCATION_STRING;
    @VisibleForTesting
    public static final String MISSING_MODEL_MESH;
    private static final Map<String, String> BUILTIN_MODELS;
    private static final Splitter COMMA_SPLITTER;
    private static final Splitter EQUAL_SPLITTER;
    public static final BlockModel GENERATION_MARKER;
    public static final BlockModel BLOCK_ENTITY_MARKER;
    private static final StateDefinition<Block, BlockState> ITEM_FRAME_FAKE_DEFINITION;
    private static final ItemModelGenerator ITEM_MODEL_GENERATOR;
    private static final Map<ResourceLocation, StateDefinition<Block, BlockState>> STATIC_DEFINITIONS;
    private final ResourceManager resourceManager;
    @Nullable
    private AtlasSet atlasSet;
    private final BlockColors blockColors;
    private final Set<ResourceLocation> loadingStack;
    private final BlockModelDefinition.Context context;
    private final Map<ResourceLocation, UnbakedModel> unbakedCache;
    private final Map<Triple<ResourceLocation, Transformation, Boolean>, BakedModel> bakedCache;
    private final Map<ResourceLocation, UnbakedModel> topLevelModels;
    private final Map<ResourceLocation, BakedModel> bakedTopLevelModels;
    private final Map<ResourceLocation, Pair<TextureAtlas, TextureAtlas.Preparations>> atlasPreparations;
    private int nextModelGroup;
    private final Object2IntMap<BlockState> modelGroups;
    
    public ModelBakery(final ResourceManager abc, final BlockColors dmn, final ProfilerFiller ami, final int integer) {
        this.loadingStack = Sets.newHashSet();
        this.context = new BlockModelDefinition.Context();
        this.unbakedCache = Maps.newHashMap();
        this.bakedCache = Maps.newHashMap();
        this.topLevelModels = Maps.newHashMap();
        this.bakedTopLevelModels = Maps.newHashMap();
        this.nextModelGroup = 1;
        this.modelGroups = Util.make((Object2IntMap)new Object2IntOpenHashMap(), object2IntOpenHashMap -> object2IntOpenHashMap.defaultReturnValue(-1));
        this.resourceManager = abc;
        this.blockColors = dmn;
        ami.push("missing_model");
        try {
            this.unbakedCache.put(ModelBakery.MISSING_MODEL_LOCATION, this.loadBlockModel(ModelBakery.MISSING_MODEL_LOCATION));
            this.loadTopLevel(ModelBakery.MISSING_MODEL_LOCATION);
        }
        catch (IOException iOException6) {
            ModelBakery.LOGGER.error("Error loading missing model, should never happen :(", (Throwable)iOException6);
            throw new RuntimeException(iOException6);
        }
        ami.popPush("static_definitions");
        ModelBakery.STATIC_DEFINITIONS.forEach((uh, cfk) -> cfk.getPossibleStates().forEach(cfj -> this.loadTopLevel(BlockModelShaper.stateToModelLocation(uh, cfj))));
        ami.popPush("blocks");
        for (final Block bvr7 : Registry.BLOCK) {
            bvr7.getStateDefinition().getPossibleStates().forEach(cfj -> this.loadTopLevel(BlockModelShaper.stateToModelLocation(cfj)));
        }
        ami.popPush("items");
        for (final ResourceLocation uh2 : Registry.ITEM.keySet()) {
            this.loadTopLevel(new ModelResourceLocation(uh2, "inventory"));
        }
        ami.popPush("special");
        this.loadTopLevel(new ModelResourceLocation("minecraft:trident_in_hand#inventory"));
        ami.popPush("textures");
        final Set<Pair<String, String>> set6 = Sets.newLinkedHashSet();
        final Set<Material> set7 = this.topLevelModels.values().stream().flatMap(enr -> enr.getMaterials(this::getModel, set6).stream()).collect(Collectors.toSet());
        set7.addAll(ModelBakery.UNREFERENCED_TEXTURES);
        set6.stream().filter(pair -> !((String)pair.getSecond()).equals(ModelBakery.MISSING_MODEL_LOCATION_STRING)).forEach(pair -> ModelBakery.LOGGER.warn("Unable to resolve texture reference: {} in {}", pair.getFirst(), pair.getSecond()));
        final Map<ResourceLocation, List<Material>> map8 = set7.stream().collect(Collectors.groupingBy(Material::atlasLocation));
        ami.popPush("stitching");
        this.atlasPreparations = Maps.newHashMap();
        for (final Map.Entry<ResourceLocation, List<Material>> entry10 : map8.entrySet()) {
            final TextureAtlas elu11 = new TextureAtlas(entry10.getKey());
            final TextureAtlas.Preparations a12 = elu11.prepareToStitch(this.resourceManager, entry10.getValue().stream().<ResourceLocation>map(Material::texture), ami, integer);
            this.atlasPreparations.put(entry10.getKey(), (Pair<TextureAtlas, TextureAtlas.Preparations>)Pair.of(elu11, a12));
        }
        ami.pop();
    }
    
    public AtlasSet uploadTextures(final TextureManager elw, final ProfilerFiller ami) {
        ami.push("atlas");
        for (final Pair<TextureAtlas, TextureAtlas.Preparations> pair5 : this.atlasPreparations.values()) {
            final TextureAtlas elu6 = (TextureAtlas)pair5.getFirst();
            final TextureAtlas.Preparations a7 = (TextureAtlas.Preparations)pair5.getSecond();
            elu6.reload(a7);
            elw.register(elu6.location(), elu6);
            elw.bind(elu6.location());
            elu6.updateFilter(a7);
        }
        this.atlasSet = new AtlasSet(this.atlasPreparations.values().stream().map(Pair::getFirst).collect(Collectors.toList()));
        ami.popPush("baking");
        BakedModel enh3;
        this.topLevelModels.keySet().forEach(uh -> {
            enh3 = null;
            try {
                enh3 = this.bake(uh, BlockModelRotation.X0_Y0);
            }
            catch (Exception exception4) {
                ModelBakery.LOGGER.warn("Unable to bake model: '{}': {}", uh, exception4);
            }
            if (enh3 != null) {
                this.bakedTopLevelModels.put(uh, enh3);
            }
            return;
        });
        ami.pop();
        return this.atlasSet;
    }
    
    private static Predicate<BlockState> predicate(final StateDefinition<Block, BlockState> cfk, final String string) {
        final Map<Property<?>, Comparable<?>> map3 = Maps.newHashMap();
        for (final String string2 : ModelBakery.COMMA_SPLITTER.split(string)) {
            final Iterator<String> iterator6 = ModelBakery.EQUAL_SPLITTER.split(string2).iterator();
            if (iterator6.hasNext()) {
                final String string3 = iterator6.next();
                final Property<?> cgl8 = cfk.getProperty(string3);
                if (cgl8 != null && iterator6.hasNext()) {
                    final String string4 = iterator6.next();
                    final Comparable<?> comparable10 = ModelBakery.<Comparable<?>>getValueHelper(cgl8, string4);
                    if (comparable10 == null) {
                        throw new RuntimeException("Unknown value: '" + string4 + "' for blockstate property: '" + string3 + "' " + cgl8.getPossibleValues());
                    }
                    map3.put(cgl8, comparable10);
                }
                else {
                    if (!string3.isEmpty()) {
                        throw new RuntimeException("Unknown blockstate property: '" + string3 + "'");
                    }
                    continue;
                }
            }
        }
        final Block bvr4 = cfk.getOwner();
        final Block block;
        final Map<Property<?>, Comparable<?>> map4;
        final Iterator<Map.Entry<Property<?>, Comparable<?>>> iterator8;
        Map.Entry<Property<?>, Comparable<?>> entry5;
        return cfj -> {
            if (cfj == null || block != cfj.getBlock()) {
                return false;
            }
            else {
                map4.entrySet().iterator();
                while (iterator8.hasNext()) {
                    entry5 = iterator8.next();
                    if (!Objects.equals(cfj.getValue(entry5.getKey()), entry5.getValue())) {
                        return false;
                    }
                }
                return true;
            }
        };
    }
    
    @Nullable
    static <T extends Comparable<T>> T getValueHelper(final Property<T> cgl, final String string) {
        return cgl.getValue(string).orElse(null);
    }
    
    public UnbakedModel getModel(final ResourceLocation uh) {
        if (this.unbakedCache.containsKey(uh)) {
            return this.unbakedCache.get(uh);
        }
        if (this.loadingStack.contains(uh)) {
            throw new IllegalStateException("Circular reference while loading " + uh);
        }
        this.loadingStack.add(uh);
        final UnbakedModel enr3 = this.unbakedCache.get(ModelBakery.MISSING_MODEL_LOCATION);
        while (!this.loadingStack.isEmpty()) {
            final ResourceLocation uh2 = this.loadingStack.iterator().next();
            try {
                if (!this.unbakedCache.containsKey(uh2)) {
                    this.loadModel(uh2);
                }
            }
            catch (BlockStateDefinitionException a5) {
                ModelBakery.LOGGER.warn(a5.getMessage());
                this.unbakedCache.put(uh2, enr3);
            }
            catch (Exception exception5) {
                ModelBakery.LOGGER.warn("Unable to load model: '{}' referenced from: {}: {}", uh2, uh, exception5);
                this.unbakedCache.put(uh2, enr3);
            }
            finally {
                this.loadingStack.remove(uh2);
            }
        }
        return this.unbakedCache.getOrDefault(uh, enr3);
    }
    
    private void loadModel(final ResourceLocation uh) throws Exception {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     1: instanceof      Lnet/minecraft/client/resources/model/ModelResourceLocation;
        //     4: ifne            18
        //     7: aload_0         /* this */
        //     8: aload_1         /* uh */
        //     9: aload_0         /* this */
        //    10: aload_1         /* uh */
        //    11: invokespecial   net/minecraft/client/resources/model/ModelBakery.loadBlockModel:(Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/renderer/block/model/BlockModel;
        //    14: invokespecial   net/minecraft/client/resources/model/ModelBakery.cacheAndQueueDependencies:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/client/resources/model/UnbakedModel;)V
        //    17: return         
        //    18: aload_1         /* uh */
        //    19: checkcast       Lnet/minecraft/client/resources/model/ModelResourceLocation;
        //    22: astore_2        /* enn3 */
        //    23: aload_2         /* enn3 */
        //    24: invokevirtual   net/minecraft/client/resources/model/ModelResourceLocation.getVariant:()Ljava/lang/String;
        //    27: ldc_w           "inventory"
        //    30: invokestatic    java/util/Objects.equals:(Ljava/lang/Object;Ljava/lang/Object;)Z
        //    33: ifeq            101
        //    36: new             Lnet/minecraft/resources/ResourceLocation;
        //    39: dup            
        //    40: aload_1         /* uh */
        //    41: invokevirtual   net/minecraft/resources/ResourceLocation.getNamespace:()Ljava/lang/String;
        //    44: new             Ljava/lang/StringBuilder;
        //    47: dup            
        //    48: invokespecial   java/lang/StringBuilder.<init>:()V
        //    51: ldc_w           "item/"
        //    54: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //    57: aload_1         /* uh */
        //    58: invokevirtual   net/minecraft/resources/ResourceLocation.getPath:()Ljava/lang/String;
        //    61: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //    64: invokevirtual   java/lang/StringBuilder.toString:()Ljava/lang/String;
        //    67: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;Ljava/lang/String;)V
        //    70: astore_3        /* uh4 */
        //    71: aload_0         /* this */
        //    72: aload_3         /* uh4 */
        //    73: invokespecial   net/minecraft/client/resources/model/ModelBakery.loadBlockModel:(Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/renderer/block/model/BlockModel;
        //    76: astore          ecy5
        //    78: aload_0         /* this */
        //    79: aload_2         /* enn3 */
        //    80: aload           ecy5
        //    82: invokespecial   net/minecraft/client/resources/model/ModelBakery.cacheAndQueueDependencies:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/client/resources/model/UnbakedModel;)V
        //    85: aload_0         /* this */
        //    86: getfield        net/minecraft/client/resources/model/ModelBakery.unbakedCache:Ljava/util/Map;
        //    89: aload_3         /* uh4 */
        //    90: aload           ecy5
        //    92: invokeinterface java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
        //    97: pop            
        //    98: goto            641
        //   101: new             Lnet/minecraft/resources/ResourceLocation;
        //   104: dup            
        //   105: aload_1         /* uh */
        //   106: invokevirtual   net/minecraft/resources/ResourceLocation.getNamespace:()Ljava/lang/String;
        //   109: aload_1         /* uh */
        //   110: invokevirtual   net/minecraft/resources/ResourceLocation.getPath:()Ljava/lang/String;
        //   113: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;Ljava/lang/String;)V
        //   116: astore_3        /* uh4 */
        //   117: getstatic       net/minecraft/client/resources/model/ModelBakery.STATIC_DEFINITIONS:Ljava/util/Map;
        //   120: aload_3         /* uh4 */
        //   121: invokeinterface java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
        //   126: invokestatic    java/util/Optional.ofNullable:(Ljava/lang/Object;)Ljava/util/Optional;
        //   129: aload_3         /* uh4 */
        //   130: invokedynamic   BootstrapMethod #11, get:(Lnet/minecraft/resources/ResourceLocation;)Ljava/util/function/Supplier;
        //   135: invokevirtual   java/util/Optional.orElseGet:(Ljava/util/function/Supplier;)Ljava/lang/Object;
        //   138: checkcast       Lnet/minecraft/world/level/block/state/StateDefinition;
        //   141: astore          cfk5
        //   143: aload_0         /* this */
        //   144: getfield        net/minecraft/client/resources/model/ModelBakery.context:Lnet/minecraft/client/renderer/block/model/BlockModelDefinition$Context;
        //   147: aload           cfk5
        //   149: invokevirtual   net/minecraft/client/renderer/block/model/BlockModelDefinition$Context.setDefinition:(Lnet/minecraft/world/level/block/state/StateDefinition;)V
        //   152: aload_0         /* this */
        //   153: getfield        net/minecraft/client/resources/model/ModelBakery.blockColors:Lnet/minecraft/client/color/block/BlockColors;
        //   156: aload           cfk5
        //   158: invokevirtual   net/minecraft/world/level/block/state/StateDefinition.getOwner:()Ljava/lang/Object;
        //   161: checkcast       Lnet/minecraft/world/level/block/Block;
        //   164: invokevirtual   net/minecraft/client/color/block/BlockColors.getColoringProperties:(Lnet/minecraft/world/level/block/Block;)Ljava/util/Set;
        //   167: invokestatic    com/google/common/collect/ImmutableList.copyOf:(Ljava/util/Collection;)Lcom/google/common/collect/ImmutableList;
        //   170: astore          list6
        //   172: aload           cfk5
        //   174: invokevirtual   net/minecraft/world/level/block/state/StateDefinition.getPossibleStates:()Lcom/google/common/collect/ImmutableList;
        //   177: astore          immutableList7
        //   179: invokestatic    com/google/common/collect/Maps.newHashMap:()Ljava/util/HashMap;
        //   182: astore          map8
        //   184: aload           immutableList7
        //   186: aload           map8
        //   188: aload_3         /* uh4 */
        //   189: invokedynamic   BootstrapMethod #12, accept:(Ljava/util/Map;Lnet/minecraft/resources/ResourceLocation;)Ljava/util/function/Consumer;
        //   194: invokevirtual   com/google/common/collect/ImmutableList.forEach:(Ljava/util/function/Consumer;)V
        //   197: invokestatic    com/google/common/collect/Maps.newHashMap:()Ljava/util/HashMap;
        //   200: astore          map9
        //   202: new             Lnet/minecraft/resources/ResourceLocation;
        //   205: dup            
        //   206: aload_1         /* uh */
        //   207: invokevirtual   net/minecraft/resources/ResourceLocation.getNamespace:()Ljava/lang/String;
        //   210: new             Ljava/lang/StringBuilder;
        //   213: dup            
        //   214: invokespecial   java/lang/StringBuilder.<init>:()V
        //   217: ldc_w           "blockstates/"
        //   220: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   223: aload_1         /* uh */
        //   224: invokevirtual   net/minecraft/resources/ResourceLocation.getPath:()Ljava/lang/String;
        //   227: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   230: ldc_w           ".json"
        //   233: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   236: invokevirtual   java/lang/StringBuilder.toString:()Ljava/lang/String;
        //   239: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;Ljava/lang/String;)V
        //   242: astore          uh10
        //   244: aload_0         /* this */
        //   245: getfield        net/minecraft/client/resources/model/ModelBakery.unbakedCache:Ljava/util/Map;
        //   248: getstatic       net/minecraft/client/resources/model/ModelBakery.MISSING_MODEL_LOCATION:Lnet/minecraft/client/resources/model/ModelResourceLocation;
        //   251: invokeinterface java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
        //   256: checkcast       Lnet/minecraft/client/resources/model/UnbakedModel;
        //   259: astore          enr11
        //   261: new             Lnet/minecraft/client/resources/model/ModelBakery$ModelGroupKey;
        //   264: dup            
        //   265: aload           enr11
        //   267: invokestatic    com/google/common/collect/ImmutableList.of:(Ljava/lang/Object;)Lcom/google/common/collect/ImmutableList;
        //   270: invokestatic    com/google/common/collect/ImmutableList.of:()Lcom/google/common/collect/ImmutableList;
        //   273: invokespecial   net/minecraft/client/resources/model/ModelBakery$ModelGroupKey.<init>:(Ljava/util/List;Ljava/util/List;)V
        //   276: astore          b12
        //   278: aload           enr11
        //   280: aload           b12
        //   282: invokedynamic   BootstrapMethod #13, get:(Lnet/minecraft/client/resources/model/ModelBakery$ModelGroupKey;)Ljava/util/function/Supplier;
        //   287: invokestatic    com/mojang/datafixers/util/Pair.of:(Ljava/lang/Object;Ljava/lang/Object;)Lcom/mojang/datafixers/util/Pair;
        //   290: astore          pair13
        //   292: aload_0         /* this */
        //   293: getfield        net/minecraft/client/resources/model/ModelBakery.resourceManager:Lnet/minecraft/server/packs/resources/ResourceManager;
        //   296: aload           uh10
        //   298: invokeinterface net/minecraft/server/packs/resources/ResourceManager.getResources:(Lnet/minecraft/resources/ResourceLocation;)Ljava/util/List;
        //   303: invokeinterface java/util/List.stream:()Ljava/util/stream/Stream;
        //   308: aload_0         /* this */
        //   309: invokedynamic   BootstrapMethod #14, apply:(Lnet/minecraft/client/resources/model/ModelBakery;)Ljava/util/function/Function;
        //   314: invokeinterface java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
        //   319: invokestatic    java/util/stream/Collectors.toList:()Ljava/util/stream/Collector;
        //   322: invokeinterface java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
        //   327: checkcast       Ljava/util/List;
        //   330: astore          list14
        //   332: goto            392
        //   335: astore          iOException15
        //   337: getstatic       net/minecraft/client/resources/model/ModelBakery.LOGGER:Lorg/apache/logging/log4j/Logger;
        //   340: ldc_w           "Exception loading blockstate definition: {}: {}"
        //   343: aload           uh10
        //   345: aload           iOException15
        //   347: invokeinterface org/apache/logging/log4j/Logger.warn:(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
        //   352: invokestatic    com/google/common/collect/Maps.newHashMap:()Ljava/util/HashMap;
        //   355: astore          map16
        //   357: aload           map8
        //   359: aload_0         /* this */
        //   360: aload           map9
        //   362: aload           uh10
        //   364: aload           pair13
        //   366: aload           map16
        //   368: invokedynamic   BootstrapMethod #15, accept:(Lnet/minecraft/client/resources/model/ModelBakery;Ljava/util/Map;Lnet/minecraft/resources/ResourceLocation;Lcom/mojang/datafixers/util/Pair;Ljava/util/Map;)Ljava/util/function/BiConsumer;
        //   373: invokeinterface java/util/Map.forEach:(Ljava/util/function/BiConsumer;)V
        //   378: aload           map16
        //   380: aload_0         /* this */
        //   381: invokedynamic   BootstrapMethod #16, accept:(Lnet/minecraft/client/resources/model/ModelBakery;)Ljava/util/function/BiConsumer;
        //   386: invokeinterface java/util/Map.forEach:(Ljava/util/function/BiConsumer;)V
        //   391: return         
        //   392: aload           list14
        //   394: invokeinterface java/util/List.iterator:()Ljava/util/Iterator;
        //   399: astore          14
        //   401: aload           14
        //   403: invokeinterface java/util/Iterator.hasNext:()Z
        //   408: ifeq            520
        //   411: aload           14
        //   413: invokeinterface java/util/Iterator.next:()Ljava/lang/Object;
        //   418: checkcast       Lcom/mojang/datafixers/util/Pair;
        //   421: astore          pair16
        //   423: aload           pair16
        //   425: invokevirtual   com/mojang/datafixers/util/Pair.getSecond:()Ljava/lang/Object;
        //   428: checkcast       Lnet/minecraft/client/renderer/block/model/BlockModelDefinition;
        //   431: astore          ecz17
        //   433: invokestatic    com/google/common/collect/Maps.newIdentityHashMap:()Ljava/util/IdentityHashMap;
        //   436: astore          map18
        //   438: aload           ecz17
        //   440: invokevirtual   net/minecraft/client/renderer/block/model/BlockModelDefinition.isMultiPart:()Z
        //   443: ifeq            472
        //   446: aload           ecz17
        //   448: invokevirtual   net/minecraft/client/renderer/block/model/BlockModelDefinition.getMultiPart:()Lnet/minecraft/client/renderer/block/model/multipart/MultiPart;
        //   451: astore          edl19
        //   453: aload           immutableList7
        //   455: aload           map18
        //   457: aload           edl19
        //   459: aload           list6
        //   461: invokedynamic   BootstrapMethod #17, accept:(Ljava/util/Map;Lnet/minecraft/client/renderer/block/model/multipart/MultiPart;Ljava/util/List;)Ljava/util/function/Consumer;
        //   466: invokevirtual   com/google/common/collect/ImmutableList.forEach:(Ljava/util/function/Consumer;)V
        //   469: goto            475
        //   472: aconst_null    
        //   473: astore          edl19
        //   475: aload           ecz17
        //   477: invokevirtual   net/minecraft/client/renderer/block/model/BlockModelDefinition.getVariants:()Ljava/util/Map;
        //   480: aload           immutableList7
        //   482: aload           cfk5
        //   484: aload           map18
        //   486: aload           list6
        //   488: aload           edl19
        //   490: aload           pair13
        //   492: aload           ecz17
        //   494: aload           uh10
        //   496: aload           pair16
        //   498: invokedynamic   BootstrapMethod #18, accept:(Lcom/google/common/collect/ImmutableList;Lnet/minecraft/world/level/block/state/StateDefinition;Ljava/util/Map;Ljava/util/List;Lnet/minecraft/client/renderer/block/model/multipart/MultiPart;Lcom/mojang/datafixers/util/Pair;Lnet/minecraft/client/renderer/block/model/BlockModelDefinition;Lnet/minecraft/resources/ResourceLocation;Lcom/mojang/datafixers/util/Pair;)Ljava/util/function/BiConsumer;
        //   503: invokeinterface java/util/Map.forEach:(Ljava/util/function/BiConsumer;)V
        //   508: aload           map9
        //   510: aload           map18
        //   512: invokeinterface java/util/Map.putAll:(Ljava/util/Map;)V
        //   517: goto            401
        //   520: invokestatic    com/google/common/collect/Maps.newHashMap:()Ljava/util/HashMap;
        //   523: astore          map14
        //   525: aload           map8
        //   527: aload_0         /* this */
        //   528: aload           map9
        //   530: aload           uh10
        //   532: aload           pair13
        //   534: aload           map14
        //   536: invokedynamic   BootstrapMethod #15, accept:(Lnet/minecraft/client/resources/model/ModelBakery;Ljava/util/Map;Lnet/minecraft/resources/ResourceLocation;Lcom/mojang/datafixers/util/Pair;Ljava/util/Map;)Ljava/util/function/BiConsumer;
        //   541: invokeinterface java/util/Map.forEach:(Ljava/util/function/BiConsumer;)V
        //   546: aload           map14
        //   548: aload_0         /* this */
        //   549: invokedynamic   BootstrapMethod #16, accept:(Lnet/minecraft/client/resources/model/ModelBakery;)Ljava/util/function/BiConsumer;
        //   554: invokeinterface java/util/Map.forEach:(Ljava/util/function/BiConsumer;)V
        //   559: goto            641
        //   562: astore          a14
        //   564: aload           a14
        //   566: athrow         
        //   567: astore          exception14
        //   569: new             Lnet/minecraft/client/resources/model/ModelBakery$BlockStateDefinitionException;
        //   572: dup            
        //   573: ldc_w           "Exception loading blockstate definition: '%s': %s"
        //   576: iconst_2       
        //   577: anewarray       Ljava/lang/Object;
        //   580: dup            
        //   581: iconst_0       
        //   582: aload           uh10
        //   584: aastore        
        //   585: dup            
        //   586: iconst_1       
        //   587: aload           exception14
        //   589: aastore        
        //   590: invokestatic    java/lang/String.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
        //   593: invokespecial   net/minecraft/client/resources/model/ModelBakery$BlockStateDefinitionException.<init>:(Ljava/lang/String;)V
        //   596: athrow         
        //   597: astore          19
        //   599: invokestatic    com/google/common/collect/Maps.newHashMap:()Ljava/util/HashMap;
        //   602: astore          map21
        //   604: aload           map8
        //   606: aload_0         /* this */
        //   607: aload           map9
        //   609: aload           uh10
        //   611: aload           pair13
        //   613: aload           map21
        //   615: invokedynamic   BootstrapMethod #15, accept:(Lnet/minecraft/client/resources/model/ModelBakery;Ljava/util/Map;Lnet/minecraft/resources/ResourceLocation;Lcom/mojang/datafixers/util/Pair;Ljava/util/Map;)Ljava/util/function/BiConsumer;
        //   620: invokeinterface java/util/Map.forEach:(Ljava/util/function/BiConsumer;)V
        //   625: aload           map21
        //   627: aload_0         /* this */
        //   628: invokedynamic   BootstrapMethod #16, accept:(Lnet/minecraft/client/resources/model/ModelBakery;)Ljava/util/function/BiConsumer;
        //   633: invokeinterface java/util/Map.forEach:(Ljava/util/function/BiConsumer;)V
        //   638: aload           19
        //   640: athrow         
        //   641: return         
        //    Exceptions:
        //  throws java.lang.Exception
        //    MethodParameters:
        //  Name  Flags  
        //  ----  -----
        //  uh    
        //    StackMapTable: 00 0C 12 FB 00 52 FF 00 E9 00 0D 07 00 02 00 00 00 00 00 00 07 02 22 07 02 22 07 01 2D 00 00 07 01 B7 00 01 07 00 72 FF 00 38 00 0E 07 00 02 00 00 00 07 00 1E 07 01 1C 07 01 1C 07 02 22 07 02 22 07 01 2D 00 00 07 01 B7 07 01 A8 00 00 FF 00 08 00 0F 07 00 02 00 00 00 07 00 1E 07 01 1C 07 01 1C 07 02 22 07 02 22 07 01 2D 00 00 07 01 B7 00 07 00 FF 00 00 FE 00 46 07 01 B7 07 00 0F 07 03 3F FC 00 02 07 03 41 FF 00 2C 00 0D 07 00 02 00 00 00 00 00 00 07 02 22 07 02 22 07 01 2D 00 00 07 01 B7 00 00 69 07 00 0A 44 07 02 7D 5D 07 02 A4 FF 00 2B 00 00 00 00
        //    Exceptions:
        //  Try           Handler
        //  Start  End    Start  End    Type                                                                            
        //  -----  -----  -----  -----  --------------------------------------------------------------------------------
        //  292    332    335    392    Ljava/io/IOException;
        //  292    352    562    567    Lnet/minecraft/client/resources/model/ModelBakery$BlockStateDefinitionException;
        //  392    520    562    567    Lnet/minecraft/client/resources/model/ModelBakery$BlockStateDefinitionException;
        //  292    352    567    597    Ljava/lang/Exception;
        //  392    520    567    597    Ljava/lang/Exception;
        //  292    352    597    641    Any
        //  392    520    597    641    Any
        //  562    599    597    641    Any
        // 
        // The error that occurred was:
        // 
        // java.lang.IllegalStateException: Could not infer any expression.
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:374)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:96)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:214)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:99)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:782)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:675)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:552)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:519)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:161)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:150)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:125)
        //     at cuchaz.enigma.SourceProvider.getSources(SourceProvider.java:85)
        //     at cuchaz.enigma.EnigmaProject$JarExport.decompileClass(EnigmaProject.java:241)
        //     at cuchaz.enigma.EnigmaProject$JarExport.lambda$decompile$1(EnigmaProject.java:230)
        //     at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
        //     at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
        //     at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        //     at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        //     at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:952)
        //     at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:926)
        //     at java.base/java.util.stream.AbstractTask.compute(AbstractTask.java:327)
        //     at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
        //     at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        //     at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        //     at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        //     at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        //     at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
    
    private void cacheAndQueueDependencies(final ResourceLocation uh, final UnbakedModel enr) {
        this.unbakedCache.put(uh, enr);
        this.loadingStack.addAll(enr.getDependencies());
    }
    
    private void loadTopLevel(final ModelResourceLocation enn) {
        final UnbakedModel enr3 = this.getModel(enn);
        this.unbakedCache.put(enn, enr3);
        this.topLevelModels.put(enn, enr3);
    }
    
    private void registerModelGroup(final Iterable<BlockState> iterable) {
        final int integer3 = this.nextModelGroup++;
        iterable.forEach(cfj -> this.modelGroups.put(cfj, integer3));
    }
    
    @Nullable
    public BakedModel bake(final ResourceLocation uh, final ModelState eno) {
        final Triple<ResourceLocation, Transformation, Boolean> triple4 = (Triple<ResourceLocation, Transformation, Boolean>)Triple.of(uh, eno.getRotation(), eno.isUvLocked());
        if (this.bakedCache.containsKey(triple4)) {
            return this.bakedCache.get(triple4);
        }
        if (this.atlasSet == null) {
            throw new IllegalStateException("bake called too early");
        }
        final UnbakedModel enr5 = this.getModel(uh);
        if (enr5 instanceof BlockModel) {
            final BlockModel ecy6 = (BlockModel)enr5;
            if (ecy6.getRootModel() == ModelBakery.GENERATION_MARKER) {
                return ModelBakery.ITEM_MODEL_GENERATOR.generateBlockModel(this.atlasSet::getSprite, ecy6).bake(this, ecy6, this.atlasSet::getSprite, eno, uh, false);
            }
        }
        final BakedModel enh6 = enr5.bake(this, this.atlasSet::getSprite, eno, uh);
        this.bakedCache.put(triple4, enh6);
        return enh6;
    }
    
    private BlockModel loadBlockModel(final ResourceLocation uh) throws IOException {
        Reader reader3 = null;
        Resource abb4 = null;
        try {
            final String string5 = uh.getPath();
            if ("builtin/generated".equals(string5)) {
                return ModelBakery.GENERATION_MARKER;
            }
            if ("builtin/entity".equals(string5)) {
                return ModelBakery.BLOCK_ENTITY_MARKER;
            }
            if (string5.startsWith("builtin/")) {
                final String string6 = string5.substring("builtin/".length());
                final String string7 = ModelBakery.BUILTIN_MODELS.get(string6);
                if (string7 == null) {
                    throw new FileNotFoundException(uh.toString());
                }
                reader3 = new StringReader(string7);
            }
            else {
                abb4 = this.resourceManager.getResource(new ResourceLocation(uh.getNamespace(), "models/" + uh.getPath() + ".json"));
                reader3 = new InputStreamReader(abb4.getInputStream(), StandardCharsets.UTF_8);
            }
            final BlockModel ecy6 = BlockModel.fromStream(reader3);
            ecy6.name = uh.toString();
            return ecy6;
        }
        finally {
            IOUtils.closeQuietly(reader3);
            IOUtils.closeQuietly((Closeable)abb4);
        }
    }
    
    public Map<ResourceLocation, BakedModel> getBakedTopLevelModels() {
        return this.bakedTopLevelModels;
    }
    
    public Object2IntMap<BlockState> getModelGroups() {
        return this.modelGroups;
    }
    
    static {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     3: dup            
        //     4: getstatic       net/minecraft/client/renderer/texture/TextureAtlas.LOCATION_BLOCKS:Lnet/minecraft/resources/ResourceLocation;
        //     7: new             Lnet/minecraft/resources/ResourceLocation;
        //    10: dup            
        //    11: ldc_w           "block/fire_0"
        //    14: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;)V
        //    17: invokespecial   net/minecraft/client/resources/model/Material.<init>:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V
        //    20: putstatic       net/minecraft/client/resources/model/ModelBakery.FIRE_0:Lnet/minecraft/client/resources/model/Material;
        //    23: new             Lnet/minecraft/client/resources/model/Material;
        //    26: dup            
        //    27: getstatic       net/minecraft/client/renderer/texture/TextureAtlas.LOCATION_BLOCKS:Lnet/minecraft/resources/ResourceLocation;
        //    30: new             Lnet/minecraft/resources/ResourceLocation;
        //    33: dup            
        //    34: ldc_w           "block/fire_1"
        //    37: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;)V
        //    40: invokespecial   net/minecraft/client/resources/model/Material.<init>:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V
        //    43: putstatic       net/minecraft/client/resources/model/ModelBakery.FIRE_1:Lnet/minecraft/client/resources/model/Material;
        //    46: new             Lnet/minecraft/client/resources/model/Material;
        //    49: dup            
        //    50: getstatic       net/minecraft/client/renderer/texture/TextureAtlas.LOCATION_BLOCKS:Lnet/minecraft/resources/ResourceLocation;
        //    53: new             Lnet/minecraft/resources/ResourceLocation;
        //    56: dup            
        //    57: ldc_w           "block/lava_flow"
        //    60: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;)V
        //    63: invokespecial   net/minecraft/client/resources/model/Material.<init>:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V
        //    66: putstatic       net/minecraft/client/resources/model/ModelBakery.LAVA_FLOW:Lnet/minecraft/client/resources/model/Material;
        //    69: new             Lnet/minecraft/client/resources/model/Material;
        //    72: dup            
        //    73: getstatic       net/minecraft/client/renderer/texture/TextureAtlas.LOCATION_BLOCKS:Lnet/minecraft/resources/ResourceLocation;
        //    76: new             Lnet/minecraft/resources/ResourceLocation;
        //    79: dup            
        //    80: ldc_w           "block/water_flow"
        //    83: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;)V
        //    86: invokespecial   net/minecraft/client/resources/model/Material.<init>:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V
        //    89: putstatic       net/minecraft/client/resources/model/ModelBakery.WATER_FLOW:Lnet/minecraft/client/resources/model/Material;
        //    92: new             Lnet/minecraft/client/resources/model/Material;
        //    95: dup            
        //    96: getstatic       net/minecraft/client/renderer/texture/TextureAtlas.LOCATION_BLOCKS:Lnet/minecraft/resources/ResourceLocation;
        //    99: new             Lnet/minecraft/resources/ResourceLocation;
        //   102: dup            
        //   103: ldc_w           "block/water_overlay"
        //   106: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;)V
        //   109: invokespecial   net/minecraft/client/resources/model/Material.<init>:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V
        //   112: putstatic       net/minecraft/client/resources/model/ModelBakery.WATER_OVERLAY:Lnet/minecraft/client/resources/model/Material;
        //   115: new             Lnet/minecraft/client/resources/model/Material;
        //   118: dup            
        //   119: getstatic       net/minecraft/client/renderer/texture/TextureAtlas.LOCATION_BLOCKS:Lnet/minecraft/resources/ResourceLocation;
        //   122: new             Lnet/minecraft/resources/ResourceLocation;
        //   125: dup            
        //   126: ldc_w           "entity/banner_base"
        //   129: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;)V
        //   132: invokespecial   net/minecraft/client/resources/model/Material.<init>:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V
        //   135: putstatic       net/minecraft/client/resources/model/ModelBakery.BANNER_BASE:Lnet/minecraft/client/resources/model/Material;
        //   138: new             Lnet/minecraft/client/resources/model/Material;
        //   141: dup            
        //   142: getstatic       net/minecraft/client/renderer/texture/TextureAtlas.LOCATION_BLOCKS:Lnet/minecraft/resources/ResourceLocation;
        //   145: new             Lnet/minecraft/resources/ResourceLocation;
        //   148: dup            
        //   149: ldc_w           "entity/shield_base"
        //   152: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;)V
        //   155: invokespecial   net/minecraft/client/resources/model/Material.<init>:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V
        //   158: putstatic       net/minecraft/client/resources/model/ModelBakery.SHIELD_BASE:Lnet/minecraft/client/resources/model/Material;
        //   161: new             Lnet/minecraft/client/resources/model/Material;
        //   164: dup            
        //   165: getstatic       net/minecraft/client/renderer/texture/TextureAtlas.LOCATION_BLOCKS:Lnet/minecraft/resources/ResourceLocation;
        //   168: new             Lnet/minecraft/resources/ResourceLocation;
        //   171: dup            
        //   172: ldc_w           "entity/shield_base_nopattern"
        //   175: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;)V
        //   178: invokespecial   net/minecraft/client/resources/model/Material.<init>:(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V
        //   181: putstatic       net/minecraft/client/resources/model/ModelBakery.NO_PATTERN_SHIELD:Lnet/minecraft/client/resources/model/Material;
        //   184: iconst_0       
        //   185: bipush          10
        //   187: invokestatic    java/util/stream/IntStream.range:(II)Ljava/util/stream/IntStream;
        //   190: invokedynamic   BootstrapMethod #29, apply:()Ljava/util/function/IntFunction;
        //   195: invokeinterface java/util/stream/IntStream.mapToObj:(Ljava/util/function/IntFunction;)Ljava/util/stream/Stream;
        //   200: invokestatic    java/util/stream/Collectors.toList:()Ljava/util/stream/Collector;
        //   203: invokeinterface java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
        //   208: checkcast       Ljava/util/List;
        //   211: putstatic       net/minecraft/client/resources/model/ModelBakery.DESTROY_STAGES:Ljava/util/List;
        //   214: getstatic       net/minecraft/client/resources/model/ModelBakery.DESTROY_STAGES:Ljava/util/List;
        //   217: invokeinterface java/util/List.stream:()Ljava/util/stream/Stream;
        //   222: invokedynamic   BootstrapMethod #30, apply:()Ljava/util/function/Function;
        //   227: invokeinterface java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
        //   232: invokestatic    java/util/stream/Collectors.toList:()Ljava/util/stream/Collector;
        //   235: invokeinterface java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
        //   240: checkcast       Ljava/util/List;
        //   243: putstatic       net/minecraft/client/resources/model/ModelBakery.BREAKING_LOCATIONS:Ljava/util/List;
        //   246: getstatic       net/minecraft/client/resources/model/ModelBakery.BREAKING_LOCATIONS:Ljava/util/List;
        //   249: invokeinterface java/util/List.stream:()Ljava/util/stream/Stream;
        //   254: invokedynamic   BootstrapMethod #31, apply:()Ljava/util/function/Function;
        //   259: invokeinterface java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
        //   264: invokestatic    java/util/stream/Collectors.toList:()Ljava/util/stream/Collector;
        //   267: invokeinterface java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
        //   272: checkcast       Ljava/util/List;
        //   275: putstatic       net/minecraft/client/resources/model/ModelBakery.DESTROY_TYPES:Ljava/util/List;
        //   278: invokestatic    com/google/common/collect/Sets.newHashSet:()Ljava/util/HashSet;
        //   281: invokedynamic   BootstrapMethod #32, accept:()Ljava/util/function/Consumer;
        //   286: invokestatic    net/minecraft/Util.make:(Ljava/lang/Object;Ljava/util/function/Consumer;)Ljava/lang/Object;
        //   289: checkcast       Ljava/util/Set;
        //   292: putstatic       net/minecraft/client/resources/model/ModelBakery.UNREFERENCED_TEXTURES:Ljava/util/Set;
        //   295: invokestatic    org/apache/logging/log4j/LogManager.getLogger:()Lorg/apache/logging/log4j/Logger;
        //   298: putstatic       net/minecraft/client/resources/model/ModelBakery.LOGGER:Lorg/apache/logging/log4j/Logger;
        //   301: new             Lnet/minecraft/client/resources/model/ModelResourceLocation;
        //   304: dup            
        //   305: ldc_w           "builtin/missing"
        //   308: ldc_w           "missing"
        //   311: invokespecial   net/minecraft/client/resources/model/ModelResourceLocation.<init>:(Ljava/lang/String;Ljava/lang/String;)V
        //   314: putstatic       net/minecraft/client/resources/model/ModelBakery.MISSING_MODEL_LOCATION:Lnet/minecraft/client/resources/model/ModelResourceLocation;
        //   317: getstatic       net/minecraft/client/resources/model/ModelBakery.MISSING_MODEL_LOCATION:Lnet/minecraft/client/resources/model/ModelResourceLocation;
        //   320: invokevirtual   net/minecraft/client/resources/model/ModelResourceLocation.toString:()Ljava/lang/String;
        //   323: putstatic       net/minecraft/client/resources/model/ModelBakery.MISSING_MODEL_LOCATION_STRING:Ljava/lang/String;
        //   326: new             Ljava/lang/StringBuilder;
        //   329: dup            
        //   330: invokespecial   java/lang/StringBuilder.<init>:()V
        //   333: ldc_w           "{    'textures': {       'particle': '"
        //   336: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   339: invokestatic    net/minecraft/client/renderer/texture/MissingTextureAtlasSprite.getLocation:()Lnet/minecraft/resources/ResourceLocation;
        //   342: invokevirtual   net/minecraft/resources/ResourceLocation.getPath:()Ljava/lang/String;
        //   345: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   348: ldc_w           "',       'missingno': '"
        //   351: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   354: invokestatic    net/minecraft/client/renderer/texture/MissingTextureAtlasSprite.getLocation:()Lnet/minecraft/resources/ResourceLocation;
        //   357: invokevirtual   net/minecraft/resources/ResourceLocation.getPath:()Ljava/lang/String;
        //   360: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   363: ldc_w           "'    },    'elements': [         {  'from': [ 0, 0, 0 ],            'to': [ 16, 16, 16 ],            'faces': {                'down':  { 'uv': [ 0, 0, 16, 16 ], 'cullface': 'down',  'texture': '#missingno' },                'up':    { 'uv': [ 0, 0, 16, 16 ], 'cullface': 'up',    'texture': '#missingno' },                'north': { 'uv': [ 0, 0, 16, 16 ], 'cullface': 'north', 'texture': '#missingno' },                'south': { 'uv': [ 0, 0, 16, 16 ], 'cullface': 'south', 'texture': '#missingno' },                'west':  { 'uv': [ 0, 0, 16, 16 ], 'cullface': 'west',  'texture': '#missingno' },                'east':  { 'uv': [ 0, 0, 16, 16 ], 'cullface': 'east',  'texture': '#missingno' }            }        }    ]}"
        //   366: invokevirtual   java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        //   369: invokevirtual   java/lang/StringBuilder.toString:()Ljava/lang/String;
        //   372: bipush          39
        //   374: bipush          34
        //   376: invokevirtual   java/lang/String.replace:(CC)Ljava/lang/String;
        //   379: putstatic       net/minecraft/client/resources/model/ModelBakery.MISSING_MODEL_MESH:Ljava/lang/String;
        //   382: ldc_w           "missing"
        //   385: getstatic       net/minecraft/client/resources/model/ModelBakery.MISSING_MODEL_MESH:Ljava/lang/String;
        //   388: invokestatic    com/google/common/collect/ImmutableMap.of:(Ljava/lang/Object;Ljava/lang/Object;)Lcom/google/common/collect/ImmutableMap;
        //   391: invokestatic    com/google/common/collect/Maps.newHashMap:(Ljava/util/Map;)Ljava/util/HashMap;
        //   394: putstatic       net/minecraft/client/resources/model/ModelBakery.BUILTIN_MODELS:Ljava/util/Map;
        //   397: bipush          44
        //   399: invokestatic    com/google/common/base/Splitter.on:(C)Lcom/google/common/base/Splitter;
        //   402: putstatic       net/minecraft/client/resources/model/ModelBakery.COMMA_SPLITTER:Lcom/google/common/base/Splitter;
        //   405: bipush          61
        //   407: invokestatic    com/google/common/base/Splitter.on:(C)Lcom/google/common/base/Splitter;
        //   410: iconst_2       
        //   411: invokevirtual   com/google/common/base/Splitter.limit:(I)Lcom/google/common/base/Splitter;
        //   414: putstatic       net/minecraft/client/resources/model/ModelBakery.EQUAL_SPLITTER:Lcom/google/common/base/Splitter;
        //   417: ldc_w           "{\"gui_light\": \"front\"}"
        //   420: invokestatic    net/minecraft/client/renderer/block/model/BlockModel.fromString:(Ljava/lang/String;)Lnet/minecraft/client/renderer/block/model/BlockModel;
        //   423: invokedynamic   BootstrapMethod #33, accept:()Ljava/util/function/Consumer;
        //   428: invokestatic    net/minecraft/Util.make:(Ljava/lang/Object;Ljava/util/function/Consumer;)Ljava/lang/Object;
        //   431: checkcast       Lnet/minecraft/client/renderer/block/model/BlockModel;
        //   434: putstatic       net/minecraft/client/resources/model/ModelBakery.GENERATION_MARKER:Lnet/minecraft/client/renderer/block/model/BlockModel;
        //   437: ldc_w           "{\"gui_light\": \"side\"}"
        //   440: invokestatic    net/minecraft/client/renderer/block/model/BlockModel.fromString:(Ljava/lang/String;)Lnet/minecraft/client/renderer/block/model/BlockModel;
        //   443: invokedynamic   BootstrapMethod #34, accept:()Ljava/util/function/Consumer;
        //   448: invokestatic    net/minecraft/Util.make:(Ljava/lang/Object;Ljava/util/function/Consumer;)Ljava/lang/Object;
        //   451: checkcast       Lnet/minecraft/client/renderer/block/model/BlockModel;
        //   454: putstatic       net/minecraft/client/resources/model/ModelBakery.BLOCK_ENTITY_MARKER:Lnet/minecraft/client/renderer/block/model/BlockModel;
        //   457: new             Lnet/minecraft/world/level/block/state/StateDefinition$Builder;
        //   460: dup            
        //   461: getstatic       net/minecraft/world/level/block/Blocks.AIR:Lnet/minecraft/world/level/block/Block;
        //   464: invokespecial   net/minecraft/world/level/block/state/StateDefinition$Builder.<init>:(Ljava/lang/Object;)V
        //   467: iconst_1       
        //   468: anewarray       Lnet/minecraft/world/level/block/state/properties/Property;
        //   471: dup            
        //   472: iconst_0       
        //   473: ldc_w           "map"
        //   476: invokestatic    net/minecraft/world/level/block/state/properties/BooleanProperty.create:(Ljava/lang/String;)Lnet/minecraft/world/level/block/state/properties/BooleanProperty;
        //   479: aastore        
        //   480: invokevirtual   net/minecraft/world/level/block/state/StateDefinition$Builder.add:([Lnet/minecraft/world/level/block/state/properties/Property;)Lnet/minecraft/world/level/block/state/StateDefinition$Builder;
        //   483: invokedynamic   BootstrapMethod #35, apply:()Ljava/util/function/Function;
        //   488: invokedynamic   BootstrapMethod #36, create:()Lnet/minecraft/world/level/block/state/StateDefinition$Factory;
        //   493: invokevirtual   net/minecraft/world/level/block/state/StateDefinition$Builder.create:(Ljava/util/function/Function;Lnet/minecraft/world/level/block/state/StateDefinition$Factory;)Lnet/minecraft/world/level/block/state/StateDefinition;
        //   496: putstatic       net/minecraft/client/resources/model/ModelBakery.ITEM_FRAME_FAKE_DEFINITION:Lnet/minecraft/world/level/block/state/StateDefinition;
        //   499: new             Lnet/minecraft/client/renderer/block/model/ItemModelGenerator;
        //   502: dup            
        //   503: invokespecial   net/minecraft/client/renderer/block/model/ItemModelGenerator.<init>:()V
        //   506: putstatic       net/minecraft/client/resources/model/ModelBakery.ITEM_MODEL_GENERATOR:Lnet/minecraft/client/renderer/block/model/ItemModelGenerator;
        //   509: new             Lnet/minecraft/resources/ResourceLocation;
        //   512: dup            
        //   513: ldc_w           "item_frame"
        //   516: invokespecial   net/minecraft/resources/ResourceLocation.<init>:(Ljava/lang/String;)V
        //   519: getstatic       net/minecraft/client/resources/model/ModelBakery.ITEM_FRAME_FAKE_DEFINITION:Lnet/minecraft/world/level/block/state/StateDefinition;
        //   522: invokestatic    com/google/common/collect/ImmutableMap.of:(Ljava/lang/Object;Ljava/lang/Object;)Lcom/google/common/collect/ImmutableMap;
        //   525: putstatic       net/minecraft/client/resources/model/ModelBakery.STATIC_DEFINITIONS:Ljava/util/Map;
        //   528: return         
        // 
        // The error that occurred was:
        // 
        // java.lang.UnsupportedOperationException: The requested operation is not supported.
        //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:276)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:271)
        //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:150)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:187)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:39)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:173)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:39)
        //     at com.strobel.assembler.metadata.MetadataHelper.substituteGenericArguments(MetadataHelper.java:1100)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2676)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1029)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:803)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2669)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1029)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:803)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:770)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:766)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1072)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:803)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:672)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:655)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:365)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:96)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:214)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:99)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:782)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:675)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:552)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:519)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:161)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:150)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:125)
        //     at cuchaz.enigma.SourceProvider.getSources(SourceProvider.java:85)
        //     at cuchaz.enigma.EnigmaProject$JarExport.decompileClass(EnigmaProject.java:241)
        //     at cuchaz.enigma.EnigmaProject$JarExport.lambda$decompile$1(EnigmaProject.java:230)
        //     at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
        //     at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
        //     at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        //     at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        //     at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:952)
        //     at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:926)
        //     at java.base/java.util.stream.AbstractTask.compute(AbstractTask.java:327)
        //     at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
        //     at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        //     at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        //     at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        //     at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        //     at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
    
    static class BlockStateDefinitionException extends RuntimeException {
        public BlockStateDefinitionException(final String string) {
            super(string);
        }
    }
    
    static class ModelGroupKey {
        private final List<UnbakedModel> models;
        private final List<Object> coloringValues;
        
        public ModelGroupKey(final List<UnbakedModel> list1, final List<Object> list2) {
            this.models = list1;
            this.coloringValues = list2;
        }
        
        @Override
        public boolean equals(final Object object) {
            if (this == object) {
                return true;
            }
            if (object instanceof ModelGroupKey) {
                final ModelGroupKey b3 = (ModelGroupKey)object;
                return Objects.equals(this.models, b3.models) && Objects.equals(this.coloringValues, b3.coloringValues);
            }
            return false;
        }
        
        @Override
        public int hashCode() {
            return 31 * this.models.hashCode() + this.coloringValues.hashCode();
        }
        
        public static ModelGroupKey create(final BlockState cfj, final MultiPart edl, final Collection<Property<?>> collection) {
            final StateDefinition<Block, BlockState> cfk4 = cfj.getBlock().getStateDefinition();
            final List<UnbakedModel> list5 = edl.getSelectors().stream().filter(edn -> edn.getPredicate(cfk4).test(cfj)).map(Selector::getVariant).collect(ImmutableList.toImmutableList());
            final List<Object> list6 = getColoringValues(cfj, collection);
            return new ModelGroupKey(list5, list6);
        }
        
        public static ModelGroupKey create(final BlockState cfj, final UnbakedModel enr, final Collection<Property<?>> collection) {
            final List<Object> list4 = getColoringValues(cfj, collection);
            return new ModelGroupKey(ImmutableList.<UnbakedModel>of(enr), list4);
        }
        
        private static List<Object> getColoringValues(final BlockState cfj, final Collection<Property<?>> collection) {
            return collection.stream().map(cfj::getValue).collect(ImmutableList.toImmutableList());
        }
    }
}
