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

package com.hypixel.hytale.server.core.entity.effect;

import it.unimi.dsi.fastutil.objects.ObjectIterator;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import com.hypixel.hytale.common.util.ArrayUtil;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.ints.IntArraySet;
import com.hypixel.hytale.server.core.asset.type.entityeffect.config.RemovalBehavior;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSkinComponent;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.entity.EntityUtils;
import com.hypixel.hytale.protocol.EffectOp;
import com.hypixel.hytale.server.core.modules.entity.livingentity.LivingEntityEffectSystem;
import com.hypixel.hytale.server.core.asset.type.entityeffect.config.OverlapBehavior;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.asset.type.entityeffect.config.EntityEffect;
import com.hypixel.hytale.component.Ref;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.protocol.EntityEffectUpdate;
import it.unimi.dsi.fastutil.objects.ObjectList;
import javax.annotation.Nullable;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import javax.annotation.Nonnull;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Component;

public class EffectControllerComponent implements Component<EntityStore>
{
    @Nonnull
    public static final BuilderCodec<EffectControllerComponent> CODEC;
    @Nonnull
    protected final Int2ObjectMap<ActiveEntityEffect> activeEffects;
    @Nullable
    protected int[] cachedActiveEffectIndexes;
    @Nonnull
    protected ObjectList<EntityEffectUpdate> changes;
    protected boolean isNetworkOutdated;
    @Nullable
    protected Model originalModel;
    protected int activeModelChangeEntityEffectIndex;
    protected boolean isInvulnerable;
    
    @Nonnull
    public static ComponentType<EntityStore, EffectControllerComponent> getComponentType() {
        return EntityModule.get().getEffectControllerComponentType();
    }
    
    public EffectControllerComponent() {
        this.activeEffects = new Int2ObjectOpenHashMap<ActiveEntityEffect>();
        this.changes = new ObjectArrayList<EntityEffectUpdate>();
        this.originalModel = null;
    }
    
    public EffectControllerComponent(@Nonnull final EffectControllerComponent effectControllerComponent) {
        this.activeEffects = new Int2ObjectOpenHashMap<ActiveEntityEffect>();
        this.changes = new ObjectArrayList<EntityEffectUpdate>();
        this.originalModel = null;
        this.originalModel = effectControllerComponent.originalModel;
        this.activeModelChangeEntityEffectIndex = effectControllerComponent.activeModelChangeEntityEffectIndex;
        this.changes.addAll(effectControllerComponent.changes);
        final ActiveEntityEffect[] activeEntityEffects = effectControllerComponent.getAllActiveEntityEffects();
        if (activeEntityEffects != null) {
            effectControllerComponent.addActiveEntityEffects(activeEntityEffects);
        }
    }
    
    public boolean isInvulnerable() {
        return this.isInvulnerable;
    }
    
    public void setInvulnerable(final boolean invulnerable) {
        this.isInvulnerable = invulnerable;
    }
    
    public boolean addEffect(@Nonnull final Ref<EntityStore> ownerRef, @Nonnull final EntityEffect entityEffect, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final int entityEffectIndex = EntityEffect.getAssetMap().getIndex(entityEffect.getId());
        return entityEffectIndex != Integer.MIN_VALUE && this.addEffect(ownerRef, entityEffectIndex, entityEffect, componentAccessor);
    }
    
    public boolean addEffect(@Nonnull final Ref<EntityStore> ownerRef, final int entityEffectIndex, @Nonnull final EntityEffect entityEffect, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final boolean infinite = entityEffect.isInfinite();
        final float duration = entityEffect.getDuration();
        final OverlapBehavior overlapBehavior = entityEffect.getOverlapBehavior();
        if (infinite) {
            return this.addInfiniteEffect(ownerRef, entityEffectIndex, entityEffect, componentAccessor);
        }
        return this.addEffect(ownerRef, entityEffectIndex, entityEffect, duration, overlapBehavior, componentAccessor);
    }
    
    public boolean addEffect(@Nonnull final Ref<EntityStore> ownerRef, @Nonnull final EntityEffect entityEffect, final float duration, @Nonnull final OverlapBehavior overlapBehavior, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final int entityEffectIndex = EntityEffect.getAssetMap().getIndex(entityEffect.getId());
        return entityEffectIndex != Integer.MIN_VALUE && this.addEffect(ownerRef, entityEffectIndex, entityEffect, duration, overlapBehavior, componentAccessor);
    }
    
