// Path: tftp-protocol/src/main/java/org/anarres/tftp/protocol/engine/AbstractTftpServer.java
// public abstract class AbstractTftpServer {
// 
//     public static final int DEFAULT_SERVER_PORT = 69;
// 
//     private final TftpDataProvider dataProvider;
//     private final int port;
// 
//     public AbstractTftpServer(@Nonnull TftpDataProvider dataProvider, @Nonnegative int port) {
//         this.dataProvider = dataProvider;
//         this.port = port;
//     }
// 
//     @Nonnull
//     public TftpDataProvider getDataProvider() {
//         return dataProvider;
//     }
// 
//     @Nonnegative
//     public int getPort() {
//         return port;
//     }
// 
//     @PostConstruct
//     public abstract void start() throws IOException, InterruptedException;
// 
//     @PreDestroy
//     public abstract void stop() throws IOException, InterruptedException;
// }
// 
// Path: tftp-protocol/src/main/java/org/anarres/tftp/protocol/resource/TftpDataProvider.java
// public interface TftpDataProvider {
// 
//     /**
//      * Returns the resource with the given name.
//      */
//     @CheckForNull
//     public TftpData open(@Nonnull String filename) throws IOException;
// }


import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.util.concurrent.DefaultThreadFactory;
import java.io.IOException;
import java.util.concurrent.ThreadFactory;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import org.anarres.tftp.protocol.engine.AbstractTftpServer;
import org.anarres.tftp.protocol.resource.TftpDataProvider;
    public void setDebug(boolean debug) {
        sharedHandlers.setDebug(debug);
    }

    @Nonnull
    public TftpChannelType getChannelType() {
        return channelType;
    }

    public void setChannelType(@Nonnull TftpChannelType channelType) {
        this.channelType = channelType;
    }

    @Override
    public void start() throws IOException, InterruptedException {
        TftpChannelType mode = getChannelType();

        ThreadFactory factory = new DefaultThreadFactory("tftp-server");
        EventLoopGroup group = mode.newEventLoopGroup(factory);

        Bootstrap b = new Bootstrap();
        b.group(group);
        b.channel(mode.getChannelType());
        b.handler(new TftpPipelineInitializer(sharedHandlers, new TftpServerHandler(sharedHandlers, getDataProvider())));
        channel = b.bind(getPort()).sync().channel();
    }

    @Override
    public void stop() throws IOException, InterruptedException {
        EventLoop loop = channel.eventLoop();
// Path: tftp-protocol/src/main/java/org/anarres/tftp/protocol/engine/AbstractTftpServer.java
// public abstract class AbstractTftpServer {
// 
//     public static final int DEFAULT_SERVER_PORT = 69;
// 
//     private final TftpDataProvider dataProvider;
//     private final int port;
// 
//     public AbstractTftpServer(@Nonnull TftpDataProvider dataProvider, @Nonnegative int port) {
//         this.dataProvider = dataProvider;
//         this.port = port;
//     }
// 
//     @Nonnull
//     public TftpDataProvider getDataProvider() {
//         return dataProvider;
//     }
// 
//     @Nonnegative
//     public int getPort() {
//         return port;
//     }
// 
//     @PostConstruct
//     public abstract void start() throws IOException, InterruptedException;
// 
//     @PreDestroy
//     public abstract void stop() throws IOException, InterruptedException;
// }
// 
// Path: tftp-protocol/src/main/java/org/anarres/tftp/protocol/resource/TftpDataProvider.java
// public interface TftpDataProvider {
// 
//     /**
//      * Returns the resource with the given name.
//      */
//     @CheckForNull
//     public TftpData open(@Nonnull String filename) throws IOException;
// }


// Path: tftp-server-netty/src/main/java/org/anarres/tftp/server/netty/TftpServer.java
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.util.concurrent.DefaultThreadFactory;
import java.io.IOException;
import java.util.concurrent.ThreadFactory;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import org.anarres.tftp.protocol.engine.AbstractTftpServer;
import org.anarres.tftp.protocol.resource.TftpDataProvider;

    public void setDebug(boolean debug) {
        sharedHandlers.setDebug(debug);
    }

    @Nonnull
    public TftpChannelType getChannelType() {
        return channelType;
    }

    public void setChannelType(@Nonnull TftpChannelType channelType) {
        this.channelType = channelType;
    }

    @Override
    public void start() throws IOException, InterruptedException {
        TftpChannelType mode = getChannelType();

        ThreadFactory factory = new DefaultThreadFactory("tftp-server");
        EventLoopGroup group = mode.newEventLoopGroup(factory);

        Bootstrap b = new Bootstrap();
        b.group(group);
        b.channel(mode.getChannelType());
        b.handler(new TftpPipelineInitializer(sharedHandlers, new TftpServerHandler(sharedHandlers, getDataProvider())));
        channel = b.bind(getPort()).sync().channel();
    }

    @Override
    public void stop() throws IOException, InterruptedException {
        EventLoop loop = channel.eventLoop();
        channel.close().sync();