@Override
	public void receiveData(byte[] dataBuffer, final int byteCount) {
		final int[] rawData = convertToIntArray(dataBuffer, byteCount);
		executor.submit(new Runnable() {
			
			@Override
			public void run() {
				InteractionEvent event = USBEventProducer.this.handler.createEvent(rawData);
				
				if (event == null) {
					return;
				}
				
				synchronized (USBEventProducer.this) {
					InteractionEvent outgoing;
					/*
					 * we receive the actual event and then a "release"
					 * event in order. fire the event after the
					 * release was received.
					 */
					
					if (event instanceof ConfirmationEvent) {
						if (pending != null) {
							outgoing = pending;
							pending = null;
							previous = outgoing;
							previousEventTime = outgoing.getTimestamp();	
						}
						else {
							return;
						}
					} 
					else {
						logger.info("new hit event: "+event+"; prev: "+previous+"; delta: "+(event.getTimestamp() - previousEventTime));
						if (event.hasSameContent(previous) 
								&& (event.getTimestamp() - previousEventTime) < MIN_TIME_DELTA) {
							/*
							 * probably a ghost event
							 */
							return;
						}
						
						pending = event;
						return;
					}
					
					for (EventListener el : USBEventProducer.this.listeners) {
						try {
							el.receiveEvent(outgoing);
						}
						catch (RuntimeException e) {
							logger.warn(e.getMessage(), e);
						}
					}
				}
			}

		});
		
	}