// Path: src/net/corpwar/lib/corpnet/util/PeerConnected.java
// public class PeerConnected implements Serializable{
// 
//     public PeerConnected(String ipToPeer, int peerPort, long pingTime) {
//         this.peerPort = peerPort;
//         this.ipToPeer = ipToPeer;
//         this.pingTime = pingTime;
//     }
// 
//     public int peerPort;
// 
//     public String ipToPeer;
// 
//     public long pingTime;
// }
// 
// Path: src/net/corpwar/lib/corpnet/util/PeerList.java
// public class PeerList implements Serializable {
// 
//     public List<PeerConnected> peerConnected = new ArrayList<>();
// 
// 
// 
// }
// 
// Path: src/net/corpwar/lib/corpnet/util/SendDataQue.java
// public class SendDataQue {
// 
//     // Data to send
//     private byte[] aByte;
// 
//     // What kind of message to send
//     private NetworkSendType networkSendType;
// 
//     // When this data was added for sending
//     private long addedTime;
// 
//     public SendDataQue() {
//     }
// 
//     public SendDataQue setValues(byte[] bytes, NetworkSendType networkSendType) {
//         this.aByte = bytes;
//         this.networkSendType = networkSendType;
//         this.addedTime = System.currentTimeMillis();
//         return this;
//     }
// 
//     public byte[] getaByte() {
//         return aByte;
//     }
// 
//     public NetworkSendType getNetworkSendType() {
//         return networkSendType;
//     }
// 
//     public long getAddedTime() {
//         return addedTime;
//     }
// }
// 
// Path: src/net/corpwar/lib/corpnet/util/SerializationUtils.java
// public class SerializationUtils {
// 
//     private static SerializationUtils serializationUtils = null;
//     private static final Logger LOG = Logger.getLogger(SerializationUtils.class.getName());
//     private static final ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 
// 
//     private SerializationUtils() {
//     }
// 
//     public static SerializationUtils getInstance() {
//         if (serializationUtils == null) {
//             serializationUtils = new SerializationUtils();
//         }
//         return serializationUtils;
//     }
// 
//     public <T> byte[] serialize(T obj) {
//         ObjectOutputStream oos = null;
//         try {
//             oos = new ObjectOutputStream(baos);
//             oos.writeObject(obj);
//             oos.reset();
//         } catch (IOException e) {
//             LOG.log(Level.SEVERE, "Error IOException", e);
//         } finally {
//             if (oos != null) {
//                 try {
//                     oos.close();
//                 } catch (IOException e) {
//                     LOG.log(Level.SEVERE, "Error IOException", e);
//                 }
//             }
//         }
//         byte[] byteObj = baos.toByteArray();
//         baos.reset();
//         return byteObj;
//     }
// 
//     public <T> T deserialize(byte[] bytes) {
//         T obj = null;
//         ByteArrayInputStream bais = null;
//         ObjectInputStream ois = null;
// 
//         try {
//             bais = new ByteArrayInputStream(bytes);
//             ois = new ObjectInputStream(bais);
//             obj = (T) ois.readObject();
//         } catch (IOException e) {
//             LOG.log(Level.SEVERE, "Error IOException", e);
//         } catch (ClassNotFoundException e) {
//             LOG.log(Level.SEVERE, "Error Class not found", e);
//             return null;
//         } finally {
//             if (ois != null) {
//                 try {
//                     ois.close();
//                 } catch (IOException e) {
//                     LOG.log(Level.SEVERE, "Error IOException", e);
//                 }
//             }
//         }
//         return obj;
//     }
// }


