// Path: src/es/eltrueno/npc/tinyprotocol/Reflection.java
// public interface FieldAccessor<T> {
//     /**
//      * Retrieve the content of a field.
//      *
//      * @param target - the target object, or NULL for a static field.
//      * @return The value of the field.
//      */
//     public T get(Object target);
// 
//     /**
//      * Set the content of a field.
//      *
//      * @param target - the target object, or NULL for a static field.
//      * @param value - the new value of the field.
//      */
//     public void set(Object target, Object value);
// 
//     /**
//      * Determine if the given object has this field.
//      *
//      * @param target - the object to test.
//      * @return TRUE if it does, FALSE otherwise.
//      */
//     public boolean hasField(Object target);
// }
// 
// Path: src/es/eltrueno/npc/tinyprotocol/Reflection.java
// public interface MethodInvoker {
//     /**
//      * Invoke a method on a specific target object.
//      *
//      * @param target - the target object, or NULL for a static method.
//      * @param arguments - the arguments to pass to the method.
//      * @return The return value, or NULL if is void.
//      */
//     public Object invoke(Object target, Object... arguments);
// }


import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.mojang.authlib.GameProfile;
import es.eltrueno.npc.tinyprotocol.Reflection.FieldAccessor;
import es.eltrueno.npc.tinyprotocol.Reflection.MethodInvoker;
import io.netty.channel.*;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
        }

        // See ChannelInjector in ProtocolLib, line 590
        channel.eventLoop().execute(new Runnable() {

            @Override
            public void run() {
                channel.pipeline().remove(handlerName);
            }

        });
    }

    /**
     * Determine if the given player has been injected by TinyProtocol.
     *
     * @param player - the player.
     * @return TRUE if it is, FALSE otherwise.
     */
    public boolean hasInjected(Player player) {
        return hasInjected(getChannel(player));
    }

    /**
     * Determine if the given channel has been injected by TinyProtocol.
     *
     * @param channel - the channel.
     * @return TRUE if it is, FALSE otherwise.
     */
    public boolean hasInjected(Channel channel) {
// Path: src/es/eltrueno/npc/tinyprotocol/Reflection.java
// public interface FieldAccessor<T> {
//     /**
//      * Retrieve the content of a field.
//      *
//      * @param target - the target object, or NULL for a static field.
//      * @return The value of the field.
//      */
//     public T get(Object target);
// 
//     /**
//      * Set the content of a field.
//      *
//      * @param target - the target object, or NULL for a static field.
//      * @param value - the new value of the field.
//      */
//     public void set(Object target, Object value);
// 
//     /**
//      * Determine if the given object has this field.
//      *
//      * @param target - the object to test.
//      * @return TRUE if it does, FALSE otherwise.
//      */
//     public boolean hasField(Object target);
// }
// 
// Path: src/es/eltrueno/npc/tinyprotocol/Reflection.java
// public interface MethodInvoker {
//     /**
//      * Invoke a method on a specific target object.
//      *
//      * @param target - the target object, or NULL for a static method.
//      * @param arguments - the arguments to pass to the method.
//      * @return The return value, or NULL if is void.
//      */
//     public Object invoke(Object target, Object... arguments);
// }


// Path: src/es/eltrueno/npc/tinyprotocol/TinyProtocol.java
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.mojang.authlib.GameProfile;
import es.eltrueno.npc.tinyprotocol.Reflection.FieldAccessor;
import es.eltrueno.npc.tinyprotocol.Reflection.MethodInvoker;
import io.netty.channel.*;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;

        }

        // See ChannelInjector in ProtocolLib, line 590
        channel.eventLoop().execute(new Runnable() {

            @Override
            public void run() {
                channel.pipeline().remove(handlerName);
            }

        });
    }

    /**
     * Determine if the given player has been injected by TinyProtocol.
     *
     * @param player - the player.
     * @return TRUE if it is, FALSE otherwise.
     */
    public boolean hasInjected(Player player) {
        return hasInjected(getChannel(player));
    }

    /**
     * Determine if the given channel has been injected by TinyProtocol.
     *
     * @param channel - the channel.
     * @return TRUE if it is, FALSE otherwise.
     */
    public boolean hasInjected(Channel channel) {
        return channel.pipeline().get(handlerName) != null;