    public boolean addEffect(@Nonnull final Ref<EntityStore> ownerRef, final int entityEffectIndex, @Nonnull final EntityEffect entityEffect, final float duration, @Nonnull final OverlapBehavior overlapBehavior, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (!LivingEntityEffectSystem.canApplyEffect(ownerRef, entityEffect, componentAccessor)) {
            return false;
        }
        final ActiveEntityEffect currentActiveEntityEffectEntry = this.activeEffects.get(entityEffectIndex);
        if (currentActiveEntityEffectEntry != null) {
            if (currentActiveEntityEffectEntry.isInfinite()) {
                return true;
            }
            switch (overlapBehavior) {
                case EXTEND: {
                    final ActiveEntityEffect activeEntityEffect = currentActiveEntityEffectEntry;
                    activeEntityEffect.remainingDuration += duration;
                    this.addChange(new EntityEffectUpdate(EffectOp.Add, entityEffectIndex, currentActiveEntityEffectEntry.remainingDuration, false, currentActiveEntityEffectEntry.debuff, currentActiveEntityEffectEntry.statusEffectIcon));
                    return true;
                }
                case IGNORE: {
                    return true;
                }
            }
        }
        final ActiveEntityEffect activeEntityEffectEntry = new ActiveEntityEffect(entityEffect.getId(), entityEffectIndex, duration, entityEffect.isDebuff(), entityEffect.getStatusEffectIcon(), entityEffect.isInvulnerable());
        this.activeEffects.put(entityEffectIndex, activeEntityEffectEntry);
        final Entity ownerEntity = EntityUtils.getEntity(ownerRef, componentAccessor);
        if (ownerEntity instanceof final LivingEntity ownerLivingEntity) {
            ownerLivingEntity.getStatModifiersManager().setRecalculate(true);
        }
        this.setModelChange(ownerRef, entityEffect, entityEffectIndex, componentAccessor);
        this.addChange(new EntityEffectUpdate(EffectOp.Add, entityEffectIndex, activeEntityEffectEntry.remainingDuration, false, activeEntityEffectEntry.debuff, activeEntityEffectEntry.statusEffectIcon));
        this.invalidateCache();
        return true;
    }
    
    public boolean addInfiniteEffect(@Nonnull final Ref<EntityStore> ownerRef, final int entityEffectIndex, @Nonnull final EntityEffect entityEffect, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (!LivingEntityEffectSystem.canApplyEffect(ownerRef, entityEffect, componentAccessor)) {
            return false;
        }
        ActiveEntityEffect currentActiveEntityEffectEntry = this.activeEffects.get(entityEffectIndex);
        if (currentActiveEntityEffectEntry == null) {
            currentActiveEntityEffectEntry = new ActiveEntityEffect(entityEffect.getId(), entityEffectIndex, true, entityEffect.isInvulnerable());
            this.activeEffects.put(entityEffectIndex, currentActiveEntityEffectEntry);
            final Entity ownerEntity = EntityUtils.getEntity(ownerRef, componentAccessor);
            if (ownerEntity instanceof final LivingEntity ownerLivingEntity) {
                ownerLivingEntity.getStatModifiersManager().setRecalculate(true);
            }
            this.invalidateCache();
        }
        else if (!currentActiveEntityEffectEntry.isInfinite()) {
            currentActiveEntityEffectEntry.infinite = true;
        }
        this.setModelChange(ownerRef, entityEffect, entityEffectIndex, componentAccessor);
        this.addChange(new EntityEffectUpdate(EffectOp.Add, entityEffectIndex, currentActiveEntityEffectEntry.remainingDuration, true, currentActiveEntityEffectEntry.debuff, currentActiveEntityEffectEntry.statusEffectIcon));
        return true;
    }
    
    public void setModelChange(@Nonnull final Ref<EntityStore> ownerRef, @Nonnull final EntityEffect entityEffect, final int entityEffectIndex, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (this.originalModel != null) {
            return;
        }
        if (entityEffect.getModelChange() == null) {
            return;
        }
        final ModelComponent modelComponent = componentAccessor.getComponent(ownerRef, ModelComponent.getComponentType());
        assert modelComponent != null;
        this.originalModel = modelComponent.getModel();
        this.activeModelChangeEntityEffectIndex = entityEffectIndex;
        final ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset(entityEffect.getModelChange());
        final Model scaledModel = Model.createRandomScaleModel(modelAsset);
        componentAccessor.putComponent(ownerRef, ModelComponent.getComponentType(), new ModelComponent(scaledModel));
    }
    
