// Path: heartbeat-common/src/main/java/com/heartbeat/common/array/ByteArray.java
// public final class ByteArray {
// 
//     private ByteArray() {
//     }
// 
//     /**
//      * Trims the given array. Finds the starting position of null index and copies with {@link Arrays#copyOf(boolean[], int)}
//      *
//      * @param bytes original array
//      * @return trimmed array
//      */
//     public static final byte[] trim(byte[] bytes) {
//         int i = bytes.length - 1;
//         while (i >= 0 && bytes[i] == 0) {
//             --i;
//         }
// 
//         return Arrays.copyOf(bytes, i + 1);
//     }
// 
// }
// 
// Path: heartbeat-log/src/main/java/com/heartbeat/log/Logger.java
// public final class Logger {
//     private static Level defaultPackageLevel = Level.INFO;
//     private static PrintStream stream = System.out;
//     //TODO: Appender  system
//     //TODO: Tag-level checks.
// 
//     private Logger() {
//     }
// 
//     public static Level getLevel() {
//         return defaultPackageLevel;
//     }
// 
//     public static void setLevel(Level defaultPackageLevel) {
//         Logger.defaultPackageLevel = defaultPackageLevel;
//     }
// 
//     public static final void trace(String tag, String message) {
//         print(Level.TRACE, tag, message);
// 
//     }
// 
//     public static final void trace(String tag, String message, Object... args) {
//         print(Level.TRACE, tag, message, args);
// 
//     }
// 
//     public static final void debug(String tag, String message) {
//         print(Level.DEBUG, tag, message);
// 
//     }
// 
//     public static final void debug(String tag, String message, Object... args) {
//         print(Level.DEBUG, tag, message, args);
// 
//     }
// 
//     public static final void info(String tag, String message) {
//         print(Level.INFO, tag, message);
// 
//     }
// 
//     public static final void info(String tag, String message, Object... args) {
//         print(Level.INFO, tag, message, args);
//     }
// 
//     public static final void warn(String tag, String message) {
//         print(Level.WARNING, tag, message);
//     }
// 
//     public static final void warn(String tag, String message, Object... args) {
//         print(Level.WARNING, tag, message, args);
//     }
// 
//     public static final void error(String tag, String message) {
//         print(Level.ERROR, tag, message);
//     }
// 
//     public static final void error(String tag, String message, Object... args) {
//         print(Level.ERROR, tag, message, args);
//     }
// 
//     public static final void error(String tag, String message, Exception ex) {
//         print(Level.ERROR, tag, message);
//         ex.printStackTrace(getStream());
//     }
// 
//     public static final void error(String tag, String message, Exception ex, Object... args) {
//         print(Level.ERROR, tag, message, args);
//         ex.printStackTrace(getStream());
//     }
// 
// 
//     private static final void print(Level level, String tag, String message) {
//         if (level.ordinal() < defaultPackageLevel.ordinal())
//             return;
//         StringBuilder builder = getBuilderWithDate(level, tag);
//         builder.append(message);
//         getStream().println(builder.toString());
//     }
// 
// 
//     private static final void print(Level level, String tag, String message, Object... args) {
//         if (level.ordinal() < defaultPackageLevel.ordinal())
//             return;
//         StringBuilder builder = getBuilderWithDate(level, tag);
//         builder.append(format(message, args));
//         getStream().println(builder.toString());
//     }
// 
//     private static final StringBuilder getBuilderWithDate(Level level, String tag) {
//         StringBuilder builder = new StringBuilder();
//         Calendar now = Calendar.getInstance();
//         builder.append('[');
//         builder.append(now.get(Calendar.YEAR));
//         builder.append('-');
//         builder.append(now.get(Calendar.MONTH));
//         builder.append('-');
//         builder.append(now.get(Calendar.DAY_OF_MONTH));
//         builder.append(' ');
//         builder.append(now.get(Calendar.HOUR_OF_DAY));
//         builder.append(':');
//         builder.append(now.get(Calendar.MINUTE));
//         builder.append(':');
//         builder.append(now.get(Calendar.SECOND));
//         builder.append(',');
//         builder.append(now.get(Calendar.MILLISECOND));
//         builder.append("]\t");
//         builder.append(level.name());
//         builder.append(" \t");
//         builder.append(tag);
//         builder.append(": \t");
//         return builder;
//     }
// 
//     public static PrintStream getStream() {
//         return stream;
//     }
// 
//     public static void setStream(PrintStream stream) {
//         Logger.stream = stream;
//     }
// 
//     public enum Level {
//         TRACE,
//         DEBUG,
//         INFO,
//         WARNING,
//         ERROR
//     }
// }


import com.heartbeat.common.array.ByteArray;
import com.heartbeat.log.Logger;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import static java.lang.String.format;
package com.heartbeat.network.udp;




/**
 * A static helper class for basic common UDP operations.
 */
public final class UDPOperations {
    private static final String TAG = UDPOperations.class.getName();

    private UDPOperations() {
    }

