// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Packets/AppPacket.java
// public class AppPacket extends Packet {
//     public static String CID = "app";
//     public static String TYPE = "pack";
// 
//     public AppPacket() {
//         cid = CID;
//         type = TYPE;
//         uid = 0;
//     }
// }
// 
// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Packets/Packet.java
// public class Packet {
//     @SerializedName("t")
//     public String type;
// 
//     public String tcid;
//     public Integer i;
//     public Integer uid;
//     public String cid;
// 
//     @SerializedName("pack")
//     public String encryptedPack;
// 
//     public transient Pack pack;
// }
// 
// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Utils.java
// public class Utils {
// 
//     public static class Unzipped {
//         public final String[] keys;
//         public final Integer[] values;
// 
//         public Unzipped(String[] keys, Integer[] values) {
//             this.keys = keys;
//             this.values = values;
//         }
//     }
// 
//     public static Map<String, Integer> zip(String[] keys, Integer[] values) throws IllegalArgumentException {
//         if (keys.length != values.length)
//             throw new IllegalArgumentException("Length of keys and values must match");
// 
//         Map<String, Integer> zipped = new HashMap<>();
//         for (int i = 0; i < keys.length; i++) {
//             zipped.put(keys[i], values[i]);
//         }
// 
//         return zipped;
//     }
// 
//     public static Unzipped unzip(Map<String, Integer> map) {
//         return new Unzipped(map.keySet().toArray(new String[0]), map.values().toArray(new Integer[0]));
//     }
// 
//     public static Map<String, Integer> getValues(DatPack pack) {
//         return zip(pack.keys, pack.values);
//     }
// 
//     public static String serializePacket(Packet packet, DeviceKeyChain deviceKeyChain) {
//         GsonBuilder gsonBuilder = new GsonBuilder();
//         Gson gson = gsonBuilder.create();
// 
//         if (packet.pack != null) {
//             String key = getKey(deviceKeyChain, packet);
//             String plainPack = gson.toJson(packet.pack);
//             packet.encryptedPack = tomikaa.greeremote.Gree.Crypto.encrypt(plainPack, key);
//         }
// 
//         return gson.toJson(packet);
//     }
// 
//     public static Packet deserializePacket(String jsonString, DeviceKeyChain deviceKeyChain) {
//         GsonBuilder gsonBuilder = new GsonBuilder();
//         gsonBuilder.registerTypeAdapter(Pack.class, new PackDeserializer());
// 
//         Gson gson = gsonBuilder.create();
// 
//         Packet packet = gson.fromJson(jsonString, Packet.class);
// 
//         if (packet.encryptedPack != null) {
//             String key = getKey(deviceKeyChain, packet);
//             String plainPack = Crypto.decrypt(packet.encryptedPack, key);
//             packet.pack = gson.fromJson(plainPack, Pack.class);
//         }
// 
//         return packet;
//     }
// 
//     private static String getKey(DeviceKeyChain keyChain, Packet packet) {
//         String key = Crypto.GENERIC_KEY;
// 
//         Log.i("getKey", String.format("packet.cid: %s, packet.tcid: %s", packet.cid, packet.tcid));
// 
//         if (keyChain != null) {
//             if (keyChain.containsKey(packet.cid)) {
//                 key = keyChain.getKey(packet.cid);
//             } else if (keyChain.containsKey(packet.tcid)) {
//                 key = keyChain.getKey(packet.tcid);
//             }
//         }
// 
//         return key;
//     }
// }