    public void tryResetModelChange(@Nonnull final Ref<EntityStore> ownerRef, final int activeEffectIndex, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (this.originalModel != null && this.activeModelChangeEntityEffectIndex == activeEffectIndex) {
            componentAccessor.putComponent(ownerRef, ModelComponent.getComponentType(), new ModelComponent(this.originalModel));
            final PlayerSkinComponent playerSkinComponent = componentAccessor.getComponent(ownerRef, PlayerSkinComponent.getComponentType());
            if (playerSkinComponent != null) {
                playerSkinComponent.setNetworkOutdated();
            }
            this.originalModel = null;
        }
    }
    
    public void addActiveEntityEffects(@Nonnull final ActiveEntityEffect[] activeEntityEffects) {
        if (activeEntityEffects.length == 0) {
            return;
        }
        for (final ActiveEntityEffect activeEntityEffect : activeEntityEffects) {
            final int entityEffectIndex = EntityEffect.getAssetMap().getIndex(activeEntityEffect.entityEffectId);
            if (entityEffectIndex != Integer.MIN_VALUE) {
                activeEntityEffect.entityEffectIndex = entityEffectIndex;
                this.activeEffects.put(entityEffectIndex, activeEntityEffect);
                this.addChange(new EntityEffectUpdate(EffectOp.Add, entityEffectIndex, activeEntityEffect.remainingDuration, activeEntityEffect.infinite, activeEntityEffect.debuff, activeEntityEffect.statusEffectIcon));
            }
        }
        this.invalidateCache();
    }
    
    public void removeEffect(@Nonnull final Ref<EntityStore> ownerRef, final int entityEffectIndex, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final EntityEffect entityEffect = EntityEffect.getAssetMap().getAsset(entityEffectIndex);
        if (entityEffect == null) {
            throw new IllegalArgumentException(String.format("Unknown EntityEffect with index \"%s\"", entityEffectIndex));
        }
        this.removeEffect(ownerRef, entityEffectIndex, entityEffect.getRemovalBehavior(), componentAccessor);
    }
    
    public void removeEffect(@Nonnull final Ref<EntityStore> ownerRef, final int entityEffectIndex, @Nonnull final RemovalBehavior removalBehavior, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final ActiveEntityEffect activeEffectEntry = this.activeEffects.get(entityEffectIndex);
        if (activeEffectEntry == null) {
            return;
        }
        this.tryResetModelChange(ownerRef, activeEffectEntry.getEntityEffectIndex(), componentAccessor);
        switch (removalBehavior) {
            case COMPLETE: {
                this.activeEffects.remove(entityEffectIndex);
                final Entity ownerEntity = EntityUtils.getEntity(ownerRef, componentAccessor);
                if (ownerEntity instanceof final LivingEntity ownerLivingEntity) {
                    ownerLivingEntity.getStatModifiersManager().setRecalculate(true);
                }
                this.addChange(new EntityEffectUpdate(EffectOp.Remove, entityEffectIndex, 0.0f, false, false, ""));
                this.invalidateCache();
                return;
            }
            case INFINITE: {
                activeEffectEntry.infinite = false;
                break;
            }
            case DURATION: {
                activeEffectEntry.remainingDuration = 0.0f;
                break;
            }
        }
        final Entity ownerEntity = EntityUtils.getEntity(ownerRef, componentAccessor);
        if (ownerEntity instanceof final LivingEntity ownerLivingEntity) {
            ownerLivingEntity.getStatModifiersManager().setRecalculate(true);
        }
        this.addChange(new EntityEffectUpdate(EffectOp.Remove, entityEffectIndex, activeEffectEntry.remainingDuration, activeEffectEntry.infinite, activeEffectEntry.debuff, activeEffectEntry.statusEffectIcon));
    }
    
    private void addChange(@Nonnull final EntityEffectUpdate update) {
        this.isNetworkOutdated = true;
        this.changes.add(update);
    }
    
    public void clearEffects(@Nonnull final Ref<EntityStore> ownerRef, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final IntSet keys = new IntArraySet(this.activeEffects.keySet());
        for (final int effect : keys) {
            this.removeEffect(ownerRef, effect, componentAccessor);
        }
        this.invalidateCache();
        if (this.originalModel != null) {
            componentAccessor.putComponent(ownerRef, ModelComponent.getComponentType(), new ModelComponent(this.originalModel));
            this.originalModel = null;
        }
    }
    