import java.util.logging.Level;
import java.util.logging.Logger;
import net.corpwar.lib.corpnet.master.*;
import net.corpwar.lib.corpnet.util.PeerConnected;
import net.corpwar.lib.corpnet.util.PeerList;
import net.corpwar.lib.corpnet.util.SendDataQue;
import net.corpwar.lib.corpnet.util.SerializationUtils;
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
    }

    public PeerToPeer(int port, String ipAddress, int maxConnections) {
        this.port = port;
        this.ipAddress = ipAddress;
        byteBuffer = ByteBuffer.allocate(byteBufferSize);
        peers = new ConcurrentHashMap<>(maxConnections);
        this.maxConnections = maxConnections;
        protocolVersionHash = protocalVersion.hashCode();
    }

    /**
     * Start server if it's not running
     */
    public void startPeer() {
        if (peerThread == null || !peerThread.isAlive()) {
            running = true;
            peerThread = new PeerThread();
            peerThread.start();
        }
        if (!handleConnection.isAlive()) {
            handleConnection.start();
        }
    }

    public void connectToPeer(int port, String ipAddress) {
        try {
            Connection connection = new Connection(InetAddress.getByName(ipAddress), port);
            connection.updateTime();
            peers.put(connection.getConnectionId(), connection);
// Path: src/net/corpwar/lib/corpnet/util/PeerConnected.java
// public class PeerConnected implements Serializable{
// 
//     public PeerConnected(String ipToPeer, int peerPort, long pingTime) {
//         this.peerPort = peerPort;
//         this.ipToPeer = ipToPeer;
//         this.pingTime = pingTime;
//     }
// 
//     public int peerPort;
// 
//     public String ipToPeer;
// 
//     public long pingTime;
// }
// 
// Path: src/net/corpwar/lib/corpnet/util/PeerList.java
// public class PeerList implements Serializable {
// 
//     public List<PeerConnected> peerConnected = new ArrayList<>();
// 
// 
// 
// }
// 
// Path: src/net/corpwar/lib/corpnet/util/SendDataQue.java
// public class SendDataQue {
// 
//     // Data to send
//     private byte[] aByte;
// 
//     // What kind of message to send
//     private NetworkSendType networkSendType;
// 
//     // When this data was added for sending
//     private long addedTime;
// 
//     public SendDataQue() {
//     }
// 
//     public SendDataQue setValues(byte[] bytes, NetworkSendType networkSendType) {
//         this.aByte = bytes;
//         this.networkSendType = networkSendType;
//         this.addedTime = System.currentTimeMillis();
//         return this;
//     }
// 
//     public byte[] getaByte() {
//         return aByte;
//     }
// 
//     public NetworkSendType getNetworkSendType() {
//         return networkSendType;
//     }
// 
//     public long getAddedTime() {
//         return addedTime;
//     }
// }
// 
// Path: src/net/corpwar/lib/corpnet/util/SerializationUtils.java
// public class SerializationUtils {
// 
//     private static SerializationUtils serializationUtils = null;
//     private static final Logger LOG = Logger.getLogger(SerializationUtils.class.getName());
//     private static final ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 
// 
//     private SerializationUtils() {
//     }
// 
//     public static SerializationUtils getInstance() {
//         if (serializationUtils == null) {
//             serializationUtils = new SerializationUtils();
//         }
//         return serializationUtils;
//     }
// 
//     public <T> byte[] serialize(T obj) {
//         ObjectOutputStream oos = null;
//         try {
//             oos = new ObjectOutputStream(baos);
//             oos.writeObject(obj);
//             oos.reset();
//         } catch (IOException e) {
//             LOG.log(Level.SEVERE, "Error IOException", e);
//         } finally {
//             if (oos != null) {
//                 try {
//                     oos.close();
//                 } catch (IOException e) {
//                     LOG.log(Level.SEVERE, "Error IOException", e);
//                 }
//             }
//         }
//         byte[] byteObj = baos.toByteArray();
//         baos.reset();
//         return byteObj;
//     }
// 
//     public <T> T deserialize(byte[] bytes) {
//         T obj = null;
//         ByteArrayInputStream bais = null;
//         ObjectInputStream ois = null;
// 
//         try {
//             bais = new ByteArrayInputStream(bytes);
//             ois = new ObjectInputStream(bais);
//             obj = (T) ois.readObject();
//         } catch (IOException e) {
//             LOG.log(Level.SEVERE, "Error IOException", e);
//         } catch (ClassNotFoundException e) {
//             LOG.log(Level.SEVERE, "Error Class not found", e);
//             return null;
//         } finally {
//             if (ois != null) {
//                 try {
//                     ois.close();
//                 } catch (IOException e) {
//                     LOG.log(Level.SEVERE, "Error IOException", e);
//                 }
//             }
//         }
//         return obj;
//     }
// }


// Path: src/net/corpwar/lib/corpnet/PeerToPeer.java
import java.util.logging.Level;
import java.util.logging.Logger;
import net.corpwar.lib.corpnet.master.*;
import net.corpwar.lib.corpnet.util.PeerConnected;
import net.corpwar.lib.corpnet.util.PeerList;
import net.corpwar.lib.corpnet.util.SendDataQue;
import net.corpwar.lib.corpnet.util.SerializationUtils;
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;

    }

    public PeerToPeer(int port, String ipAddress, int maxConnections) {
        this.port = port;
        this.ipAddress = ipAddress;
        byteBuffer = ByteBuffer.allocate(byteBufferSize);
        peers = new ConcurrentHashMap<>(maxConnections);
        this.maxConnections = maxConnections;
        protocolVersionHash = protocalVersion.hashCode();
    }

    /**
     * Start server if it's not running
     */
    public void startPeer() {
        if (peerThread == null || !peerThread.isAlive()) {
            running = true;
            peerThread = new PeerThread();
            peerThread.start();
        }
        if (!handleConnection.isAlive()) {
            handleConnection.start();
        }
    }

    public void connectToPeer(int port, String ipAddress) {
        try {
            Connection connection = new Connection(InetAddress.getByName(ipAddress), port);
            connection.updateTime();
            peers.put(connection.getConnectionId(), connection);
            connection.addToSendQue(SerializationUtils.getInstance().serialize("Knock knock peer"), NetworkSendType.PEER_DATA);