// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.npc.entities;

import com.hypixel.hytale.server.core.asset.type.environment.config.Environment;
import com.hypixel.hytale.server.core.asset.type.entityeffect.config.ApplicationEffects;
import com.hypixel.hytale.server.core.asset.type.entityeffect.config.EntityEffect;
import com.hypixel.hytale.server.core.entity.effect.EffectControllerComponent;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.server.npc.role.RoleDebugFlags;
import java.util.EnumSet;
import com.hypixel.hytale.server.spawning.assets.spawns.config.WorldNPCSpawn;
import com.hypixel.hytale.server.npc.components.messaging.NPCEntityEventSupport;
import com.hypixel.hytale.server.npc.components.messaging.PlayerEntityEventSupport;
import com.hypixel.hytale.server.npc.components.messaging.EntityEventSupport;
import com.hypixel.hytale.server.npc.blackboard.view.event.EntityEventNotification;
import com.hypixel.hytale.server.npc.components.messaging.NPCBlockEventSupport;
import com.hypixel.hytale.server.npc.components.messaging.PlayerBlockEventSupport;
import com.hypixel.hytale.server.npc.components.messaging.EventSupport;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.npc.blackboard.view.event.EventNotification;
import java.util.EnumMap;
import com.hypixel.hytale.server.npc.blackboard.Blackboard;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.npc.NPCPlugin;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.protocol.BlockMaterial;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.entity.AnimationUtils;
import java.util.Objects;
import com.hypixel.hytale.server.core.modules.entity.component.ActiveAnimationComponent;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.protocol.AnimationSlot;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.inventory.Inventory;
import com.hypixel.hytale.server.core.universe.world.World;
import java.util.HashSet;
import com.hypixel.hytale.math.random.RandomExtra;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.ComponentType;
import java.util.UUID;
import java.util.Set;
import com.hypixel.hytale.server.npc.storage.AlarmStore;
import com.hypixel.hytale.server.npc.blackboard.view.event.entity.EntityEventType;
import com.hypixel.hytale.server.npc.blackboard.view.event.entity.EntityEventView;
import it.unimi.dsi.fastutil.ints.IntSet;
import com.hypixel.hytale.server.npc.blackboard.view.event.block.BlockEventType;
import java.util.Map;
import com.hypixel.hytale.server.npc.blackboard.view.event.block.BlockEventView;
import it.unimi.dsi.fastutil.ints.IntList;
import com.hypixel.hytale.server.npc.blackboard.view.blocktype.BlockTypeView;
import com.hypixel.hytale.server.npc.util.DamageData;
import javax.annotation.Nonnull;
import java.time.Instant;
import com.hypixel.hytale.math.vector.Vector3d;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.server.core.universe.world.npc.INonPlayerCharacter;
import com.hypixel.hytale.server.core.entity.LivingEntity;

public class NPCEntity extends LivingEntity implements INonPlayerCharacter
{
    public static final BuilderCodec<NPCEntity> CODEC;
    private String roleName;
    private int roleIndex;
    @Nullable
    private Role role;
    private int spawnRoleIndex;
    @Nullable
    private String spawnRoleName;
    @Nullable
    private String spawnConfigurationName;
    private int environmentIndex;
    private int spawnConfigurationIndex;
    private boolean isSpawnTracked;
    private boolean isDespawning;
    private boolean isPlayingDespawnAnim;
    private float despawnRemainingSeconds;
    private float despawnCheckRemainingSeconds;
    private float despawnAnimationRemainingSeconds;
    private float cachedEntityHorizontalSpeedMultiplier;
    private final Vector3d leashPoint;
    private float leashHeading;
    private float leashPitch;
    private boolean hasLeashPosition;
    private float hoverPhase;
    private double hoverHeight;
    private float initialModelScale;
    private Instant spawnInstant;
    @Nonnull
    private PathManager pathManager;
    private final DamageData damageData;
    @Nullable
    private BlockTypeView blackboardBlockTypeView;
    private IntList blackboardBlockTypeSets;
    private BlockEventView blackboardBlockChangeView;
    private Map<BlockEventType, IntSet> blackboardBlockChangeSets;
    private EntityEventView blackboardEntityEventView;
    private Map<EntityEventType, IntSet> blackboardEntityEventSets;
    private AlarmStore alarmStore;
    @Deprecated(forRemoval = true)
    private int worldgenId;
    @Nonnull
    private final Set<UUID> reservedBy;
    private final Vector3d oldPosition;
    
