public ZMonitor(ZContext ctx, Socket socket)
    {
        Objects.requireNonNull(ctx, "ZMonitor works only with a supplied context");
        Objects.requireNonNull(socket, "Socket has to be supplied");
        final MonitorActor actor = new MonitorActor(socket);
        final ZActor zactor = new ZActor(ctx, actor, UUID.randomUUID().toString());

        agent = zactor.agent();
        exit = zactor.exit();

        // wait for the start of the actor
        agent.recv().destroy();
    }
@Test
    public void testZMonitor()
    {
        final ZContext ctx = new ZContext();
        final Socket client = ctx.createSocket(SocketType.DEALER);
        final Socket server = ctx.createSocket(SocketType.DEALER);

        final ZMonitor clientMonitor = new ZMonitor(ctx, client);
        clientMonitor.verbose(true);
        clientMonitor.add(Event.LISTENING, Event.CONNECTED, Event.DISCONNECTED, Event.ACCEPT_FAILED);
        clientMonitor.remove(Event.ACCEPT_FAILED);

        clientMonitor.start();

        final ZMonitor serverMonitor = new ZMonitor(ctx, server);
        serverMonitor.verbose(false);
        serverMonitor.add(Event.LISTENING, Event.ACCEPTED, Event.HANDSHAKE_PROTOCOL);
        serverMonitor.start();

        //  Check server is now listening
        int port = server.bindToRandomPort("tcp://127.0.0.1");
        ZEvent received = serverMonitor.nextEvent();
        Assert.assertEquals(Event.LISTENING, received.type);

        //  Check server connected to client
        boolean rc = client.connect("tcp://127.0.0.1:" + port);
        Assert.assertTrue(rc);
        received = clientMonitor.nextEvent();
        assertThat(received.type, is(Event.CONNECTED));

        //  Check server accepted connection
        received = serverMonitor.nextEvent(true);
        Assert.assertEquals(Event.ACCEPTED, received.type);

        //  Check server accepted connection
        received = serverMonitor.nextEvent(-1); // timeout -1 aka blocking
        Assert.assertEquals(Event.HANDSHAKE_PROTOCOL, received.type);

        received = serverMonitor.nextEvent(false); // with no blocking
        Assert.assertNull(received);

        received = serverMonitor.nextEvent(10); // timeout
        Assert.assertNull(received);

        client.close();
        clientMonitor.close();

        server.close();
        serverMonitor.close();

        ctx.close();
    }