class SocketIoMemoryAdapter extends SocketIoAdapter {

    @Override
    public synchronized void broadcast(Packet packet, String[] rooms, String[] socketsExcluded) throws IllegalArgumentException {
        if (packet == null) {
            throw new IllegalArgumentException("packet must not be null.");
        }

        socketsExcluded = (socketsExcluded != null)? socketsExcluded : EMPTY_SOCKET_EXCLUSION;
        final Set<String> socketsExcludedSet = new HashSet<>();
        Collections.addAll(socketsExcludedSet, socketsExcluded);

        final Map<String, SocketIoSocket> connectedSockets = mNamespace.getConnectedSockets();

        if (rooms != null) {
            final Set<String> sentSocketIds = new HashSet<>();  // To ensure only one packet is sent if socket is added to multiple rooms

            for (String room : rooms) {
                if (mRoomSockets.containsKey(room)) {
                    final Set<SocketIoSocket> sockets = mRoomSockets.get(room);
                    for (SocketIoSocket socket : sockets) {
                        if (!socketsExcludedSet.contains(socket.getId()) &&
                                !sentSocketIds.contains(socket.getId()) &&
                                connectedSockets.containsKey(socket.getId())) {
                            socket.sendPacket(packet);
                            sentSocketIds.add(socket.getId());
                        }
                    }
                }
            }
        } else {
            for (String socketId : mSocketRooms.keySet()) {
                if (!socketsExcludedSet.contains(socketId)) {
                    final SocketIoSocket socket = connectedSockets.get(socketId);
                    if (socket != null) {
                        socket.sendPacket(packet);
                    }
                }
            }
        }
    }

    private  SocketIoMemoryAdapter(SocketIoNamespace namespace);

}