    public void invalidateCache() {
        this.cachedActiveEffectIndexes = null;
    }
    
    @Nonnull
    public Int2ObjectMap<ActiveEntityEffect> getActiveEffects() {
        return this.activeEffects;
    }
    
    public int[] getActiveEffectIndexes() {
        if (this.cachedActiveEffectIndexes == null) {
            if (this.activeEffects.isEmpty()) {
                this.cachedActiveEffectIndexes = ArrayUtil.EMPTY_INT_ARRAY;
            }
            else {
                this.cachedActiveEffectIndexes = this.activeEffects.keySet().toIntArray();
            }
        }
        return this.cachedActiveEffectIndexes;
    }
    
    public boolean consumeNetworkOutdated() {
        final boolean temp = this.isNetworkOutdated;
        this.isNetworkOutdated = false;
        return temp;
    }
    
    @Nonnull
    public EntityEffectUpdate[] consumeChanges() {
        return this.changes.toArray(EntityEffectUpdate[]::new);
    }
    
    public void clearChanges() {
        this.changes.clear();
    }
    
    @Nonnull
    public EntityEffectUpdate[] createInitUpdates() {
        final EntityEffectUpdate[] changeArray = new EntityEffectUpdate[this.activeEffects.size()];
        int index = 0;
        final ObjectIterator<Int2ObjectMap.Entry<ActiveEntityEffect>> iterator = Int2ObjectMaps.fastIterator(this.activeEffects);
        while (iterator.hasNext()) {
            final Int2ObjectMap.Entry<ActiveEntityEffect> entry = iterator.next();
            final ActiveEntityEffect activeEntityEffectEntry = entry.getValue();
            changeArray[index++] = new EntityEffectUpdate(EffectOp.Add, entry.getIntKey(), activeEntityEffectEntry.remainingDuration, activeEntityEffectEntry.infinite, activeEntityEffectEntry.debuff, activeEntityEffectEntry.statusEffectIcon);
        }
        return changeArray;
    }
    
    @Nullable
    public ActiveEntityEffect[] getAllActiveEntityEffects() {
        if (this.activeEffects.isEmpty()) {
            return null;
        }
        final ActiveEntityEffect[] activeEntityEffects = new ActiveEntityEffect[this.activeEffects.size()];
        int index = 0;
        for (final ActiveEntityEffect entityEffect : this.activeEffects.values()) {
            activeEntityEffects[index] = entityEffect;
            ++index;
        }
        return activeEntityEffects;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "EntityEffectController{, activeEffects=" + String.valueOf(this.activeEffects);
    }
    
    @Nonnull
    @Override
    public EffectControllerComponent clone() {
        return new EffectControllerComponent(this);
    }
    
    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/core/entity/effect/EffectControllerComponent.$assertionsDisabled:Z
        //    16: ldc             Lcom/hypixel/hytale/server/core/entity/effect/EffectControllerComponent;.class
        //    18: invokedynamic   BootstrapMethod #2, get:()Ljava/util/function/Supplier;
        //    23: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    26: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    29: dup            
        //    30: ldc_w           "ActiveEntityEffects"
        //    33: new             Lcom/hypixel/hytale/codec/codecs/array/ArrayCodec;
        //    36: dup            
        //    37: getstatic       com/hypixel/hytale/server/core/entity/effect/ActiveEntityEffect.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //    40: invokedynamic   BootstrapMethod #3, apply:()Ljava/util/function/IntFunction;
        //    45: invokespecial   com/hypixel/hytale/codec/codecs/array/ArrayCodec.<init>:(Lcom/hypixel/hytale/codec/Codec;Ljava/util/function/IntFunction;)V
        //    48: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    51: invokedynamic   BootstrapMethod #4, accept:()Ljava/util/function/BiConsumer;
        //    56: invokedynamic   BootstrapMethod #5, apply:()Ljava/util/function/Function;
        //    61: 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;
        //    64: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    67: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    70: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //    73: putstatic       com/hypixel/hytale/server/core/entity/effect/EffectControllerComponent.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //    76: 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.visitParameterizedType(TypeSubstitutionVisitor.java:225)
        //     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:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:211)
        //     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:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:314)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2611)
        //     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.runInference(TypeAnalysis.java:684)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypesForVariables(TypeAnalysis.java:593)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:405)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:109)
        //     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.");
    }
}
