// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/exception/IncorrectHeaderException.java
// public class IncorrectHeaderException extends Exception {
// 
//     public IncorrectHeaderException(final String msg) {
//         super(msg);
//     }
// 
// }
// 
// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/header/AddressType.java
// public enum AddressType {
//     IPv4((byte) 0),
//     IPv6((byte) 1),
//     DOMAIN((byte) 2);
// 
//     private final byte value;
// 
//     AddressType(final byte value) {
//         this.value = value;
//     }
// 
//     public byte getValue() {
//         return value;
//     }
// 
//     private static final AddressType[] types = AddressType.values();
// 
//     public static AddressType fromByte(final byte type) {
//         try {
//             return types[type];
//         } catch (final ArrayIndexOutOfBoundsException e) {
//             throw new IllegalArgumentException("Type byte " + type + " not found");
//         }
//     }
// }
// 
// Path: dragonite-utils/src/main/java/com/vecsight/dragonite/utils/binary/BinaryReader.java
// public class BinaryReader {
// 
//     private final ByteBuffer byteBuffer;
// 
//     public BinaryReader(final byte[] bytes) {
//         byteBuffer = ByteBuffer.wrap(bytes);
//     }
// 
//     public byte getSignedByte() {
//         return byteBuffer.get();
//     }
// 
//     public short getUnsignedByte() {
//         return (short) (byteBuffer.get() & (short) 0xff);
//     }
// 
//     public short getSignedShort() {
//         return byteBuffer.getShort();
//     }
// 
//     public int getUnsignedShort() {
//         return byteBuffer.getShort() & 0xffff;
//     }
// 
//     public int getSignedInt() {
//         return byteBuffer.getInt();
//     }
// 
//     public long getUnsignedInt() {
//         return (long) byteBuffer.getInt() & 0xffffffffL;
//     }
// 
//     public void getBytes(final byte[] bytes) {
//         byteBuffer.get(bytes);
//     }
// 
//     public byte[] getBytesGroupWithByteLength() {
//         final short len = getUnsignedByte();
//         final byte[] bytes = new byte[len];
//         byteBuffer.get(bytes);
//         return bytes;
//     }
// 
//     public byte[] getBytesGroupWithShortLength() {
//         final int len = getUnsignedShort();
//         final byte[] bytes = new byte[len];
//         byteBuffer.get(bytes);
//         return bytes;
//     }
// 
//     public boolean getBoolean() {
//         return byteBuffer.get() != 0;
//     }
// 
//     public int remaining() {
//         return byteBuffer.remaining();
//     }
// 
// }
// 
// Path: dragonite-utils/src/main/java/com/vecsight/dragonite/utils/binary/BinaryWriter.java
// public class BinaryWriter {
// 
//     private final ByteBuffer byteBuffer;
// 
//     public BinaryWriter(final int capacity) {
//         byteBuffer = ByteBuffer.allocate(capacity);
//     }
// 
//     public BinaryWriter putSignedByte(final byte sb) {
//         byteBuffer.put(sb);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedByte(final short ub) {
//         byteBuffer.put((byte) (ub & 0xff));
//         return this;
//     }
// 
//     public BinaryWriter putSignedShort(final short ss) {
//         byteBuffer.putShort(ss);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedShort(final int us) {
//         byteBuffer.putShort((short) (us & 0xffff));
//         return this;
//     }
// 
//     public BinaryWriter putSignedInt(final int si) {
//         byteBuffer.putInt(si);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedInt(final long ui) {
//         byteBuffer.putInt((int) (ui & 0xffffffffL));
//         return this;
//     }
// 
//     public BinaryWriter putBytes(final byte[] bytes) {
//         byteBuffer.put(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBytesGroupWithByteLength(final byte[] bytes) {
//         putUnsignedByte((short) bytes.length);
//         putBytes(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBytesGroupWithShortLength(final byte[] bytes) {
//         putUnsignedShort(bytes.length);
//         putBytes(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBoolean(final boolean b) {
//         byteBuffer.put((byte) (b ? 1 : 0));
//         return this;
//     }
// 
//     public byte[] toBytes() {
//         return byteBuffer.array();
//     }
// 
// }


import com.vecsight.dragonite.proxy.exception.IncorrectHeaderException;
import com.vecsight.dragonite.proxy.header.AddressType;
import com.vecsight.dragonite.utils.binary.BinaryReader;
import com.vecsight.dragonite.utils.binary.BinaryWriter;
import java.nio.BufferUnderflowException;
/*
 * The Dragonite Project
 * -------------------------
 * See the LICENSE file in the root directory for license information.
 */


package com.vecsight.dragonite.proxy.header.mux;



/*
 * addrType 1 SB
 * addr     [4B/16B/1+length]
 * port     2 US
 * UDP mode 1 BOOL
 */

public class MuxConnectionRequestHeader {

    private AddressType type;

    private byte[] addr;

    private int port;

    private boolean udpMode;

    public MuxConnectionRequestHeader(final AddressType type, final byte[] addr, final int port, final boolean udpMode) {
        this.type = type;
        this.addr = addr;
        this.port = port;
        this.udpMode = udpMode;
    }