    @Nullable
    public static ComponentType<EntityStore, NPCEntity> getComponentType() {
        return EntityModule.get().getComponentType(NPCEntity.class);
    }
    
    public NPCEntity() {
        this.roleIndex = Integer.MIN_VALUE;
        this.spawnRoleIndex = Integer.MIN_VALUE;
        this.environmentIndex = Integer.MIN_VALUE;
        this.spawnConfigurationIndex = Integer.MIN_VALUE;
        this.despawnCheckRemainingSeconds = RandomExtra.randomRange(1.0f, 5.0f);
        this.cachedEntityHorizontalSpeedMultiplier = Float.MAX_VALUE;
        this.leashPoint = new Vector3d();
        this.initialModelScale = 1.0f;
        this.pathManager = new PathManager();
        this.damageData = new DamageData();
        this.worldgenId = 0;
        this.reservedBy = new HashSet<UUID>();
        this.oldPosition = new Vector3d();
        this.role = null;
    }
    
    public NPCEntity(@Nonnull final World world) {
        super(world);
        this.roleIndex = Integer.MIN_VALUE;
        this.spawnRoleIndex = Integer.MIN_VALUE;
        this.environmentIndex = Integer.MIN_VALUE;
        this.spawnConfigurationIndex = Integer.MIN_VALUE;
        this.despawnCheckRemainingSeconds = RandomExtra.randomRange(1.0f, 5.0f);
        this.cachedEntityHorizontalSpeedMultiplier = Float.MAX_VALUE;
        this.leashPoint = new Vector3d();
        this.initialModelScale = 1.0f;
        this.pathManager = new PathManager();
        this.damageData = new DamageData();
        this.worldgenId = 0;
        this.reservedBy = new HashSet<UUID>();
        this.oldPosition = new Vector3d();
        this.role = null;
    }
    
    @Nonnull
    public AlarmStore getAlarmStore() {
        if (this.alarmStore == null) {
            this.alarmStore = new AlarmStore();
        }
        return this.alarmStore;
    }
    
    @Nonnull
    @Override
    protected Inventory createDefaultInventory() {
        return new Inventory((short)0, Inventory.DEFAULT_ARMOR_CAPACITY, (short)3, (short)0, (short)0);
    }
    
    @Nullable
    public Role getRole() {
        return this.role;
    }
    
    public void invalidateCachedHorizontalSpeedMultiplier() {
        this.cachedEntityHorizontalSpeedMultiplier = Float.MAX_VALUE;
    }
    
    public void storeTickStartPosition(@Nonnull final Vector3d position) {
        this.oldPosition.assign(position);
    }
    
    public boolean tickDespawnAnimationRemainingSeconds(final float dt) {
        final float despawnAnimationRemainingSeconds = this.despawnAnimationRemainingSeconds - dt;
        this.despawnAnimationRemainingSeconds = despawnAnimationRemainingSeconds;
        return despawnAnimationRemainingSeconds <= 0.0f;
    }
    
    public void setDespawnAnimationRemainingSeconds(final float seconds) {
        this.despawnAnimationRemainingSeconds = seconds;
    }
    
    public boolean tickDespawnRemainingSeconds(final float dt) {
        final float despawnRemainingSeconds = this.despawnRemainingSeconds - dt;
        this.despawnRemainingSeconds = despawnRemainingSeconds;
        return despawnRemainingSeconds <= 0.0f;
    }
    
