@Override
    public IOAdapter createAdapter(final URL url) {
        return new IOAdapter() {
            SocketChannel socketChannel;
            ByteBuffer byteBuffer = ByteBuffer.allocate(2048);

            @Override
            public void open() throws IOException {
                socketChannel = SocketChannel.open(
                        new InetSocketAddress(url.getHost(), url.getPort() != -1 ? url.getPort() : url.getDefaultPort()));
            }

            @Override
            public int read(byte[] buffer) throws IOException {
                int nRead = 0;
                if(byteBuffer.position() == 0) {
                    nRead = socketChannel.read(byteBuffer);
                    byteBuffer.flip();
                }
                if(nRead > 0 || byteBuffer.limit() > 0) {
                    nRead = Math.min(byteBuffer.limit() - byteBuffer.position(), buffer.length);
                    byteBuffer.get(buffer, 0, nRead);
                    if(byteBuffer.position() == byteBuffer.limit())
                        byteBuffer.clear();
                }
                return nRead;
            }

            @Override
            public int write(byte[] buffer) throws IOException {
                return write(buffer, 0, buffer.length);
            }

            @Override
            public int write(byte[] buffer, int offset, int length) throws IOException {
                return socketChannel.write(ByteBuffer.wrap(buffer, offset, length));
            }

            @Override
            public void close() throws IOException {
                if(socketChannel != null) socketChannel.close();
            }
        };
    }