class EventSubscribeXmlRenderingCallback implements WEvtApi.EVT_SUBSCRIBE_CALLBACK {

    @Override
    public synchronized int onEvent(int evtSubscribeNotifyAction, WinDef.PVOID userContext, WinNT.HANDLE eventHandle) {
        if (logger.isDebugEnabled()) {
            logger.debug("onEvent(" + evtSubscribeNotifyAction + ", " + userContext + ", " + eventHandle);
        }

        if (evtSubscribeNotifyAction == WEvtApi.EvtSubscribeNotifyAction.ERROR) {
            if (eventHandle.getPointer().getInt(0) == WEvtApi.EvtSubscribeErrors.ERROR_EVT_QUERY_RESULT_STALE) {
                logger.error(MISSING_EVENT_MESSAGE);
            } else {
                logger.error(RECEIVED_THE_FOLLOWING_WIN32_ERROR + eventHandle.getPointer().getInt(0));
            }
        } else if (evtSubscribeNotifyAction == WEvtApi.EvtSubscribeNotifyAction.DELIVER) {
            wEvtApi.EvtRender(null, eventHandle, WEvtApi.EvtRenderFlags.EVENT_XML, size, buffer, used, propertyCount);

            // Not enough room in buffer, resize so it's big enough
            if (kernel32.GetLastError() == W32Errors.ERROR_INSUFFICIENT_BUFFER) {
                int newMaxSize = used.getInt(0);
                // Check for overflow or too big
                if (newMaxSize < size || newMaxSize > maxBufferSize) {
                    logger.error("Dropping event " + eventHandle + " because it couldn't be rendered within " + maxBufferSize + " bytes.");
                    // Ignored, see https://msdn.microsoft.com/en-us/library/windows/desktop/aa385577(v=vs.85).aspx
                    return 0;
                }
                size = newMaxSize;
                buffer = new Memory(size);
                wEvtApi.EvtRender(null, eventHandle, WEvtApi.EvtRenderFlags.EVENT_XML, size, buffer, used, propertyCount);
            }

            int lastError = kernel32.GetLastError();
            if (lastError == W32Errors.ERROR_SUCCESS) {
                int usedBytes = used.getInt(0);
                String string = Charsets.UTF_16LE.decode(buffer.getByteBuffer(0, usedBytes)).toString();
                if (string.endsWith("\u0000")) {
                    string = string.substring(0, string.length() - 1);
                }
                consumer.accept(string);
            } else {
                logger.error(EVT_RENDER_RETURNED_THE_FOLLOWING_ERROR_CODE + errorLookup.getLastError() + ".");
            }
        }
        // Ignored, see https://msdn.microsoft.com/en-us/library/windows/desktop/aa385577(v=vs.85).aspx
        return 0;
    }

    public  EventSubscribeXmlRenderingCallback(ComponentLog logger, Consumer<String> consumer, int maxBufferSize, WEvtApi wEvtApi, Kernel32 kernel32, ErrorLookup errorLookup);

}