    public MuxConnectionRequestHeader(final byte[] header) throws IncorrectHeaderException {
// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/exception/IncorrectHeaderException.java
// public class IncorrectHeaderException extends Exception {
// 
//     public IncorrectHeaderException(final String msg) {
//         super(msg);
//     }
// 
// }
// 
// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/header/AddressType.java
// public enum AddressType {
//     IPv4((byte) 0),
//     IPv6((byte) 1),
//     DOMAIN((byte) 2);
// 
//     private final byte value;
// 
//     AddressType(final byte value) {
//         this.value = value;
//     }
// 
//     public byte getValue() {
//         return value;
//     }
// 
//     private static final AddressType[] types = AddressType.values();
// 
//     public static AddressType fromByte(final byte type) {
//         try {
//             return types[type];
//         } catch (final ArrayIndexOutOfBoundsException e) {
//             throw new IllegalArgumentException("Type byte " + type + " not found");
//         }
//     }
// }
// 
// Path: dragonite-utils/src/main/java/com/vecsight/dragonite/utils/binary/BinaryReader.java
// public class BinaryReader {
// 
//     private final ByteBuffer byteBuffer;
// 
//     public BinaryReader(final byte[] bytes) {
//         byteBuffer = ByteBuffer.wrap(bytes);
//     }
// 
//     public byte getSignedByte() {
//         return byteBuffer.get();
//     }
// 
//     public short getUnsignedByte() {
//         return (short) (byteBuffer.get() & (short) 0xff);
//     }
// 
//     public short getSignedShort() {
//         return byteBuffer.getShort();
//     }
// 
//     public int getUnsignedShort() {
//         return byteBuffer.getShort() & 0xffff;
//     }
// 
//     public int getSignedInt() {
//         return byteBuffer.getInt();
//     }
// 
//     public long getUnsignedInt() {
//         return (long) byteBuffer.getInt() & 0xffffffffL;
//     }
// 
//     public void getBytes(final byte[] bytes) {
//         byteBuffer.get(bytes);
//     }
// 
//     public byte[] getBytesGroupWithByteLength() {
//         final short len = getUnsignedByte();
//         final byte[] bytes = new byte[len];
//         byteBuffer.get(bytes);
//         return bytes;
//     }
// 
//     public byte[] getBytesGroupWithShortLength() {
//         final int len = getUnsignedShort();
//         final byte[] bytes = new byte[len];
//         byteBuffer.get(bytes);
//         return bytes;
//     }
// 
//     public boolean getBoolean() {
//         return byteBuffer.get() != 0;
//     }
// 
//     public int remaining() {
//         return byteBuffer.remaining();
//     }
// 
// }
// 
// Path: dragonite-utils/src/main/java/com/vecsight/dragonite/utils/binary/BinaryWriter.java
// public class BinaryWriter {
// 
//     private final ByteBuffer byteBuffer;
// 
//     public BinaryWriter(final int capacity) {
//         byteBuffer = ByteBuffer.allocate(capacity);
//     }
// 
//     public BinaryWriter putSignedByte(final byte sb) {
//         byteBuffer.put(sb);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedByte(final short ub) {
//         byteBuffer.put((byte) (ub & 0xff));
//         return this;
//     }
// 
//     public BinaryWriter putSignedShort(final short ss) {
//         byteBuffer.putShort(ss);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedShort(final int us) {
//         byteBuffer.putShort((short) (us & 0xffff));
//         return this;
//     }
// 
//     public BinaryWriter putSignedInt(final int si) {
//         byteBuffer.putInt(si);
//         return this;
//     }
// 
//     public BinaryWriter putUnsignedInt(final long ui) {
//         byteBuffer.putInt((int) (ui & 0xffffffffL));
//         return this;
//     }
// 
//     public BinaryWriter putBytes(final byte[] bytes) {
//         byteBuffer.put(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBytesGroupWithByteLength(final byte[] bytes) {
//         putUnsignedByte((short) bytes.length);
//         putBytes(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBytesGroupWithShortLength(final byte[] bytes) {
//         putUnsignedShort(bytes.length);
//         putBytes(bytes);
//         return this;
//     }
// 
//     public BinaryWriter putBoolean(final boolean b) {
//         byteBuffer.put((byte) (b ? 1 : 0));
//         return this;
//     }
// 
//     public byte[] toBytes() {
//         return byteBuffer.array();
//     }
// 
// }


// Path: dragonite-proxy/src/main/java/com/vecsight/dragonite/proxy/header/mux/MuxConnectionRequestHeader.java
import com.vecsight.dragonite.proxy.exception.IncorrectHeaderException;
import com.vecsight.dragonite.proxy.header.AddressType;
import com.vecsight.dragonite.utils.binary.BinaryReader;
import com.vecsight.dragonite.utils.binary.BinaryWriter;
import java.nio.BufferUnderflowException;

/*
 * The Dragonite Project
 * -------------------------
 * See the LICENSE file in the root directory for license information.
 */


package com.vecsight.dragonite.proxy.header.mux;



/*
 * addrType 1 SB
 * addr     [4B/16B/1+length]
 * port     2 US
 * UDP mode 1 BOOL
 */

public class MuxConnectionRequestHeader {

    private AddressType type;

    private byte[] addr;

    private int port;

    private boolean udpMode;

    public MuxConnectionRequestHeader(final AddressType type, final byte[] addr, final int port, final boolean udpMode) {
        this.type = type;
        this.addr = addr;
        this.port = port;
        this.udpMode = udpMode;
    }

    public MuxConnectionRequestHeader(final byte[] header) throws IncorrectHeaderException {
        final BinaryReader reader = new BinaryReader(header);