    /**
     * Sends a UDP datagram to the receiver
     *
     * @param socket       local socket
     * @param receiverIP   receiver IP address
     * @param receiverPort receiver port
     * @param data         data to send
     * @throws IOException
     */
    public static final void send(DatagramSocket socket, InetAddress receiverIP, int receiverPort, byte[] data) throws IOException {
        DatagramPacket sendPacket = new DatagramPacket(data, data.length, receiverIP, receiverPort);
        socket.send(sendPacket);
// Path: heartbeat-common/src/main/java/com/heartbeat/common/array/ByteArray.java
// public final class ByteArray {
// 
//     private ByteArray() {
//     }
// 
//     /**
//      * Trims the given array. Finds the starting position of null index and copies with {@link Arrays#copyOf(boolean[], int)}
//      *
//      * @param bytes original array
//      * @return trimmed array
//      */
//     public static final byte[] trim(byte[] bytes) {
//         int i = bytes.length - 1;
//         while (i >= 0 && bytes[i] == 0) {
//             --i;
//         }
// 
//         return Arrays.copyOf(bytes, i + 1);
//     }
// 
// }
// 
// Path: heartbeat-log/src/main/java/com/heartbeat/log/Logger.java
// public final class Logger {
//     private static Level defaultPackageLevel = Level.INFO;
//     private static PrintStream stream = System.out;
//     //TODO: Appender  system
//     //TODO: Tag-level checks.
// 
//     private Logger() {
//     }
// 
//     public static Level getLevel() {
//         return defaultPackageLevel;
//     }
// 
//     public static void setLevel(Level defaultPackageLevel) {
//         Logger.defaultPackageLevel = defaultPackageLevel;
//     }
// 
//     public static final void trace(String tag, String message) {
//         print(Level.TRACE, tag, message);
// 
//     }
// 
//     public static final void trace(String tag, String message, Object... args) {
//         print(Level.TRACE, tag, message, args);
// 
//     }
// 
//     public static final void debug(String tag, String message) {
//         print(Level.DEBUG, tag, message);
// 
//     }
// 
//     public static final void debug(String tag, String message, Object... args) {
//         print(Level.DEBUG, tag, message, args);
// 
//     }
// 
//     public static final void info(String tag, String message) {
//         print(Level.INFO, tag, message);
// 
//     }
// 
//     public static final void info(String tag, String message, Object... args) {
//         print(Level.INFO, tag, message, args);
//     }
// 
//     public static final void warn(String tag, String message) {
//         print(Level.WARNING, tag, message);
//     }
// 
//     public static final void warn(String tag, String message, Object... args) {
//         print(Level.WARNING, tag, message, args);
//     }
// 
//     public static final void error(String tag, String message) {
//         print(Level.ERROR, tag, message);
//     }
// 
//     public static final void error(String tag, String message, Object... args) {
//         print(Level.ERROR, tag, message, args);
//     }
// 
//     public static final void error(String tag, String message, Exception ex) {
//         print(Level.ERROR, tag, message);
//         ex.printStackTrace(getStream());
//     }
// 
//     public static final void error(String tag, String message, Exception ex, Object... args) {
//         print(Level.ERROR, tag, message, args);
//         ex.printStackTrace(getStream());
//     }
// 
// 
//     private static final void print(Level level, String tag, String message) {
//         if (level.ordinal() < defaultPackageLevel.ordinal())
//             return;
//         StringBuilder builder = getBuilderWithDate(level, tag);
//         builder.append(message);
//         getStream().println(builder.toString());
//     }
// 
// 
//     private static final void print(Level level, String tag, String message, Object... args) {
//         if (level.ordinal() < defaultPackageLevel.ordinal())
//             return;
//         StringBuilder builder = getBuilderWithDate(level, tag);
//         builder.append(format(message, args));
//         getStream().println(builder.toString());
//     }
// 
//     private static final StringBuilder getBuilderWithDate(Level level, String tag) {
//         StringBuilder builder = new StringBuilder();
//         Calendar now = Calendar.getInstance();
//         builder.append('[');
//         builder.append(now.get(Calendar.YEAR));
//         builder.append('-');
//         builder.append(now.get(Calendar.MONTH));
//         builder.append('-');
//         builder.append(now.get(Calendar.DAY_OF_MONTH));
//         builder.append(' ');
//         builder.append(now.get(Calendar.HOUR_OF_DAY));
//         builder.append(':');
//         builder.append(now.get(Calendar.MINUTE));
//         builder.append(':');
//         builder.append(now.get(Calendar.SECOND));
//         builder.append(',');
//         builder.append(now.get(Calendar.MILLISECOND));
//         builder.append("]\t");
//         builder.append(level.name());
//         builder.append(" \t");
//         builder.append(tag);
//         builder.append(": \t");
//         return builder;
//     }
// 
//     public static PrintStream getStream() {
//         return stream;
//     }
// 
//     public static void setStream(PrintStream stream) {
//         Logger.stream = stream;
//     }
// 
//     public enum Level {
//         TRACE,
//         DEBUG,
//         INFO,
//         WARNING,
//         ERROR
//     }
// }


// Path: heartbeat-network/src/main/java/com/heartbeat/network/udp/UDPOperations.java
import com.heartbeat.common.array.ByteArray;
import com.heartbeat.log.Logger;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import static java.lang.String.format;

package com.heartbeat.network.udp;




/**
 * A static helper class for basic common UDP operations.
 */
public final class UDPOperations {
    private static final String TAG = UDPOperations.class.getName();

    private UDPOperations() {
    }

    /**
     * Sends a UDP datagram to the receiver
     *
     * @param socket       local socket
     * @param receiverIP   receiver IP address
     * @param receiverPort receiver port
     * @param data         data to send
     * @throws IOException
     */
    public static final void send(DatagramSocket socket, InetAddress receiverIP, int receiverPort, byte[] data) throws IOException {
        DatagramPacket sendPacket = new DatagramPacket(data, data.length, receiverIP, receiverPort);
        socket.send(sendPacket);
        Logger.info(TAG, format("%s[%d]\tPacket sent\tlength: %d", receiverIP.getHostAddress(), receiverPort, data.length));