public synchronized boolean addEvent (ObjectatEvent event) throws Exception {
		boolean success = false;
		if (hashMapOfKeys.containsKey(event.getKey())) {
			int eventIndex = hashMapOfKeys.get(event.getKey());
			ObjectatEvent deduplicateEvent = arrayListOfEvents.get(eventIndex);
			
			if (!deduplicateEvent.getKey().equals(event.getKey())) {
				this.logger.log(ObjectatLogLevel.WARN, "Index of keys is invalid before deduplicating event, attempting to re-index event keys.");
				this.reindexEventKeys();
				
				deduplicateEvent = arrayListOfEvents.get(hashMapOfKeys.get(event.getKey()));
				if (!deduplicateEvent.getKey().equals(event.getKey())) {
					// TODO
					// Define custom exception(s)
					this.logger.log(ObjectatLogLevel.FATAL, "Indexing of event keys failed, Objectat is corrupt.");
					Exception e = new Exception("Indexing of event keys failed, Objectat is corrupt.");
					throw e;
				}
			}
			
			success = deduplicateEvent.deduplicate(event);
		} else {
			event.setFirst(new Date());
			event.setLast(new Date());
			long thisEventId = ++eventId;
			event.setEventId(thisEventId);
			int newEventIndex = arrayListOfEvents.size();
			arrayListOfEvents.add(event);
			hashMapOfKeys.put(event.getKey(), newEventIndex);
			
			if (!arrayListOfEvents.get(hashMapOfKeys.get(event.getKey())).getKey().equals(event.getKey())) {
				// Key mapping is invalid, re-index keys
				this.logger.log(ObjectatLogLevel.WARN, "Index of keys is invalid after adding event, attempting to re-index event keys.");
				this.reindexEventKeys();
				
				if (!arrayListOfEvents.get(hashMapOfKeys.get(event.getKey())).getKey().equals(event.getKey())) {
					// TODO
					// Define custom exception(s)
					this.logger.log(ObjectatLogLevel.FATAL, "Indexing of event keys failed, Objectat is corrupt.");
					Exception e = new Exception("Indexing of event keys failed, Objectat is corrupt.");
					throw e;
				}
			}
			
			success = true;
		}
		
		this.eventStats.setEventsProcessed(this.eventStats.getEventsProcessed() + 1);
		this.eventStats.setEventsInObjectat(this.getArrayListOfEvents().size());
		
		if (success) {
			for (int i = 0; i < this.getArrayListOfObjectatClientWriters().size(); i++) {
				this.getArrayListOfObjectatClientWriters().get(i).addObjectToQueue(
						arrayListOfEvents.get(hashMapOfKeys.get(event.getKey()))
				);
			}
		}
		
		return success;
	}