public boolean monitor (final String addr_, int events_) {
        boolean rc;
        if (ctx_terminated) {
            ZError.errno(ZError.ETERM);
            return false;
        }

        // Support deregistering monitoring endpoints as well
        if (addr_ == null) {
            stop_monitor ();
            return true;
        }

        //  Parse addr_ string.
        URI uri;
        try {
            uri = new URI(addr_);
        } catch (URISyntaxException e) {
            ZError.errno (ZError.EINVAL);
            throw new IllegalArgumentException (e);
        }
        String protocol = uri.getScheme();
        String address = uri.getAuthority();
        String path = uri.getPath();
        if (address == null)
            address = path;

        check_protocol (protocol);

        // Event notification only supported over inproc://
        if (!protocol.equals ("inproc")) {
            ZError.errno (ZError.EPROTONOSUPPORT);
            return false;
        }

        // Register events to monitor
        monitor_events = events_;

        monitor_socket = get_ctx ().create_socket(ZMQ.ZMQ_PAIR);
        if (monitor_socket == null)
            return false;

        // Never block context termination on pending event messages
        int linger = 0;
        rc = monitor_socket.setsockopt (ZMQ.ZMQ_LINGER, linger);
        if (!rc)
             stop_monitor ();

        // Spawn the monitor socket endpoint
        rc = monitor_socket.bind (addr_);
        if (!rc)
             stop_monitor ();
        return rc;
    }