@@ -0,0 +1,3083 @@
+package deterno.fight.tgm.damage.tracker.base;%0A%0Aimport com.google.common.base.Preconditions;%0Aimport com.google.common.collect.ImmutableSet;%0Aimport com.google.common.collect.Sets;%0Aimport deterno.fight.tgm.damage.tracker.Tracker;%0Aimport org.bukkit.Bukkit;%0Aimport org.bukkit.World;%0A%0Aimport javax.annotation.Nonnull;%0Aimport java.util.Set;%0A%0A/**%0A * Abstract class for implementing %7B@link Tracker%7D.%0A *%0A * Implements the stateful operations of enabling / disabling the tracker in%0A * certain worlds and notifies the child class through the %7B@link #onEnable%7D%0A * and %7B@link #onDisable%7D methods.%0A */%0Apublic abstract class AbstractTracker implements Tracker %7B%0A    /**%0A     * Method called when the tracker is enabled for a world.%0A     *%0A     * @param world World the tracker is now enabled in%0A     */%0A    protected void onEnable(World world) %7B %7D%0A%0A    /**%0A     * Method called when the tracker is disabled for a world.%0A     *%0A     * Will be called before the %7B@link #clear%7D method.%0A     *%0A     * @param world World the tracker is now disabled in%0A     */%0A    protected void onDisable(World world) %7B %7D%0A%0A    // implementation%0A    private boolean enabled = false;%0A    private final Set%3CWorld%3E oppositeWorlds = Sets.newHashSet();%0A%0A    public boolean isEnabled(@Nonnull World world) %7B%0A        Preconditions.checkNotNull(world, %22world%22);%0A%0A        boolean opposite = this.oppositeWorlds.contains(world);%0A%0A        return this.enabled %5E opposite;%0A    %7D%0A%0A    public boolean enable() %7B%0A        return this.setEnabled(true);%0A    %7D%0A%0A    public boolean enable(@Nonnull World world) %7B%0A        return this.setEnabled(true, world);%0A    %7D%0A%0A    public boolean disable() %7B%0A        return this.setEnabled(false);%0A    %7D%0A%0A    public boolean disable(@Nonnull World world) %7B%0A        return this.setEnabled(false, world);%0A    %7D%0A%0A    private boolean setEnabled(boolean now) %7B%0A        Set%3CWorld%3E changed = this.getOppositeWorlds(now);%0A%0A        this.enabled = now;%0A        this.oppositeWorlds.clear();%0A%0A        for(World world : changed) %7B%0A            this.notifyChange(now, world);%0A        %7D%0A%0A        return !changed.isEmpty();%0A    %7D%0A%0A    private boolean setEnabled(boolean now, @Nonnull World world) %7B%0A        Preconditions.checkNotNull(world, %22world%22);%0A%0A        boolean changed;%0A%0A        if(this.enabled == now) %7B%0A            changed = this.oppositeWorlds.remove(world);%0A        %7D else %7B%0A            changed = this.oppositeWorlds.add(world);%0A        %7D%0A%0A        if(changed) %7B%0A            this.notifyChange(now, world);%0A        %7D%0A%0A        return changed;%0A    %7D%0A%0A    private Set%3CWorld%3E getOppositeWorlds(boolean now) %7B%0A        if(this.enabled == now) %7B%0A            return ImmutableSet.copyOf(this.oppositeWorlds);%0A        %7D else %7B%0A            Set%3CWorld%3E opp = Sets.newHashSet(Bukkit.getWorlds());%0A            opp.removeAll(this.oppositeWorlds);%0A            return ImmutableSet.copyOf(opp);%0A        %7D%0A    %7D%0A%0A    private void notifyChange(boolean now, @Nonnull World world) %7B%0A        if(now) %7B%0A            this.onDisable(world);%0A            this.clear(world);%0A        %7D else %7B%0A            this.onEnable(world);%0A        %7D%0A    %7D%0A%7D%0A

Create AbstractTracker.java