class ClientCacheQueryContinuousHandle implements CacheEntryUpdatedListener<Object, Object>, ClientCloseableResource {
    /** */
    private final ClientConnectionContext ctx;

    /** */
    private final AtomicBoolean closeGuard = new AtomicBoolean();

    /** */
    private volatile Long id;

    /** */
    private volatile QueryCursor<?> cur;

    /**
     * Ctor.
     * @param ctx Context.
     */
    public ClientCacheQueryContinuousHandle(ClientConnectionContext ctx) {
        assert ctx != null;

        this.ctx = ctx;
    }

    /** {@inheritDoc} */
    @Override public void onUpdated(Iterable<CacheEntryEvent<?, ?>> iterable) throws CacheEntryListenerException {<FILL_FUNCTION_BODY>}

    /**
     * Sets the cursor.
     * @param cur Cursor.
     */
    public void setCursor(QueryCursor<?> cur) {
        this.cur = cur;
    }

    /**
     * Sets the cursor id.
     * @param id Cursor id.
     */
    public void startNotifications(long id) {
        this.id = id;
    }

    /** {@inheritDoc} */
    @Override public void close() {
        if (closeGuard.compareAndSet(false, true)) {
            assert cur != null;
            cur.close();

            ctx.decrementCursors();
        }
    }
}

        // Client is not yet ready to receive notifications - skip them.
        if (id == null)
            return;

        ClientCacheEntryEventNotification notification = new ClientCacheEntryEventNotification(
                ClientMessageParser.OP_QUERY_CONTINUOUS_EVENT_NOTIFICATION, id, iterable);

        ctx.notifyClient(notification);
    
<no_super_class>