    public void setDespawnRemainingSeconds(final float seconds) {
        this.despawnRemainingSeconds = seconds;
    }
    
    public void setDespawning(final boolean despawning) {
        this.isDespawning = despawning;
    }
    
    public void setPlayingDespawnAnim(final boolean playingDespawnAnim) {
        this.isPlayingDespawnAnim = playingDespawnAnim;
    }
    
    public boolean tickDespawnCheckRemainingSeconds(final float dt) {
        final float despawnCheckRemainingSeconds = this.despawnCheckRemainingSeconds - dt;
        this.despawnCheckRemainingSeconds = despawnCheckRemainingSeconds;
        return despawnCheckRemainingSeconds <= 0.0f;
    }
    
    public void setDespawnCheckRemainingSeconds(final float seconds) {
        this.despawnCheckRemainingSeconds = seconds;
    }
    
    public void setInitialModelScale(final float scale) {
        this.initialModelScale = scale;
    }
    
    public Vector3d getOldPosition() {
        return this.oldPosition;
    }
    
    public void playAnimation(@Nonnull final Ref<EntityStore> ref, @Nonnull final AnimationSlot animationSlot, @Nullable final String animationId, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        Model model = null;
        final ModelComponent modelComponent = componentAccessor.getComponent(ref, ModelComponent.getComponentType());
        if (modelComponent != null) {
            model = modelComponent.getModel();
        }
        if (animationSlot != AnimationSlot.Action && animationId != null && model != null && !model.getAnimationSetMap().containsKey(animationId)) {
            Entity.LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES).log("Missing animation '%s' for Model '%s'", animationId, model.getModelAssetId());
            return;
        }
        final ActiveAnimationComponent activeAnimationComponent = componentAccessor.getComponent(ref, ActiveAnimationComponent.getComponentType());
        if (activeAnimationComponent == null) {
            Entity.LOGGER.at(Level.WARNING).atMostEvery(1, TimeUnit.MINUTES).log("Missing active animation component for entity: %s", this.roleName);
            return;
        }
        final String[] activeAnimations = activeAnimationComponent.getActiveAnimations();
        if (animationSlot != AnimationSlot.Action && Objects.equals(activeAnimations[animationSlot.ordinal()], animationId)) {
            return;
        }
        activeAnimationComponent.setPlayingAnimation(animationSlot, activeAnimations[animationSlot.ordinal()] = animationId);
        AnimationUtils.playAnimation(ref, animationSlot, animationId, componentAccessor);
    }
    
    public void clearDamageData() {
        this.damageData.reset();
    }
    
    public void setToDespawn() {
        this.isDespawning = true;
    }
    
    public void setDespawnTime(final float time) {
        if (this.isDespawning) {
            this.despawnRemainingSeconds = time;
        }
    }
    
    public double getDespawnTime() {
        return this.despawnRemainingSeconds;
    }
    
    @Override
    public boolean canBreathe(@Nonnull final Ref<EntityStore> ref, @Nonnull final BlockMaterial breathingMaterial, final int fluidId, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        return this.role.canBreathe(breathingMaterial, fluidId);
    }
    
    public DamageData getDamageData() {
        return this.damageData;
    }
    
    public boolean getCanCauseDamage(@Nonnull final Ref<EntityStore> attackerRef, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        return this.role.getCombatSupport().getCanCauseDamage(attackerRef, componentAccessor);
    }
    
    public void onFlockSetState(@Nonnull final Ref<EntityStore> ref, @Nonnull final String state, @Nullable final String subState, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        this.role.getStateSupport().setState(ref, state, subState, componentAccessor);
    }
    
    public void onFlockSetTarget(@Nonnull final String targetSlot, @Nonnull final Ref<EntityStore> target) {
        this.role.setMarkedTarget(targetSlot, target);
    }
    
    public void saveLeashInformation(@Nonnull final Vector3d position, @Nonnull final Vector3f rotation) {
        this.leashPoint.assign(position);
        this.leashHeading = rotation.getYaw();
        this.leashPitch = rotation.getPitch();
        this.saveLeashBlockType();
    }
    
    public void saveLeashBlockType() {
    }
    
    public boolean requiresLeashPosition() {
        if (this.role != null) {
            return this.role.requiresLeashPosition();
        }
        return this.hasLeashPosition;
    }
    
    public Vector3d getLeashPoint() {
        return this.leashPoint;
    }
    
    public void setLeashPoint(@Nonnull final Vector3d leashPoint) {
        this.leashPoint.assign(leashPoint);
    }
    
    public float getLeashHeading() {
        return this.leashHeading;
    }
    
    public void setLeashHeading(final float leashHeading) {
        this.leashHeading = leashHeading;
    }
    
    public float getLeashPitch() {
        return this.leashPitch;
    }
    
    public void setLeashPitch(final float leashPitch) {
        this.leashPitch = leashPitch;
    }
    
    public float getHoverPhase() {
        return this.hoverPhase;
    }
    
    public void setHoverPhase(final float hoverPhase) {
        this.hoverPhase = hoverPhase;
    }
    
    public double getHoverHeight() {
        return this.hoverHeight;
    }
    
    public void setHoverHeight(final double hoverHeight) {
        this.hoverHeight = hoverHeight;
    }
    
    public String getRoleName() {
        return this.roleName;
    }
    
    public void setRoleName(final String roleName) {
        this.roleName = roleName;
    }
    
    public int getRoleIndex() {
        return this.roleIndex;
    }
    
    public void setRoleIndex(final int roleIndex) {
        this.roleIndex = roleIndex;
    }
    
    public void setRole(final Role role) {
        this.role = role;
    }
    
    public int getSpawnRoleIndex() {
        return (this.spawnRoleIndex != Integer.MIN_VALUE) ? this.spawnRoleIndex : this.roleIndex;
    }
    
    public void setSpawnRoleIndex(int spawnRoleIndex) {
        if (spawnRoleIndex == this.roleIndex) {
            spawnRoleIndex = Integer.MIN_VALUE;
        }
        if ((this.spawnRoleIndex = spawnRoleIndex) == Integer.MIN_VALUE) {
            this.spawnRoleName = null;
            return;
        }
        this.spawnRoleName = NPCPlugin.get().getName(spawnRoleIndex);
    }
    
    @Nonnull
    public BlockTypeView getBlockTypeBlackboardView(@Nonnull final Ref<EntityStore> ref, @Nonnull final Store<EntityStore> store) {
        if (this.blackboardBlockTypeView == null) {
            this.initBlockTypeBlackboardView(ref, store);
        }
        if (this.blackboardBlockTypeView.isOutdated(ref, store)) {
            this.blackboardBlockTypeView = this.blackboardBlockTypeView.getUpdatedView(ref, store);
        }
        return this.blackboardBlockTypeView;
    }
    
    @Nullable
    public BlockTypeView removeBlockTypeBlackboardView() {
        final BlockTypeView view = this.blackboardBlockTypeView;
        this.blackboardBlockTypeView = null;
        return view;
    }
    
    public void initBlockTypeBlackboardView(@Nonnull final Ref<EntityStore> ref, final ComponentAccessor<EntityStore> componentAccessor) {
        if (this.blackboardBlockTypeSets != null) {
            (this.blackboardBlockTypeView = componentAccessor.getResource(Blackboard.getResourceType()).getView(BlockTypeView.class, ref, componentAccessor)).initialiseEntity(ref, this);
        }
    }
    
    public void initBlockChangeBlackboardView(@Nonnull final Ref<EntityStore> ref, final ComponentAccessor<EntityStore> componentAccessor) {
        if (this.blackboardBlockChangeSets != null) {
            (this.blackboardBlockChangeView = componentAccessor.getResource(Blackboard.getResourceType()).getView(BlockEventView.class, ref, componentAccessor)).initialiseEntity(ref, this);
        }
        if (this.blackboardEntityEventSets != null) {
            (this.blackboardEntityEventView = componentAccessor.getResource(Blackboard.getResourceType()).getView(EntityEventView.class, ref, componentAccessor)).initialiseEntity(ref, this);
        }
    }
    
    public void addBlackboardBlockTypeSets(final IntList blackboardBlockSets) {
        this.blackboardBlockTypeSets = blackboardBlockSets;
    }
    
    public IntList getBlackboardBlockTypeSets() {
        return this.blackboardBlockTypeSets;
    }
    
    public void addBlackboardBlockChangeSets(@Nonnull final BlockEventType type, @Nonnull final IntSet sets) {
        if (this.blackboardBlockChangeSets == null) {
            this.blackboardBlockChangeSets = new EnumMap<BlockEventType, IntSet>(BlockEventType.class);
        }
        this.blackboardBlockChangeSets.put(type, sets);
    }
    
    public IntSet getBlackboardBlockChangeSet(final BlockEventType type) {
        return this.blackboardBlockChangeSets.getOrDefault(type, null);
    }
    
    public Map<BlockEventType, IntSet> getBlackboardBlockChangeSets() {
        return this.blackboardBlockChangeSets;
    }
    
    public void notifyBlockChange(@Nonnull final BlockEventType type, @Nonnull final EventNotification notification) {
        final Store<EntityStore> store = this.world.getEntityStore().getStore();
        final Ref<EntityStore> initiator = notification.getInitiator();
        final boolean isPlayer = store.getArchetype(initiator).contains(Player.getComponentType());
        EventSupport<BlockEventType, EventNotification> support;
        if (isPlayer) {
            support = store.getComponent(this.reference, PlayerBlockEventSupport.getComponentType());
        }
        else {
            support = store.getComponent(this.reference, NPCBlockEventSupport.getComponentType());
        }
        if (support != null) {
            support.postMessage(type, notification, this.getReference(), store);
        }
    }
    
    public void addBlackboardEntityEventSets(@Nonnull final EntityEventType type, @Nonnull final IntSet sets) {
        if (this.blackboardEntityEventSets == null) {
            this.blackboardEntityEventSets = new EnumMap<EntityEventType, IntSet>(EntityEventType.class);
        }
        this.blackboardEntityEventSets.put(type, sets);
    }
    
    public IntSet getBlackboardEntityEventSet(@Nonnull final EntityEventType type) {
        return this.blackboardEntityEventSets.getOrDefault(type, null);
    }
    
    public Map<EntityEventType, IntSet> getBlackboardEntityEventSets() {
        return this.blackboardEntityEventSets;
    }
    
    public void notifyEntityEvent(@Nonnull final EntityEventType type, @Nonnull final EntityEventNotification notification) {
        final Store<EntityStore> store = this.world.getEntityStore().getStore();
        final Ref<EntityStore> initiator = notification.getInitiator();
        final boolean isPlayer = store.getArchetype(initiator).contains(Player.getComponentType());
        EntityEventSupport support;
        if (isPlayer) {
            support = store.getComponent(this.reference, PlayerEntityEventSupport.getComponentType());
        }
        else {
            support = store.getComponent(this.reference, NPCEntityEventSupport.getComponentType());
        }
        if (support != null) {
            support.postMessage(type, notification, this.reference, store);
        }
    }
    
    public void setEnvironment(final int env) {
        this.environmentIndex = env;
    }
    
    public int getEnvironment() {
        return this.environmentIndex;
    }
    
    public int getSpawnConfiguration() {
        return this.spawnConfigurationIndex;
    }
    
    public void setSpawnConfiguration(final int spawnConfigurationIndex) {
        if (spawnConfigurationIndex == Integer.MIN_VALUE) {
            this.spawnConfigurationIndex = Integer.MIN_VALUE;
            this.spawnConfigurationName = null;
            return;
        }
        final String name = WorldNPCSpawn.getAssetMap().getAsset(spawnConfigurationIndex).getId();
        if (name == null) {
            throw new IllegalArgumentException("setSpawnConfiguration: Cannot find spawn configuration name for index: " + spawnConfigurationIndex);
        }
        this.spawnConfigurationIndex = spawnConfigurationIndex;
        this.spawnConfigurationName = name;
    }
    
    public boolean updateSpawnTrackingState(final boolean newState) {
        final boolean oldState = this.isSpawnTracked;
        this.isSpawnTracked = newState;
        return oldState;
    }
    
    public boolean isDespawning() {
        return this.isDespawning;
    }
    
    public boolean isPlayingDespawnAnim() {
        return this.isPlayingDespawnAnim;
    }
    
    public EnumSet<RoleDebugFlags> getRoleDebugFlags() {
        return this.role.getDebugSupport().getDebugFlags();
    }
    
    public void setRoleDebugFlags(@Nonnull final EnumSet<RoleDebugFlags> flags) {
        this.role.getDebugSupport().setDebugFlags(flags);
    }
    
    public void setSpawnInstant(@Nonnull final Instant spawned) {
        this.spawnInstant = spawned;
    }
    
    public Instant getSpawnInstant() {
        return this.spawnInstant;
    }
    
    public void setInventorySize(final int hotbarCapacity, final int inventoryCapacity, final int offHandCapacity) {
        this.setInventory(new Inventory((short)inventoryCapacity, Inventory.DEFAULT_ARMOR_CAPACITY, (short)hotbarCapacity, (short)offHandCapacity, (short)0));
    }
    
    @Deprecated(forRemoval = true)
    public int getLegacyWorldgenId() {
        return this.worldgenId;
    }
    
    @Nonnull
    public PathManager getPathManager() {
        return this.pathManager;
    }
    
    public static boolean setAppearance(@Nonnull final Ref<EntityStore> ref, @Nonnull final String name, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (name.isEmpty()) {
            throw new IllegalArgumentException("Appearance can't be changed to empty");
        }
        final ModelComponent modelComponent = componentAccessor.getComponent(ref, ModelComponent.getComponentType());
        if (modelComponent == null) {
            return false;
        }
        final Model model = modelComponent.getModel();
        if (name.equals(model.getModelAssetId())) {
            return true;
        }
        final NPCEntity npcComponent = componentAccessor.getComponent(ref, getComponentType());
        assert npcComponent != null;
        final ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset(name);
        if (modelAsset == null) {
            NPCPlugin.get().getLogger().at(Level.SEVERE).log("Role '%s': Cannot find model '%s'", npcComponent.roleName, name);
            return false;
        }
        npcComponent.setAppearance(ref, modelAsset, componentAccessor);
        return true;
    }
    
    public void setAppearance(@Nonnull final Ref<EntityStore> ref, @Nonnull final ModelAsset modelAsset, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final Model model = Model.createScaledModel(modelAsset, this.initialModelScale);
        componentAccessor.putComponent(ref, ModelComponent.getComponentType(), new ModelComponent(model));
        this.role.updateMotionControllers(ref, model, model.getBoundingBox(), componentAccessor);
    }
    
    public float getCurrentHorizontalSpeedMultiplier(@Nullable final Ref<EntityStore> ref, @Nullable final ComponentAccessor<EntityStore> componentAccessor) {
        if (this.cachedEntityHorizontalSpeedMultiplier != Float.MAX_VALUE) {
            return this.cachedEntityHorizontalSpeedMultiplier;
        }
        this.cachedEntityHorizontalSpeedMultiplier = 1.0f;
        if (ref == null || componentAccessor == null) {
            return this.cachedEntityHorizontalSpeedMultiplier;
        }
        final EffectControllerComponent effectControllerComponent = componentAccessor.getComponent(ref, EffectControllerComponent.getComponentType());
        if (effectControllerComponent == null) {
            return this.cachedEntityHorizontalSpeedMultiplier;
        }
        final int[] cachedEffectIndexes = effectControllerComponent.getActiveEffectIndexes();
        if (cachedEffectIndexes == null) {
            return this.cachedEntityHorizontalSpeedMultiplier;
        }
        for (final int cachedEffectIndex : cachedEffectIndexes) {
            final EntityEffect effect = EntityEffect.getAssetMap().getAsset(cachedEffectIndex);
            if (effect != null) {
                final ApplicationEffects applicationEffects = effect.getApplicationEffects();
                if (applicationEffects != null) {
                    final float multiplier = applicationEffects.getHorizontalSpeedMultiplier();
                    if (multiplier >= 0.0f) {
                        this.cachedEntityHorizontalSpeedMultiplier *= multiplier;
                    }
                }
            }
        }
        return this.cachedEntityHorizontalSpeedMultiplier;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "NPCEntity{role=" + String.valueOf(this.role) + ", spawnRoleIndex=" + this.spawnRoleIndex + ", spawnPoint=" + String.valueOf(this.leashPoint) + ", spawnHeading=" + this.leashHeading + ", spawnPitch=" + this.leashPitch + ", environmentIndex='" + this.environmentIndex + "'} " + super.toString();
    }
    
    @Override
    public String getNPCTypeId() {
        return this.roleName;
    }
    
    @Override
    public int getNPCTypeIndex() {
        return this.roleIndex;
    }
    
    public void addReservation(@Nonnull final UUID playerUUID) {
        this.reservedBy.add(playerUUID);
    }
    
    public void removeReservation(@Nonnull final UUID playerUUID) {
        this.reservedBy.remove(playerUUID);
    }
    
    public boolean isReserved() {
        return !this.reservedBy.isEmpty();
    }
    
    public boolean isReservedBy(@Nonnull final UUID playerUUID) {
        return this.reservedBy.contains(playerUUID);
    }
    
    static {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     2: invokevirtual   java/lang/Class.desiredAssertionStatus:()Z
        //     5: ifne            12
        //     8: iconst_1       
        //     9: goto            13
        //    12: iconst_0       
        //    13: putstatic       com/hypixel/hytale/server/npc/entities/NPCEntity.$assertionsDisabled:Z
        //    16: ldc             Lcom/hypixel/hytale/server/npc/entities/NPCEntity;.class
        //    18: invokedynamic   BootstrapMethod #2, get:()Ljava/util/function/Supplier;
        //    23: getstatic       com/hypixel/hytale/server/core/entity/LivingEntity.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //    26: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;Lcom/hypixel/hytale/codec/builder/BuilderCodec;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    29: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    32: dup            
        //    33: ldc_w           "Env"
        //    36: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //    39: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    42: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
        //    47: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
        //    52: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    55: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    58: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    61: dup            
        //    62: ldc_w           "HvrPhs"
        //    65: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
        //    68: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    71: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
        //    76: invokedynamic   BootstrapMethod #6, apply:()Ljava/util/function/Function;
        //    81: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    84: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    87: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    90: dup            
        //    91: ldc_w           "HvrHght"
        //    94: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
        //    97: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   100: invokedynamic   BootstrapMethod #7, accept:()Ljava/util/function/BiConsumer;
        //   105: invokedynamic   BootstrapMethod #8, apply:()Ljava/util/function/Function;
        //   110: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   113: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   116: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   119: dup            
        //   120: ldc_w           "SpawnName"
        //   123: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //   126: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   129: invokedynamic   BootstrapMethod #9, accept:()Ljava/util/function/BiConsumer;
        //   134: invokedynamic   BootstrapMethod #10, apply:()Ljava/util/function/Function;
        //   139: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   142: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   145: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   148: dup            
        //   149: ldc_w           "MdlScl"
        //   152: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
        //   155: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   158: invokedynamic   BootstrapMethod #11, accept:()Ljava/util/function/BiConsumer;
        //   163: invokedynamic   BootstrapMethod #12, apply:()Ljava/util/function/Function;
        //   168: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   171: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   174: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   177: dup            
        //   178: ldc_w           "SpawnConfig"
        //   181: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //   184: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   187: invokedynamic   BootstrapMethod #13, accept:()Ljava/util/function/BiConsumer;
        //   192: invokedynamic   BootstrapMethod #14, apply:()Ljava/util/function/Function;
        //   197: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   200: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   203: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   206: dup            
        //   207: ldc_w           "SpawnInstant"
        //   210: getstatic       com/hypixel/hytale/codec/Codec.INSTANT:Lcom/hypixel/hytale/codec/function/FunctionCodec;
        //   213: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   216: invokedynamic   BootstrapMethod #15, accept:()Ljava/util/function/BiConsumer;
        //   221: invokedynamic   BootstrapMethod #16, apply:()Ljava/util/function/Function;
        //   226: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   229: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   232: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   235: dup            
        //   236: ldc_w           "AlarmStore"
        //   239: getstatic       com/hypixel/hytale/server/npc/storage/AlarmStore.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   242: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   245: invokedynamic   BootstrapMethod #17, accept:()Ljava/util/function/BiConsumer;
        //   250: invokedynamic   BootstrapMethod #18, apply:()Ljava/util/function/Function;
        //   255: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   258: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   261: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   264: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   267: dup            
        //   268: ldc_w           "WorldgenId"
        //   271: getstatic       com/hypixel/hytale/codec/Codec.INTEGER:Lcom/hypixel/hytale/codec/codecs/simple/IntegerCodec;
        //   274: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   277: invokedynamic   BootstrapMethod #19, accept:()Ljava/util/function/BiConsumer;
        //   282: invokedynamic   BootstrapMethod #20, apply:()Ljava/util/function/Function;
        //   287: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   290: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   293: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   296: dup            
        //   297: ldc_w           "PathManager"
        //   300: getstatic       com/hypixel/hytale/server/npc/entities/PathManager.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   303: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   306: invokedynamic   BootstrapMethod #21, accept:()Ljava/util/function/BiConsumer;
        //   311: invokedynamic   BootstrapMethod #22, apply:()Ljava/util/function/Function;
        //   316: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   319: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   322: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   325: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   328: dup            
        //   329: ldc_w           "LeashPos"
        //   332: getstatic       com/hypixel/hytale/math/vector/Vector3d.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   335: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   338: invokedynamic   BootstrapMethod #23, accept:()Ljava/util/function/BiConsumer;
        //   343: invokedynamic   BootstrapMethod #24, apply:()Ljava/util/function/Function;
        //   348: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   351: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   354: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   357: dup            
        //   358: ldc_w           "LeashHdg"
        //   361: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
        //   364: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   367: invokedynamic   BootstrapMethod #25, accept:()Ljava/util/function/BiConsumer;
        //   372: invokedynamic   BootstrapMethod #26, apply:()Ljava/util/function/Function;
        //   377: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   380: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   383: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   386: dup            
        //   387: ldc_w           "LeashPtch"
        //   390: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
        //   393: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   396: invokedynamic   BootstrapMethod #27, accept:()Ljava/util/function/BiConsumer;
        //   401: invokedynamic   BootstrapMethod #28, apply:()Ljava/util/function/Function;
        //   406: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   409: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   412: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   415: dup            
        //   416: ldc_w           "RoleName"
        //   419: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //   422: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   425: invokedynamic   BootstrapMethod #29, accept:()Ljava/util/function/BiConsumer;
        //   430: invokedynamic   BootstrapMethod #30, apply:()Ljava/util/function/Function;
        //   435: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.addField:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   438: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   441: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   444: putstatic       com/hypixel/hytale/server/npc/entities/NPCEntity.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   447: return         
        //    StackMapTable: 00 02 0C 40 01
        // 
        // 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:284)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
        //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:267)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.TypeDefinition.accept(TypeDefinition.java:189)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:324)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2586)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1083)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:373)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
        //     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:206)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
        //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
        //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
}
