// Path: src/main/java/org/cyclops/everlastingabilities/api/Ability.java
// public class Ability implements Comparable<Ability> {
// 
//     public static final Ability EMPTY = new Ability(new AbilityType("", "", () -> Rarity.COMMON, () -> 0, () -> 0, () -> true, () -> true, () -> true, () -> true), 0);
// 
//     private final IAbilityType abilityType;
//     private final int level;
// 
//     public Ability(@Nonnull IAbilityType abilityType, int level) {
//         this.abilityType = Objects.requireNonNull(abilityType);
//         this.level = level;
//     }
// 
//     public IAbilityType getAbilityType() {
//         return abilityType;
//     }
// 
//     public int getLevel() {
//         return level;
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("[%s @ %s]", abilityType.getTranslationKey(), level);
//     }
// 
//     @Override
//     public int compareTo(Ability other) {
//         return this.toString().compareTo(other.toString());
//     }
// 
//     public ITextComponent getTextComponent() {
//         return new StringTextComponent("[")
//                 .append(new TranslationTextComponent(abilityType.getTranslationKey()))
//                 .appendString(" @ " + level + "]");
//     }
// 
//     public boolean isEmpty() {
//         return getLevel() <= 0;
//     }
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/api/IAbilityType.java
// public interface IAbilityType extends IForgeRegistryEntry<IAbilityType> {
// 
//     public String getTranslationKey();
//     public String getUnlocalizedDescription();
//     public Rarity getRarity();
//     public int getMaxLevel();
//     public default int getMaxLevelInfinitySafe() {
//         return getMaxLevel() < 0 ? Integer.MAX_VALUE : getMaxLevel();
//     }
//     public int getBaseXpPerLevel();
//     public boolean isObtainableOnPlayerSpawn();
//     public boolean isObtainableOnMobSpawn();
//     public boolean isObtainableOnCraft();
//     public boolean isObtainableOnLoot();
// 
//     public void onTick(PlayerEntity player, int level);
//     public void onChangedLevel(PlayerEntity player, int oldLevel, int newLevel);
// 
// }


import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.cyclops.everlastingabilities.api.Ability;
import org.cyclops.everlastingabilities.api.IAbilityType;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
package org.cyclops.everlastingabilities.api.capability;



/**
 * Default implementation of {@link IAbilityStore} for storing abilities as a capability.
 * @author rubensworks
 */
public class DefaultAbilityStore implements IAbilityStore {

    protected final Map<IAbilityType, Integer> abilityTypes = Maps.newLinkedHashMap();

    public DefaultAbilityStore() {

    }

    public DefaultAbilityStore(DefaultMutableAbilityStore abilityStore) {
        setAbilities(abilityStore.abilityTypes);
    }

    @Override
    public void setAbilities(Map<IAbilityType, Integer> abilityTypes) {
        this.abilityTypes.clear();
        this.abilityTypes.putAll(abilityTypes);
    }

    @Override
    public boolean hasAbilityType(IAbilityType abilityType) {
        return abilityTypes.containsKey(abilityType);
    }

    @Override
    public Collection<IAbilityType> getAbilityTypes() {
        return abilityTypes.keySet();
    }

    @Override
// Path: src/main/java/org/cyclops/everlastingabilities/api/Ability.java
// public class Ability implements Comparable<Ability> {
// 
//     public static final Ability EMPTY = new Ability(new AbilityType("", "", () -> Rarity.COMMON, () -> 0, () -> 0, () -> true, () -> true, () -> true, () -> true), 0);
// 
//     private final IAbilityType abilityType;
//     private final int level;
// 
//     public Ability(@Nonnull IAbilityType abilityType, int level) {
//         this.abilityType = Objects.requireNonNull(abilityType);
//         this.level = level;
//     }
// 
//     public IAbilityType getAbilityType() {
//         return abilityType;
//     }
// 
//     public int getLevel() {
//         return level;
//     }
// 
//     @Override
//     public String toString() {
//         return String.format("[%s @ %s]", abilityType.getTranslationKey(), level);
//     }
// 
//     @Override
//     public int compareTo(Ability other) {
//         return this.toString().compareTo(other.toString());
//     }
// 
//     public ITextComponent getTextComponent() {
//         return new StringTextComponent("[")
//                 .append(new TranslationTextComponent(abilityType.getTranslationKey()))
//                 .appendString(" @ " + level + "]");
//     }
// 
//     public boolean isEmpty() {
//         return getLevel() <= 0;
//     }
// 
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/api/IAbilityType.java
// public interface IAbilityType extends IForgeRegistryEntry<IAbilityType> {
// 
//     public String getTranslationKey();
//     public String getUnlocalizedDescription();
//     public Rarity getRarity();
//     public int getMaxLevel();
//     public default int getMaxLevelInfinitySafe() {
//         return getMaxLevel() < 0 ? Integer.MAX_VALUE : getMaxLevel();
//     }
//     public int getBaseXpPerLevel();
//     public boolean isObtainableOnPlayerSpawn();
//     public boolean isObtainableOnMobSpawn();
//     public boolean isObtainableOnCraft();
//     public boolean isObtainableOnLoot();
// 
//     public void onTick(PlayerEntity player, int level);
//     public void onChangedLevel(PlayerEntity player, int oldLevel, int newLevel);
// 
// }


// Path: src/main/java/org/cyclops/everlastingabilities/api/capability/DefaultAbilityStore.java
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.cyclops.everlastingabilities.api.Ability;
import org.cyclops.everlastingabilities.api.IAbilityType;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

package org.cyclops.everlastingabilities.api.capability;



/**
 * Default implementation of {@link IAbilityStore} for storing abilities as a capability.
 * @author rubensworks
 */
public class DefaultAbilityStore implements IAbilityStore {

    protected final Map<IAbilityType, Integer> abilityTypes = Maps.newLinkedHashMap();

    public DefaultAbilityStore() {

    }

    public DefaultAbilityStore(DefaultMutableAbilityStore abilityStore) {
        setAbilities(abilityStore.abilityTypes);
    }

    @Override
    public void setAbilities(Map<IAbilityType, Integer> abilityTypes) {
        this.abilityTypes.clear();
        this.abilityTypes.putAll(abilityTypes);
    }

    @Override
    public boolean hasAbilityType(IAbilityType abilityType) {
        return abilityTypes.containsKey(abilityType);
    }

    @Override
    public Collection<IAbilityType> getAbilityTypes() {
        return abilityTypes.keySet();
    }

    @Override
    public Collection<Ability> getAbilities() {