import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.util.Log;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.ArrayList;
import tomikaa.greeremote.Gree.Packets.AppPacket;
import tomikaa.greeremote.Gree.Packets.Packet;
import tomikaa.greeremote.Gree.Utils;
        Packet[] responses = new Packet[0];

        if (requests == null || requests.length == 0)
            return responses;

        if (!createSocket())
            return responses;

        try {
            for (Packet request : requests)
                broadcastPacket(request);
            responses = receivePackets(TIMEOUT_MS);
        } catch (Exception e) {
            Log.e(LOG_TAG, "Error: " + e.getMessage());
        } finally {
            closeSocket();
        }

        return responses;
    }

    @Override
    protected void onPostExecute(Packet[] responses) {
        super.onPostExecute(responses);

        if (mCommunicationFinishedListener != null)
            mCommunicationFinishedListener.onFinished();
    }

    private void broadcastPacket(Packet packet) throws IOException {
// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Packets/AppPacket.java
// public class AppPacket extends Packet {
//     public static String CID = "app";
//     public static String TYPE = "pack";
// 
//     public AppPacket() {
//         cid = CID;
//         type = TYPE;
//         uid = 0;
//     }
// }
// 
// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Packets/Packet.java
// public class Packet {
//     @SerializedName("t")
//     public String type;
// 
//     public String tcid;
//     public Integer i;
//     public Integer uid;
//     public String cid;
// 
//     @SerializedName("pack")
//     public String encryptedPack;
// 
//     public transient Pack pack;
// }
// 
// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Utils.java
// public class Utils {
// 
//     public static class Unzipped {
//         public final String[] keys;
//         public final Integer[] values;
// 
//         public Unzipped(String[] keys, Integer[] values) {
//             this.keys = keys;
//             this.values = values;
//         }
//     }
// 
//     public static Map<String, Integer> zip(String[] keys, Integer[] values) throws IllegalArgumentException {
//         if (keys.length != values.length)
//             throw new IllegalArgumentException("Length of keys and values must match");
// 
//         Map<String, Integer> zipped = new HashMap<>();
//         for (int i = 0; i < keys.length; i++) {
//             zipped.put(keys[i], values[i]);
//         }
// 
//         return zipped;
//     }
// 
//     public static Unzipped unzip(Map<String, Integer> map) {
//         return new Unzipped(map.keySet().toArray(new String[0]), map.values().toArray(new Integer[0]));
//     }
// 
//     public static Map<String, Integer> getValues(DatPack pack) {
//         return zip(pack.keys, pack.values);
//     }
// 
//     public static String serializePacket(Packet packet, DeviceKeyChain deviceKeyChain) {
//         GsonBuilder gsonBuilder = new GsonBuilder();
//         Gson gson = gsonBuilder.create();
// 
//         if (packet.pack != null) {
//             String key = getKey(deviceKeyChain, packet);
//             String plainPack = gson.toJson(packet.pack);
//             packet.encryptedPack = tomikaa.greeremote.Gree.Crypto.encrypt(plainPack, key);
//         }
// 
//         return gson.toJson(packet);
//     }
// 
//     public static Packet deserializePacket(String jsonString, DeviceKeyChain deviceKeyChain) {
//         GsonBuilder gsonBuilder = new GsonBuilder();
//         gsonBuilder.registerTypeAdapter(Pack.class, new PackDeserializer());
// 
//         Gson gson = gsonBuilder.create();
// 
//         Packet packet = gson.fromJson(jsonString, Packet.class);
// 
//         if (packet.encryptedPack != null) {
//             String key = getKey(deviceKeyChain, packet);
//             String plainPack = Crypto.decrypt(packet.encryptedPack, key);
//             packet.pack = gson.fromJson(plainPack, Pack.class);
//         }
// 
//         return packet;
//     }
// 
//     private static String getKey(DeviceKeyChain keyChain, Packet packet) {
//         String key = Crypto.GENERIC_KEY;
// 
//         Log.i("getKey", String.format("packet.cid: %s, packet.tcid: %s", packet.cid, packet.tcid));
// 
//         if (keyChain != null) {
//             if (keyChain.containsKey(packet.cid)) {
//                 key = keyChain.getKey(packet.cid);
//             } else if (keyChain.containsKey(packet.tcid)) {
//                 key = keyChain.getKey(packet.tcid);
//             }
//         }
// 
//         return key;
//     }
// }


// Path: GreeRemoteAndroid/app/src/main/java/tomikaa/greeremote/Gree/Network/AsyncCommunicator.java
import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.util.Log;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.ArrayList;
import tomikaa.greeremote.Gree.Packets.AppPacket;
import tomikaa.greeremote.Gree.Packets.Packet;
import tomikaa.greeremote.Gree.Utils;

        Packet[] responses = new Packet[0];

        if (requests == null || requests.length == 0)
            return responses;

        if (!createSocket())
            return responses;

        try {
            for (Packet request : requests)
                broadcastPacket(request);
            responses = receivePackets(TIMEOUT_MS);
        } catch (Exception e) {
            Log.e(LOG_TAG, "Error: " + e.getMessage());
        } finally {
            closeSocket();
        }

        return responses;
    }

    @Override
    protected void onPostExecute(Packet[] responses) {
        super.onPostExecute(responses);

        if (mCommunicationFinishedListener != null)
            mCommunicationFinishedListener.onFinished();
    }

    private void broadcastPacket(Packet packet) throws IOException {
        String data = Utils.serializePacket(packet, mKeyChain);