Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/SequenceInstanceOfTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/SequenceInstanceOfTest.java	(revision 432)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/SequenceInstanceOfTest.java	(revision 433)
@@ -11,5 +11,5 @@
 
 import de.ugoe.cs.quest.SequenceInstanceOf;
-import de.ugoe.cs.quest.data.Event;
+import de.ugoe.cs.quest.eventcore.Event;
 
 
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/TestAll.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/TestAll.java	(revision 432)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/TestAll.java	(revision 433)
@@ -19,6 +19,6 @@
 	de.ugoe.cs.quest.assertions.TestAll.class,
 	de.ugoe.cs.quest.coverage.TestAll.class,
-	de.ugoe.cs.quest.data.TestAll.class,
-	de.ugoe.cs.quest.models.TestAll.class
+	de.ugoe.cs.quest.eventcore.TestAll.class,
+	de.ugoe.cs.quest.usageprofiles.TestAll.class
 })
 public class TestAll {
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/assertions/AssertEventTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/assertions/AssertEventTest.java	(revision 432)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/assertions/AssertEventTest.java	(revision 433)
@@ -4,5 +4,5 @@
 
 import de.ugoe.cs.quest.assertions.AssertEvent;
-import de.ugoe.cs.quest.data.mock.MockReplayable;
+import de.ugoe.cs.quest.eventcore.mock.MockReplayable;
 import static org.junit.Assert.*;
 
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/coverage/CoverageCalculatorObservedTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/coverage/CoverageCalculatorObservedTest.java	(revision 432)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/coverage/CoverageCalculatorObservedTest.java	(revision 433)
@@ -4,6 +4,6 @@
 import java.util.Collection;
 import de.ugoe.cs.quest.coverage.CoverageCalculatorObserved;
-import de.ugoe.cs.quest.data.Event;
-import de.ugoe.cs.quest.models.MockTrieBasedModel;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.MockTrieBasedModel;
 
 import java.util.LinkedHashSet;
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/coverage/CoverageCalculatorProcessTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/coverage/CoverageCalculatorProcessTest.java	(revision 432)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/coverage/CoverageCalculatorProcessTest.java	(revision 433)
@@ -10,6 +10,6 @@
 import java.util.Set;
 import de.ugoe.cs.quest.coverage.CoverageCalculatorProcess;
-import de.ugoe.cs.quest.data.Event;
-import de.ugoe.cs.quest.models.MockTrieBasedModel;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.MockTrieBasedModel;
 
 import org.junit.*;
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/coverage/SequenceToolsTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/coverage/SequenceToolsTest.java	(revision 432)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/coverage/SequenceToolsTest.java	(revision 433)
@@ -11,8 +11,8 @@
 import java.util.Set;
 import de.ugoe.cs.quest.coverage.SequenceTools;
-import de.ugoe.cs.quest.data.Event;
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel;
-import de.ugoe.cs.quest.models.IStochasticProcess;
-import de.ugoe.cs.quest.models.MockTrieBasedModel;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
+import de.ugoe.cs.quest.usageprofiles.MockTrieBasedModel;
 
 import org.junit.*;
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/EventTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/EventTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/EventTest.java	(revision 433)
@@ -0,0 +1,406 @@
+package de.ugoe.cs.quest.eventcore;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+import nl.jqno.equalsverifier.Warning;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>EventTest</code> contains tests for the class
+ * <code>{@link Event}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class EventTest {
+
+	@Test
+	public void testEvent_1() throws Exception {
+		String type = "typeString";
+
+		Event<String> result = new Event<String>(type);
+
+		assertNotNull(result);
+		assertEquals(type, result.type);
+		assertNull(result.target);
+		assertNull(result.targetShort);
+		assertEquals("", result.idInfo);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testEvent_2() throws Exception {
+		new Event<String>(null);
+	}
+
+	@Test
+	public void testEquals_1() throws Exception {
+		String type1 = "typeString";
+		String type2 = "typeString";
+		Event<String> fixture = new Event<String>(type1);
+		Event<String> other = new Event<String>(type2);
+
+		boolean result = fixture.equals(other);
+
+		assertTrue(result);
+	}
+
+	@Test
+	public void testEquals_2() throws Exception {
+		String type1 = "typeString1";
+		String type2 = "typeString2";
+		Event<String> fixture = new Event<String>(type1);
+		Event<String> other = new Event<String>(type2);
+
+		boolean result = fixture.equals(other);
+
+		assertFalse(result);
+	}
+
+	@Test
+	public void testEquals_3() throws Exception {
+		String type1 = "typeString";
+		String type2 = "typeString";
+		String target1 = "target";
+		String target2 = "target";
+		Event<String> fixture = new Event<String>(type1);
+		fixture.target = target1;
+		Event<String> other = new Event<String>(type2);
+		other.target = target2;
+
+		boolean result = fixture.equals(other);
+
+		assertTrue(result);
+	}
+
+	@Test
+	public void testEquals_4() throws Exception {
+		String type1 = "typeString1";
+		String type2 = "typeString2";
+		String target1 = "target";
+		String target2 = "target";
+		Event<String> fixture = new Event<String>(type1);
+		fixture.target = target1;
+		Event<String> other = new Event<String>(type2);
+		other.target = target2;
+
+		boolean result = fixture.equals(other);
+
+		assertFalse(result);
+	}
+
+	@Test
+	public void testEquals_5() throws Exception {
+		String type1 = "typeString";
+		String type2 = "typeString";
+		String target1 = "target1";
+		String target2 = "target2";
+		Event<String> fixture = new Event<String>(type1);
+		fixture.target = target1;
+		Event<String> other = new Event<String>(type2);
+		other.target = target2;
+
+		boolean result = fixture.equals(other);
+
+		assertFalse(result);
+	}
+
+	@Test
+	public void testEquals_6() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		boolean result = fixture.equals(fixture);
+
+		assertTrue(result);
+	}
+
+	@Test
+	public void testEqualsContract() throws Exception {
+		EqualsVerifier.forClass(Event.class)
+				.suppress(Warning.NONFINAL_FIELDS).withRedefinedSubclass(ReplayableEvent.class)
+				.verify();
+	}
+
+	@Test
+	public void testGetIdInfo_fixture_1() throws Exception {
+		String type = "typeString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.idInfo = idInfo;
+
+		String result = fixture.getIdInfo();
+
+		assertEquals(idInfo, result);
+	}
+
+	@Test
+	public void testGetShortId_1() throws Exception {
+		String type = "typeString";
+		String targetShort = "targetShortString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.targetShort = targetShort;
+
+		String result = fixture.getShortId();
+
+		assertEquals("targetShortString.typeString", result);
+	}
+
+	@Test
+	public void testGetShortId_2() throws Exception {
+		String type = "typeString";
+		String targetShort = "targetShortString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.targetShort = targetShort;
+		fixture.idInfo = idInfo;
+
+		String result = fixture.getShortId();
+
+		assertEquals("targetShortString.typeString.idInfoString", result);
+	}
+
+	@Test
+	public void testGetShortId_3() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+
+		String result = fixture.getShortId();
+
+		assertEquals("targetString.typeString", result);
+	}
+
+	@Test
+	public void testGetStandardId_1() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+
+		String result = fixture.getStandardId();
+
+		assertEquals("targetString.typeString", result);
+	}
+
+	@Test
+	public void testGetStandardId_2() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+		fixture.idInfo = idInfo;
+
+		String result = fixture.getStandardId();
+
+		assertEquals("targetString.typeString.idInfoString", result);
+	}
+
+	@Test
+	public void testGetStandardId_3() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.getStandardId();
+
+		assertEquals("typeString", result);
+	}
+
+	@Test
+	public void testGetStandardId_4() throws Exception {
+		String type = "typeString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.idInfo = idInfo;
+
+		String result = fixture.getStandardId();
+
+		assertEquals("typeString.idInfoString", result);
+	}
+
+	@Test
+	public void testGetTarget_1() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+
+		String result = fixture.getTarget();
+
+		assertEquals(target, result);
+	}
+
+	@Test
+	public void testGetTarget_2() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.getTarget();
+
+		assertNull(result);
+	}
+
+	@Test
+	public void testGetTargetShort_1() throws Exception {
+		String type = "typeString";
+		String targetShort = "targetShort";
+		Event<String> fixture = new Event<String>(type);
+		fixture.targetShort = targetShort;
+
+		String result = fixture.getTargetShort();
+
+		assertEquals(targetShort, result);
+	}
+
+	@Test
+	public void testGetTargetShort_2() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.getTargetShort();
+
+		assertNull(result);
+	}
+
+	@Test
+	public void testGetType_1() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.getType();
+
+		assertEquals(type, result);
+	}
+
+	@Test
+	public void testSetIdInfo_fixture_1() throws Exception {
+		String type = "typeString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+
+		fixture.setIdInfo(idInfo);
+
+		assertEquals(idInfo, fixture.idInfo);
+	}
+
+	@Test
+	public void testSetIdInfo_2() throws Exception {
+		String type = "typeString";
+		String idInfo = null;
+		Event<String> fixture = new Event<String>(type);
+
+		fixture.setIdInfo(idInfo);
+
+		assertEquals(idInfo, fixture.idInfo);
+	}
+
+	@Test
+	public void testSetTarget_1() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+
+		boolean result = fixture.setTarget(target);
+
+		assertTrue(result);
+		assertEquals(target, fixture.target);
+	}
+
+	@Test
+	public void testSetTarget_2() throws Exception {
+		String type = "typeString";
+		String target1 = "targetString1";
+		String target2 = "targetString2";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target1;
+
+		boolean result = fixture.setTarget(target2);
+
+		assertFalse(result);
+		assertEquals(target1, fixture.target);
+	}
+
+	@Test
+	public void testSetTargetShort_1() throws Exception {
+		String type = "typeString";
+		String targetShort = "targetShortString";
+		Event<String> fixture = new Event<String>(type);
+
+		boolean result = fixture.setTargetShort(targetShort);
+
+		assertTrue(result);
+		assertEquals(targetShort, fixture.targetShort);
+	}
+
+	@Test
+	public void testSetTargetShort_2() throws Exception {
+		String type = "typeString";
+		String targetShort1 = "targetShortString1";
+		String targetShort2 = "targetShortString2";
+		Event<String> fixture = new Event<String>(type);
+		fixture.targetShort = targetShort1;
+
+		boolean result = fixture.setTargetShort(targetShort2);
+
+		assertFalse(result);
+		assertEquals(targetShort1, fixture.targetShort);
+	}
+
+	@Test
+	public void testToString_1() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+
+		String result = fixture.toString();
+
+		assertEquals("targetString.typeString", result);
+	}
+
+	@Test
+	public void testToString_2() throws Exception {
+		String type = "typeString";
+		String target = "targetString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.target = target;
+		fixture.idInfo = idInfo;
+
+		String result = fixture.toString();
+
+		assertEquals("targetString.typeString.idInfoString", result);
+	}
+
+	@Test
+	public void testToString_3() throws Exception {
+		String type = "typeString";
+		Event<String> fixture = new Event<String>(type);
+
+		String result = fixture.toString();
+
+		assertEquals("typeString", result);
+	}
+
+	@Test
+	public void testToString_4() throws Exception {
+		String type = "typeString";
+		String idInfo = "idInfoString";
+		Event<String> fixture = new Event<String>(type);
+		fixture.idInfo = idInfo;
+
+		String result = fixture.toString();
+
+		assertEquals("typeString.idInfoString", result);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(EventTest.class);
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/ReplayableEventTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/ReplayableEventTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/ReplayableEventTest.java	(revision 433)
@@ -0,0 +1,474 @@
+package de.ugoe.cs.quest.eventcore;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import junitx.framework.ListAssert;
+import de.ugoe.cs.quest.IReplayDecorator;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+import de.ugoe.cs.quest.eventcore.mock.MockReplayable;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>ReplayableEventTest</code> contains tests for the class
+ * <code>{@link ReplayableEvent}</code>.
+ * 
+ * @generatedBy CodePro at 12/20/11 10:17 AM
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ReplayableEventTest {
+
+	private static class StubReplayDecorator implements IReplayDecorator {
+
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public String getHeader() {
+			return null;
+		}
+
+		@Override
+		public String getFooter() {
+			return null;
+		}
+
+		@Override
+		public String getSessionHeader(int sessionId) {
+			return null;
+		}
+
+		@Override
+		public String getSessionFooter(int sessionId) {
+			return null;
+		}
+		
+	}
+
+	@Test
+	public void testReplayableEvent_1() throws Exception {
+		String type = "typeString";
+
+		ReplayableEvent<MockReplayable> result = new ReplayableEvent<MockReplayable>(
+				type);
+
+		assertNotNull(result);
+		assertNotNull(result.replayEvents);
+		assertTrue(result.replayEvents.isEmpty());
+		assertEquals(true, result.replayValid);
+		assertEquals(null, result.decorator);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testReplayableEvent_2() throws Exception {
+		new ReplayableEvent<MockReplayable>(null);
+	}
+
+	@Test
+	public void testAddReplayEvent_1() throws Exception {
+		String type = "typeString";
+		String replayableReplay = "replayString";
+		String replaybleTarget = "replayTargetString";
+		MockReplayable replayable = new MockReplayable(replayableReplay,
+				replaybleTarget);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.addReplayEvent(replayable);
+		
+		
+		assertEquals(1, fixture.replayEvents.size());
+		assertEquals(replayable, fixture.replayEvents.get(0));
+	}
+	
+	@Test
+	public void testAddReplayEvent_2() throws Exception {
+		String type = "typeString";
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replaybleTarget1 = "replayTargetString1";
+		String replaybleTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replaybleTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replaybleTarget2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.addReplayEvent(replayable1);
+		fixture.addReplayEvent(replayable2);
+		
+		
+		assertEquals(2, fixture.replayEvents.size());
+		assertEquals(replayable1, fixture.replayEvents.get(0));
+		assertEquals(replayable2, fixture.replayEvents.get(1));
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class )
+	public void testAddReplayEvent_fixture_3() throws Exception {
+		String type = "typeString";
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.addReplayEvent(null);
+	}
+
+	@Test
+	public void testAddReplaySequence_1() throws Exception {
+		String type = "typeString";
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replaybleTarget1 = "replayTargetString1";
+		String replaybleTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replaybleTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replaybleTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		
+		fixture.addReplaySequence(replaySequence);		
+		
+		assertEquals(2, fixture.replayEvents.size());
+		assertEquals(replayable1, fixture.replayEvents.get(0));
+		assertEquals(replayable2, fixture.replayEvents.get(1));
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class )
+	public void testAddReplaySequence_2() throws Exception {
+		String type = "typeString";
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		
+		fixture.addReplaySequence(null);	
+	}
+
+	@Test
+	public void testEquals_1() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString";
+		boolean replayValidOther = true;
+		String replayableReplayOther1 = "replayString1";
+		String replayableReplayOther2 = "replayString2";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(true, result);
+	}
+	
+	@Test
+	public void testEquals_2() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString2";
+		boolean replayValidOther = true;
+		String replayableReplayOther1 = "replayString1";
+		String replayableReplayOther2 = "replayString2";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(false, result);
+	}
+	
+	@Test
+	public void testEquals_3() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString";
+		boolean replayValidOther = true;
+		String replayableReplayOther1 = "replayString3";
+		String replayableReplayOther2 = "replayString2";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(true, result);
+	}
+	
+	@Test
+	public void testEquals_4() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString";
+		boolean replayValidOther = true;
+		String replayableReplayOther1 = "replayString1";
+		String replayableReplayOther2 = "replayString3";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(true, result);
+	}
+	
+	@Test
+	public void testEquals_5() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+		
+		String typeOther = "typeString";
+		boolean replayValidOther = false;
+		String replayableReplayOther1 = "replayString1";
+		String replayableReplayOther2 = "replayString2";
+		String replaybleTargetOther1 = "replayTargetString1";
+		String replaybleTargetOther2 = "replayTargetString2";
+		MockReplayable replayableOther1 = new MockReplayable(replayableReplayOther1,
+				replaybleTargetOther1);
+		MockReplayable replayableOther2 = new MockReplayable(replayableReplayOther2, replaybleTargetOther2);
+		List<MockReplayable> replaySequenceOther = new LinkedList<MockReplayable>();
+		replaySequenceOther.add(replayableOther1);
+		replaySequenceOther.add(replayableOther2);
+		ReplayableEvent<MockReplayable> other = new ReplayableEvent<MockReplayable>(
+				typeOther);
+		other.replayEvents = replaySequenceOther;
+		other.replayValid = replayValidOther;
+
+		boolean result = fixture.equals(other);
+
+		assertEquals(true, result);
+	}
+	
+	@Test
+	public void testEquals_6() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+		fixture.replayValid = replayValid;
+
+		boolean result = fixture.equals(fixture);
+
+		assertEquals(true, result);
+	}
+
+	@Test
+	public void testGetReplayDecorator_1() throws Exception {
+		String type = "typeString";
+		StubReplayDecorator decorator = new StubReplayDecorator();
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.decorator = decorator; 
+
+		IReplayDecorator result = fixture.getReplayDecorator();
+
+		assertEquals(decorator, result);
+	}
+
+	@Test
+	public void testGetReplayMessages_1() throws Exception {
+		String type = "typeString";
+		String replayableReplay1 = "replayString1";
+		String replayableReplay2 = "replayString2";
+		String replayableTarget1 = "replayTargetString1";
+		String replayableTarget2 = "replayTargetString2";
+		MockReplayable replayable1 = new MockReplayable(replayableReplay1,
+				replayableTarget1);
+		MockReplayable replayable2 = new MockReplayable(replayableReplay2, replayableTarget2);
+		List<MockReplayable> replaySequence = new LinkedList<MockReplayable>();
+		replaySequence.add(replayable1);
+		replaySequence.add(replayable2);
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayEvents = replaySequence;
+
+		List<MockReplayable> result = fixture.getReplayMessages();
+
+		ListAssert.assertEquals(replaySequence, result);
+	}
+
+	@Test
+	public void testHasValidReplay_1() throws Exception {
+		String type = "typeString";
+		boolean replayValid = true;
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayValid = replayValid;
+
+		boolean result = fixture.hasValidReplay();
+
+		assertEquals(replayValid, result);
+	}
+	
+	@Test
+	public void testHasValidReplay_2() throws Exception {
+		String type = "typeString";
+		boolean replayValid = false;
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		fixture.replayValid = replayValid;
+
+		boolean result = fixture.hasValidReplay();
+
+		assertEquals(replayValid, result);
+	}
+
+	@Test
+	public void testInvalidateReplay_1() throws Exception {
+		String type = "typeString";
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		
+		fixture.invalidateReplay();
+
+		assertFalse(fixture.replayValid);
+	}
+	
+	@Test
+	public void testInvalidateReplay_2() throws Exception {
+		String type = "typeString";
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+		
+		fixture.invalidateReplay();
+		fixture.invalidateReplay();
+
+		assertFalse(fixture.replayValid);
+	}
+
+	@Test
+	public void testSetDecorator_fixture_1() throws Exception {
+		String type = "typeString";
+		StubReplayDecorator decorator = new StubReplayDecorator();
+		ReplayableEvent<MockReplayable> fixture = new ReplayableEvent<MockReplayable>(
+				type);
+
+		fixture.setDecorator(decorator);
+
+		assertEquals(decorator, fixture.decorator);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(ReplayableEventTest.class);
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/TestAll.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/TestAll.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/TestAll.java	(revision 433)
@@ -0,0 +1,25 @@
+package de.ugoe.cs.quest.eventcore;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * The class <code>TestAll</code> builds a suite that can be used to run all
+ * of the tests within its package as well as within any subpackages of its
+ * package.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	EventTest.class,
+	ReplayableEventTest.class
+})
+public class TestAll {
+
+	public static void main(String[] args) {
+		JUnitCore.runClasses(new Class[] { TestAll.class });
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/mock/MockReplayable.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/mock/MockReplayable.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/eventcore/mock/MockReplayable.java	(revision 433)
@@ -0,0 +1,61 @@
+package de.ugoe.cs.quest.eventcore.mock;
+
+import de.ugoe.cs.quest.eventcore.IReplayable;
+
+public class MockReplayable implements IReplayable {
+
+	private static final long serialVersionUID = 1L;
+
+	final String replay;
+	final String target;
+
+	public MockReplayable(String replay, String target) {
+		this.replay = replay;
+		this.target = target;
+	}
+
+	@Override
+	public String getReplay() {
+		return replay;
+	}
+
+	@Override
+	public String getTarget() {
+		return target;
+	}
+
+	@Override
+	public boolean equals(Object other) {
+		if (this == other) {
+			return true;
+		}
+		if (other instanceof MockReplayable) {
+			if (replay != null && target != null) {
+				return replay.equals(((MockReplayable) other).replay)
+						&& target.equals(((MockReplayable) other).target);
+			} else if (replay != null && target == null) {
+				return replay.equals(((MockReplayable) other).replay)
+						&& ((MockReplayable) other).target == null;
+			} else if (replay == null && target != null) {
+				return ((MockReplayable) other).replay == null
+						&& target.equals(((MockReplayable) other).target);
+			} else {
+				return ((MockReplayable) other).replay == null
+						&& ((MockReplayable) other).target == null;
+			}
+		}
+		return false;
+	}
+	
+	@Override
+	public int hashCode() {
+		int hashCode = 17;
+		if( replay!=null ) {
+			hashCode *= replay.hashCode();
+		}
+		if( target!=null ) {
+			hashCode *= target.hashCode();
+		}
+		return hashCode;
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomatonTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomatonTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomatonTest.java	(revision 433)
@@ -0,0 +1,157 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.DeterministicFiniteAutomaton;
+
+import java.util.Random;
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>DeterministicFiniteAutomatonTest</code> contains tests for
+ * the class <code>{@link DeterministicFiniteAutomaton}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class DeterministicFiniteAutomatonTest {
+
+	Collection<List<? extends Event<?>>> sequences;
+
+	@Test
+	public void testDeterministicFiniteAutomaton_1() throws Exception {
+		Random r = new Random();
+
+		DeterministicFiniteAutomaton result = new DeterministicFiniteAutomaton(
+				r);
+
+		assertNotNull(result);
+		assertEquals(2, result.trieOrder);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testDeterministicFiniteAutomaton_2() throws Exception {
+		new DeterministicFiniteAutomaton(null);
+	}
+
+	@Test
+	public void testGetProbability_1() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+		context.add(new Event<String>("b"));
+
+		Event<String> symbol = new Event<String>("r");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_2() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d / 4.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_3() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d / 4.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_4() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("e");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(0.0d, result, 0.0001);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetProbability_5() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = null;
+
+		fixture.getProbability(context, symbol);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetProbability_6() throws Exception {
+		DeterministicFiniteAutomaton fixture = new DeterministicFiniteAutomaton(
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = null;
+
+		Event<String> symbol = new Event<String>("a");
+
+		fixture.getProbability(context, symbol);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore()
+				.run(DeterministicFiniteAutomatonTest.class);
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModelTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModelTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModelTest.java	(revision 433)
@@ -0,0 +1,94 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+import org.junit.*;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel.MarkovEdge;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>FirstOrderMarkovModelTest</code> contains tests for the class
+ * <code>{@link FirstOrderMarkovModel}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class FirstOrderMarkovModelTest {
+
+	Collection<List<? extends Event<?>>> sequences;
+	
+	@Test
+	public void testFirstOrderMarkovModel_1() throws Exception {
+		Random r = new Random();
+
+		FirstOrderMarkovModel result = new FirstOrderMarkovModel(r);
+
+		assertNotNull(result);
+		assertEquals(r, result.r);
+		assertEquals(2, result.trieOrder);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testFirstOrderMarkovModel_2() throws Exception {
+		new FirstOrderMarkovModel(null);
+	}
+	
+	@Test
+	public void testCalcEntropy() throws Exception {
+		Random r = new Random();
+		FirstOrderMarkovModel fixture = new FirstOrderMarkovModel(r);
+		fixture.train(sequences);
+		
+		double result = fixture.calcEntropy();
+		
+		assertEquals(0.7392d, result, 0.0001);
+	}
+	
+	@Test
+	public void testMarkovEdgeMarkovEdge_1() throws Exception {
+		double weight = 0.2d;
+		
+		MarkovEdge result = new MarkovEdge(weight);
+		
+		assertNotNull(result);
+		assertEquals(weight, result.weight, 0.0001);
+	}
+	
+	@Test
+	public void testMarkovEdgeToString_1() throws Exception {
+		double weight = 0.2d;
+		MarkovEdge fixture = new MarkovEdge(weight);
+		
+		String result = fixture.toString();
+		
+		assertEquals(Double.toString(0.2d), result);
+	}
+	
+	@Before
+	public void setUp() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(FirstOrderMarkovModelTest.class);
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModelTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModelTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModelTest.java	(revision 433)
@@ -0,0 +1,241 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.HighOrderMarkovModel;
+
+import java.util.Random;
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>HighOrderMarkovModelTest</code> contains tests for the class
+ * <code>{@link HighOrderMarkovModel}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class HighOrderMarkovModelTest {
+
+	Collection<List<? extends Event<?>>> sequences;
+
+	@Test
+	public void testHighOrderMarkovModel_1() throws Exception {
+		int maxOrder = 1;
+		Random r = new Random();
+
+		HighOrderMarkovModel result = new HighOrderMarkovModel(maxOrder, r);
+
+		assertNotNull(result);
+		assertEquals(r, result.r);
+		assertEquals(maxOrder + 1, result.trieOrder);
+	}
+
+	@Test
+	public void testHighOrderMarkovModel_2() throws Exception {
+		int maxOrder = 0;
+		Random r = new Random();
+
+		HighOrderMarkovModel result = new HighOrderMarkovModel(maxOrder, r);
+
+		assertNotNull(result);
+		assertEquals(r, result.r);
+		assertEquals(maxOrder + 1, result.trieOrder);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testHighOrderMarkovModel_3() throws Exception {
+		int maxOrder = 1;
+		Random r = null;
+
+		new HighOrderMarkovModel(maxOrder, r);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testHighOrderMarkovModel_4() throws Exception {
+		int maxOrder = -1;
+		Random r = new Random();
+
+		new HighOrderMarkovModel(maxOrder, r);
+	}
+
+	@Test
+	public void testGetProbability_1() throws Exception {
+		int markovOrder = 1;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(2.0d / 5.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_2() throws Exception {
+		int markovOrder = 1;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("r");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(0.0d / 5.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_3() throws Exception {
+		int markovOrder = 1;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<String>> context = new ArrayList<Event<String>>();
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d / 5.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_4() throws Exception {
+		int markovOrder = 1;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(2.0d / 5.0, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_5() throws Exception {
+		int markovOrder = 2;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(1.0d, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_6() throws Exception {
+		int markovOrder = 2;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("b"));
+
+		Event<String> symbol = new Event<String>("b");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(0.0d, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_7() throws Exception {
+		int markovOrder = 0;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("b"));
+
+		Event<String> symbol = new Event<String>("a");
+
+		double result = fixture.getProbability(context, symbol);
+
+		assertEquals(5.0d / 13.0, result, 0.0001);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetProbability_8() throws Exception {
+		int markovOrder = 0;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("b"));
+
+		Event<String> symbol = null;
+
+		fixture.getProbability(context, symbol);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetProbability_9() throws Exception {
+		int markovOrder = 0;
+		HighOrderMarkovModel fixture = new HighOrderMarkovModel(markovOrder,
+				new Random());
+		fixture.train(sequences);
+
+		List<Event<?>> context = null;
+
+		Event<String> symbol = new Event<String>("b");
+
+		fixture.getProbability(context, symbol);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(HighOrderMarkovModelTest.class);
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/IncompleteMemoryTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/IncompleteMemoryTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/IncompleteMemoryTest.java	(revision 433)
@@ -0,0 +1,152 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.*;
+
+import de.ugoe.cs.quest.usageprofiles.IncompleteMemory;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>IncompleteMemoryTest</code> contains tests for the class <code>{@link IncompleteMemory}</code>.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class IncompleteMemoryTest {
+
+	@Test
+	public void testIncompleteMemory_1()
+		throws Exception {
+		int length = 1;
+
+		IncompleteMemory<String> result = new IncompleteMemory<String>(length);
+
+		assertNotNull(result);
+		assertEquals(0, result.getLast(1).size());
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testIncompleteMemory_2()
+		throws Exception {
+		int length = 0;
+
+		new IncompleteMemory<String>(length);
+	}
+
+	@Test
+	public void testGetLast_1()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		int num = -1;
+
+		List<String> result = fixture.getLast(num);
+
+		assertNotNull(result);
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetLast_2()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		int num = 1;
+		
+		List<String> expected = new ArrayList<String>();
+		expected.add("3");
+
+		List<String> result = fixture.getLast(num);
+
+		assertNotNull(result);
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetLast_3()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		int num = 2;
+		
+		List<String> expected = new ArrayList<String>();
+		expected.add("2");
+		expected.add("3");
+
+		List<String> result = fixture.getLast(num);
+
+		assertNotNull(result);
+		assertEquals(expected, result);
+	}
+	
+	@Test
+	public void testGetLast_4()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		int num = 3;
+		
+		List<String> expected = new ArrayList<String>();
+		expected.add("2");
+		expected.add("3");
+
+		List<String> result = fixture.getLast(num);
+
+		assertNotNull(result);
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetLength_1()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		
+		int result = fixture.getLength(); 
+
+		assertEquals(0, result);
+	}
+	
+	@Test
+	public void testGetLength_2()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		
+		int result = fixture.getLength(); 
+
+		assertEquals(1, result);
+	}
+	
+	@Test
+	public void testGetLength_3()
+		throws Exception {
+		int length = 2;
+		IncompleteMemory<String> fixture = new IncompleteMemory<String>(length);
+		fixture.add("1");
+		fixture.add("2");
+		fixture.add("3");
+		
+		int result = fixture.getLength(); 
+
+		assertEquals(2, result);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(IncompleteMemoryTest.class);
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/MockTrieBasedModel.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/MockTrieBasedModel.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/MockTrieBasedModel.java	(revision 433)
@@ -0,0 +1,31 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+
+public class MockTrieBasedModel extends TrieBasedModel {
+	private static final long serialVersionUID = 1L;
+
+	public MockTrieBasedModel(int markovOrder, Random r) {
+		super(markovOrder, r);
+	}
+
+	@Override
+	public double getProbability(List<? extends Event<?>> context,
+			Event<?> symbol) {
+		List<Event<?>> list = new ArrayList<Event<?>>();
+		if( context.isEmpty() ) {
+			return 2;
+		}
+		list.add(context.get(context.size()-1));
+		if( trie.find(list).getFollowingSymbols().contains(symbol) ) {
+			return 1;
+		} else {
+			return 0;
+		}
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/ModelFlattenerTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/ModelFlattenerTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/ModelFlattenerTest.java	(revision 433)
@@ -0,0 +1,148 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import org.junit.*;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.HighOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.ModelFlattener;
+import de.ugoe.cs.quest.usageprofiles.PredictionByPartialMatch;
+import de.ugoe.cs.quest.usageprofiles.TrieNode;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>ModelFlattenerTest</code> contains tests for the class <code>{@link ModelFlattener}</code>.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ModelFlattenerTest {
+	
+	List<Event<?>> sequence;
+	
+	private static void assertCollectionContent(Collection<?> c1, Collection<?> c2) {
+		assertEquals(c1.size(), c2.size());
+		for( Object obj : c1 ) {
+			assertTrue(c2.contains(obj));
+		}
+	}
+	
+	@Test
+	public void testFlattenHighOrderMarkovModel_1()
+		throws Exception {
+		ModelFlattener fixture = new ModelFlattener();
+		HighOrderMarkovModel model = new HighOrderMarkovModel(2, new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		model.train(sequences);
+		
+		Collection<Event<?>> expectedSymbols = new HashSet<Event<?>>();
+		expectedSymbols.add(new Event<Object>("a-=-END"));
+		expectedSymbols.add(new Event<Object>("a-=-b"));
+		expectedSymbols.add(new Event<Object>("a-=-c"));
+		expectedSymbols.add(new Event<Object>("a-=-d"));
+		expectedSymbols.add(new Event<Object>("b-=-r"));
+		expectedSymbols.add(new Event<Object>("c-=-a"));
+		expectedSymbols.add(new Event<Object>("d-=-a"));
+		expectedSymbols.add(new Event<Object>("r-=-a"));
+		expectedSymbols.add(new Event<Object>("START-=-a"));
+
+		FirstOrderMarkovModel result = fixture.flattenHighOrderMarkovModel(model);
+		
+		assertCollectionContent(expectedSymbols, result.getEvents());
+		
+		TrieNode<Event<?>> root = result.trie.find(null);
+		TrieNode<Event<?>> root_aEnd = root.getChild(new Event<Object>("a-=-END"));
+		TrieNode<Event<?>> root_ab = root.getChild(new Event<Object>("a-=-b"));
+		TrieNode<Event<?>> root_ab_br = root_ab.getChild(new Event<Object>("b-=-r"));
+		TrieNode<Event<?>> root_ac = root.getChild(new Event<Object>("a-=-c"));
+		TrieNode<Event<?>> root_ac_ca = root_ac.getChild(new Event<Object>("c-=-a"));
+		TrieNode<Event<?>> root_ad = root.getChild(new Event<Object>("a-=-d"));
+		TrieNode<Event<?>> root_ad_da = root_ad.getChild(new Event<Object>("d-=-a"));
+		TrieNode<Event<?>> root_br = root.getChild(new Event<Object>("b-=-r"));
+		TrieNode<Event<?>> root_br_ra = root_br.getChild(new Event<Object>("r-=-a"));
+		TrieNode<Event<?>> root_ca = root.getChild(new Event<Object>("c-=-a"));
+		TrieNode<Event<?>> root_ca_ad = root_ca.getChild(new Event<Object>("a-=-d"));
+		TrieNode<Event<?>> root_da = root.getChild(new Event<Object>("d-=-a"));
+		TrieNode<Event<?>> root_da_ab = root_da.getChild(new Event<Object>("a-=-b"));
+		TrieNode<Event<?>> root_ra = root.getChild(new Event<Object>("r-=-a"));
+		TrieNode<Event<?>> root_ra_ac = root_ra.getChild(new Event<Object> ("a-=-c"));
+		TrieNode<Event<?>> root_ra_aEnd = root_ra.getChild(new Event<Object>("a-=-END"));
+		TrieNode<Event<?>> root_startA = root.getChild(new Event<Object>("START-=-a"));
+		TrieNode<Event<?>> root_startA_ab = root_startA.getChild(new Event<Object>("a-=-b"));
+		
+		assertEquals(1, root_aEnd.getCount());
+		assertTrue(root_aEnd.isLeaf());
+		assertEquals(2, root_ab.getCount());
+		assertEquals(1, root_ab.getChildren().size());
+		assertEquals(2, root_ab_br.getCount());
+		assertTrue(root_ab_br.isLeaf());
+		assertEquals(1, root_ac.getCount());
+		assertEquals(1, root_ac.getChildren().size());
+		assertEquals(1, root_ac_ca.getCount());
+		assertTrue(root_ac_ca.isLeaf());
+		assertEquals(1, root_ad.getCount());
+		assertEquals(1, root_ad.getChildren().size());
+		assertEquals(1, root_ad_da.getCount());
+		assertTrue(root_ad_da.isLeaf());
+		assertEquals(2, root_br.getCount());
+		assertEquals(1, root_br.getChildren().size());
+		assertEquals(2, root_br_ra.getCount());
+		assertTrue(root_br_ra.isLeaf());
+		assertEquals(1, root_ca.getCount());
+		assertEquals(1, root_ca.getChildren().size());
+		assertEquals(1, root_ca_ad.getCount());
+		assertTrue(root_ca_ad.isLeaf());
+		assertEquals(1, root_da.getCount());
+		assertEquals(1, root_da.getChildren().size());
+		assertEquals(1, root_da_ab.getCount());
+		assertTrue(root_da_ab.isLeaf());
+		assertEquals(2, root_ra.getCount());
+		assertEquals(2, root_ra.getChildren().size());
+		assertEquals(1, root_ra_ac.getCount());
+		assertTrue(root_ra_ac.isLeaf());
+		assertEquals(1, root_ra_aEnd.getCount());
+		assertTrue(root_ra_aEnd.isLeaf());
+		assertEquals(1, root_startA.getCount());
+		assertEquals(1, root_startA.getChildren().size());
+		assertEquals(1, root_startA_ab.getCount());
+		assertTrue(root_startA_ab.isLeaf());		
+	}
+
+	@Test
+	public void testFlattenPredictionByPartialMatch_1()
+		throws Exception {
+		ModelFlattener fixture = new ModelFlattener();
+		PredictionByPartialMatch model = new PredictionByPartialMatch(1, new Random());
+
+		FirstOrderMarkovModel result = fixture.flattenPredictionByPartialMatch(model);
+		
+		assertEquals(null, result);
+	}
+
+	@Before
+	public void setUp()
+		throws Exception {
+		sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(ModelFlattenerTest.class);
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatchTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatchTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatchTest.java	(revision 433)
@@ -0,0 +1,365 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.PredictionByPartialMatch;
+
+import java.util.Random;
+import org.junit.*;
+
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>PredictionByPartialMatchTest</code> contains tests for the
+ * class <code>{@link PredictionByPartialMatch}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class PredictionByPartialMatchTest {
+
+	Collection<List<? extends Event<?>>> sequences;
+
+	@Test
+	public void testPredictionByPartialMatch_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+
+		PredictionByPartialMatch result = new PredictionByPartialMatch(
+				markovOrder, r);
+
+		assertNotNull(result);
+		assertEquals(markovOrder+1, result.trieOrder);
+		assertEquals(0, result.minOrder);
+		assertEquals(r, result.r);
+		assertEquals(0.1, result.probEscape, 0.0001);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_2() throws Exception {
+		int markovOrder = -1;
+		Random r = new Random();
+
+		new PredictionByPartialMatch(markovOrder, r);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_3() throws Exception {
+		int markovOrder = 2;
+		Random r = null;
+
+		new PredictionByPartialMatch(markovOrder, r);
+	}
+	
+	@Test
+	public void testPredictionByPartialMatch_4() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+
+		PredictionByPartialMatch result = new PredictionByPartialMatch(
+				markovOrder, r, probEscape);
+
+		assertNotNull(result);
+		assertEquals(markovOrder+1, result.trieOrder);
+		assertEquals(0, result.minOrder);
+		assertEquals(r, result.r);
+		assertEquals(probEscape, result.probEscape, 0.0001);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_5() throws Exception {
+		int markovOrder = -1;
+		Random r = new Random();
+		double probEscape = 0.2;
+
+		new PredictionByPartialMatch(markovOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_6() throws Exception {
+		int markovOrder = 2;
+		Random r = null;
+		double probEscape = 0.2;
+
+		new PredictionByPartialMatch(markovOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_7() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.0;
+
+		new PredictionByPartialMatch(markovOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_8() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 1.0;
+
+		new PredictionByPartialMatch(markovOrder, r, probEscape);
+	}
+	
+	@Test
+	public void testPredictionByPartialMatch_9() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		PredictionByPartialMatch result = new PredictionByPartialMatch(
+				markovOrder, minOrder, r, probEscape);
+
+		assertNotNull(result);
+		assertEquals(markovOrder+1, result.trieOrder);
+		assertEquals(minOrder, result.minOrder);
+		assertEquals(r, result.r);
+		assertEquals(probEscape, result.probEscape, 0.0001);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_10() throws Exception {
+		int markovOrder = -1;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_11() throws Exception {
+		int markovOrder = 2;
+		Random r = null;
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_12() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.0;
+		int minOrder = 1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_13() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 1.0;
+		int minOrder = 1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_14() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 3;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testPredictionByPartialMatch_15() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = -1;
+
+		new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+	}
+
+	@Test
+	public void testGetProbEscape_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.probEscape = probEscape;
+		
+		double result = fixture.getProbEscape();
+
+		assertEquals(probEscape, result, 0.0001);
+	}
+
+	@Test
+	public void testGetProbability_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.88d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_2() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.04d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_3() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 2;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(1.0d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_4() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 2;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.0d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_5() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 0;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("b");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.8701d, result, 0.0001);
+	}
+	
+	@Test
+	public void testGetProbability_6() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 0;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+		fixture.train(sequences);
+		
+		List<Event<?>> context = new ArrayList<Event<?>>();
+		context.add(Event.STARTEVENT);
+		context.add(new Event<String>("a"));
+
+		Event<String> symbol = new Event<String>("c");
+		
+		double result = fixture.getProbability(context, symbol);
+		
+		assertEquals(0.0350, result, 0.0001);
+	}
+
+	@Test
+	public void testSetProbEscape_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+		double probEscape = 0.2;
+		int minOrder = 1;
+		double newProbEscape = 0.3;
+
+		PredictionByPartialMatch fixture = new PredictionByPartialMatch(markovOrder, minOrder, r, probEscape);
+				
+		fixture.setProbEscape(newProbEscape);
+
+		assertEquals(newProbEscape, fixture.probEscape, 0.0001);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		List<Event<?>> sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore()
+				.run(PredictionByPartialMatchTest.class);
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/TestAll.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/TestAll.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/TestAll.java	(revision 433)
@@ -0,0 +1,31 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * The class <code>TestAll</code> builds a suite that can be used to run all
+ * of the tests within its package as well as within any subpackages of its
+ * package.
+ *
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+	DeterministicFiniteAutomatonTest.class,
+	FirstOrderMarkovModelTest.class,
+	HighOrderMarkovModelTest.class,
+	IncompleteMemoryTest.class,
+	ModelFlattenerTest.class,
+	PredictionByPartialMatchTest.class,
+	TrieBasedModelTest.class,	
+	TrieTest.class
+})
+public class TestAll {
+
+	public static void main(String[] args) {
+		JUnitCore.runClasses(new Class[] { TestAll.class });
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/TrieBasedModelTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/TrieBasedModelTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/TrieBasedModelTest.java	(revision 433)
@@ -0,0 +1,635 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.Trie;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.quest.usageprofiles.TrieNode;
+
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>TrieBasedModelTest</code> contains tests for the class
+ * <code>{@link TrieBasedModel}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class TrieBasedModelTest {
+
+	List<Event<?>> sequence;
+	Collection<Event<?>> symbols;
+
+	private void assertTrieStructure(Trie<Event<?>> trie, int numSequences) {
+		TrieNode<Event<?>> root = trie.find(null);
+		TrieNode<Event<?>> root_a = root.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_a = root_a.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_b = root_a.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_a_b_a = root_a_b
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_b_b = root_a_b
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_a_b_c = root_a_b
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_a_b_d = root_a_b
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_a_b_r = root_a_b
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_a_c = root_a.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_a_c_a = root_a_c
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_c_b = root_a_c
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_a_c_c = root_a_c
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_a_c_d = root_a_c
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_a_c_r = root_a_c
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_a_d = root_a.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_a_d_a = root_a_d
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_a_d_b = root_a_d
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_a_d_c = root_a_d
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_a_d_d = root_a_d
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_a_d_r = root_a_d
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_a_r = root_a.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_b = root.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_b_a = root_b.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_b_b = root_b.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_b_c = root_b.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_b_d = root_b.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_b_r = root_b.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_b_r_a = root_b_r
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_b_r_b = root_b_r
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_b_r_c = root_b_r
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_b_r_d = root_b_r
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_b_r_r = root_b_r
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_c = root.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_c_a = root_c.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_c_a_a = root_c_a
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_c_a_b = root_c_a
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_c_a_c = root_c_a
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_c_a_d = root_c_a
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_c_a_r = root_c_a
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_c_b = root_c.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_c_c = root_c.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_c_d = root_c.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_c_r = root_c.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_d = root.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_d_a = root_d.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_d_a_a = root_d_a
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_d_a_b = root_d_a
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_d_a_c = root_d_a
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_d_a_d = root_d_a
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_d_a_r = root_d_a
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_d_b = root_d.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_d_c = root_d.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_d_d = root_d.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_d_r = root_d.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_r = root.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_r_a = root_r.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_r_a_a = root_r_a
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_r_a_b = root_r_a
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_r_a_c = root_r_a
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_r_a_d = root_r_a
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_r_a_r = root_r_a
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_r_a_end = root_r_a.getChild(Event.ENDEVENT);
+		TrieNode<Event<?>> root_r_b = root_r.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_r_c = root_r.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_r_d = root_r.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_r_r = root_r.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_start = root.getChild(Event.STARTEVENT);
+		TrieNode<Event<?>> root_start_a = root_start
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_start_a_a = root_start_a
+				.getChild(new Event<String>("a"));
+		TrieNode<Event<?>> root_start_a_b = root_start_a
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_start_a_c = root_start_a
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_start_a_d = root_start_a
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_start_a_r = root_start_a
+				.getChild(new Event<String>("r"));
+		TrieNode<Event<?>> root_start_b = root_start
+				.getChild(new Event<String>("b"));
+		TrieNode<Event<?>> root_start_c = root_start
+				.getChild(new Event<String>("c"));
+		TrieNode<Event<?>> root_start_d = root_start
+				.getChild(new Event<String>("d"));
+		TrieNode<Event<?>> root_start_r = root_start
+				.getChild(new Event<String>("r"));
+
+		assertEquals(numSequences * 5, root_a.getCount());
+		assertNull(root_a_a);
+		assertEquals(numSequences * 2, root_a_b.getCount());
+		assertNull(root_a_b_a);
+		assertNull(root_a_b_b);
+		assertNull(root_a_b_c);
+		assertNull(root_a_b_d);
+		assertEquals(numSequences * 2, root_a_b_r.getCount());
+		assertEquals(numSequences * 1, root_a_c.getCount());
+		assertEquals(numSequences * 1, root_a_c_a.getCount());
+		assertNull(root_a_c_b);
+		assertNull(root_a_c_c);
+		assertNull(root_a_c_d);
+		assertNull(root_a_c_r);
+		assertEquals(numSequences * 1, root_a_d.getCount());
+		assertEquals(numSequences * 1, root_a_d_a.getCount());
+		assertNull(root_a_d_b);
+		assertNull(root_a_d_c);
+		assertNull(root_a_d_d);
+		assertNull(root_a_d_r);
+		assertNull(root_a_r);
+
+		assertEquals(numSequences * 2, root_b.getCount());
+		assertNull(root_b_a);
+		assertNull(root_b_b);
+		assertNull(root_b_c);
+		assertNull(root_b_d);
+		assertEquals(numSequences * 2, root_b_r.getCount());
+		assertEquals(numSequences * 2, root_b_r_a.getCount());
+		assertNull(root_b_r_b);
+		assertNull(root_b_r_c);
+		assertNull(root_b_r_d);
+		assertNull(root_b_r_r);
+
+		assertEquals(numSequences * 1, root_c.getCount());
+		assertEquals(numSequences * 1, root_c_a.getCount());
+		assertNull(root_c_a_a);
+		assertNull(root_c_a_b);
+		assertNull(root_c_a_c);
+		assertEquals(numSequences * 1, root_c_a_d.getCount());
+		assertNull(root_c_a_r);
+		assertNull(root_c_b);
+		assertNull(root_c_c);
+		assertNull(root_c_d);
+		assertNull(root_c_r);
+
+		assertEquals(numSequences * 1, root_d.getCount());
+		assertEquals(numSequences * 1, root_d_a.getCount());
+		assertNull(root_d_a_a);
+		assertEquals(numSequences * 1, root_d_a_b.getCount());
+		assertNull(root_d_a_c);
+		assertNull(root_d_a_d);
+		assertNull(root_d_a_r);
+		assertNull(root_d_b);
+		assertNull(root_d_c);
+		assertNull(root_d_d);
+		assertNull(root_d_r);
+
+		assertEquals(numSequences * 2, root_r.getCount());
+		assertEquals(numSequences * 2, root_r_a.getCount());
+		assertNull(root_r_a_a);
+		assertNull(root_r_a_b);
+		assertEquals(numSequences * 1, root_r_a_c.getCount());
+		assertNull(root_r_a_d);
+		assertNull(root_r_a_r);
+		assertEquals(numSequences * 1, root_r_a_end.getCount());
+		assertNull(root_r_b);
+		assertNull(root_r_c);
+		assertNull(root_r_d);
+		assertNull(root_r_r);
+
+		assertEquals(numSequences * 1, root_start.getCount());
+		assertEquals(numSequences * 1, root_start_a.getCount());
+		assertNull(root_start_a_a);
+		assertEquals(numSequences * 1, root_start_a_b.getCount());
+		assertNull(root_start_a_c);
+		assertNull(root_start_a_d);
+		assertNull(root_start_a_r);
+		assertNull(root_start_b);
+		assertNull(root_start_c);
+		assertNull(root_start_d);
+		assertNull(root_start_r);
+
+		// check if leafs are really leafs
+		assertTrue(root_a_b_r.isLeaf());
+		assertTrue(root_a_c_a.isLeaf());
+		assertTrue(root_a_d_a.isLeaf());
+		assertTrue(root_b_r_a.isLeaf());
+		assertTrue(root_c_a_d.isLeaf());
+		assertTrue(root_d_a_b.isLeaf());
+		assertTrue(root_r_a_c.isLeaf());
+		assertTrue(root_r_a_end.isLeaf());
+	}
+
+	private static void assertCollectionContent(Collection<?> c1,
+			Collection<?> c2) {
+		assertEquals(c1.size(), c2.size());
+		for (Object obj : c1) {
+			assertTrue(c2.contains(obj));
+		}
+	}
+
+	@Test
+	public void testTrieBasedModel_1() throws Exception {
+		int markovOrder = 2;
+		Random r = new Random();
+
+		MockTrieBasedModel result = new MockTrieBasedModel(markovOrder, r);
+
+		assertNotNull(result);
+		assertEquals(markovOrder + 1, result.trieOrder);
+		assertEquals(r, result.r);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testTrieBasedModel_2() throws Exception {
+		int markovOrder = -1;
+		Random r = new Random();
+
+		new MockTrieBasedModel(markovOrder, r);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testTrieBasedModel_3() throws Exception {
+		int markovOrder = 2;
+		Random r = null;
+
+		new MockTrieBasedModel(markovOrder, r);
+	}
+
+	@Test
+	public void testGenerateSequences_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 2;
+
+		Collection<List<Event<?>>> expected = new HashSet<List<Event<?>>>();
+		ArrayList<Event<?>> list;
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("a"));
+		list.add(Event.ENDEVENT);
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("b"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("c"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("d"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("b"));
+		list.add(new Event<String>("r"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("c"));
+		list.add(new Event<String>("a"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("d"));
+		list.add(new Event<String>("a"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(new Event<String>("r"));
+		list.add(new Event<String>("a"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		expected.add(list);
+
+		Collection<List<? extends Event<?>>> result = fixture
+				.generateSequences(length);
+
+		assertCollectionContent(expected, result);
+	}
+
+	@Test
+	public void testGenerateSequences_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 3;
+
+		Collection<List<Event<?>>> expected = new HashSet<List<Event<?>>>();
+		ArrayList<Event<?>> list;
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(Event.ENDEVENT);
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("b"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("c"));
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("d"));
+		expected.add(list);
+
+		Collection<List<? extends Event<?>>> result = fixture
+				.generateSequences(length, true);
+
+		assertCollectionContent(expected, result);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGenerateSequences_3() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 0;
+
+		fixture.generateSequences(length, false);
+	}
+
+	@Test
+	public void testGenerateValidSequences_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 5;
+
+		Collection<List<Event<?>>> expected = new HashSet<List<Event<?>>>();
+		ArrayList<Event<?>> list;
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("c"));
+		list.add(new Event<String>("a"));
+		list.add(Event.ENDEVENT);
+		expected.add(list);
+		list = new ArrayList<Event<?>>();
+		list.add(Event.STARTEVENT);
+		list.add(new Event<String>("a"));
+		list.add(new Event<String>("d"));
+		list.add(new Event<String>("a"));
+		list.add(Event.ENDEVENT);
+		expected.add(list);
+
+		Collection<List<? extends Event<?>>> result = fixture
+				.generateValidSequences(length);
+
+		assertCollectionContent(expected, result);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGenerateValidSequences_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+		int length = 0;
+
+		fixture.generateValidSequences(length);
+	}
+
+	@Test
+	public void testGetEvents_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+
+		fixture.train(sequences);
+
+		Collection<? extends Event<?>> result = fixture.getEvents();
+
+		assertCollectionContent(symbols, result);
+	}
+
+	@Test
+	public void testGetEvents_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+
+		Collection<? extends Event<?>> result = fixture.getEvents();
+
+		assertCollectionContent(new HashSet<Event<?>>(), result);
+	}
+
+	@Test
+	public void testGetNumFOMStates_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+
+		fixture.train(sequences);
+
+		int result = fixture.getNumFOMStates();
+
+		assertEquals(10, result);
+	}
+
+	@Test
+	public void testGetNumFOMStates_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		;
+
+		int result = fixture.getNumFOMStates();
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testGetNumSymbols_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+
+		int result = fixture.getNumSymbols();
+
+		assertEquals(7, result);
+	}
+
+	@Test
+	public void testGetNumSymbols_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+
+		int result = fixture.getNumSymbols();
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testGetNumTransitions_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+
+		int result = fixture.getNumTransitions();
+
+		assertEquals(11, result);
+	}
+
+	@Test
+	public void testGetNumTransitions_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+
+		int result = fixture.getNumTransitions();
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testTrain_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+
+		fixture.train(sequences);
+
+		assertCollectionContent(symbols, fixture.getEvents());
+
+		assertTrieStructure(fixture.trie, 1);
+	}
+
+	@Test
+	public void testTrain_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		sequences.add(sequence);
+
+		fixture.train(sequences);
+
+		assertCollectionContent(symbols, fixture.getEvents());
+
+		assertTrieStructure(fixture.trie, 2);
+	}
+	
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testTrain_3() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = null;
+
+		fixture.train(sequences);
+	}
+
+	@Test
+	public void testUpdate_1() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = new ArrayList<List<? extends Event<?>>>();
+		sequences.add(sequence);
+		fixture.train(sequences);
+
+		fixture.update(sequences);
+
+		assertCollectionContent(symbols, fixture.getEvents());
+		assertTrieStructure(fixture.trie, 2);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testUpdate_2() throws Exception {
+		int markovOrder = 2;
+		MockTrieBasedModel fixture = new MockTrieBasedModel(markovOrder,
+				new Random());
+		Collection<List<? extends Event<?>>> sequences = null;
+		fixture.trie = null;
+
+		fixture.update(sequences);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		sequence = new ArrayList<Event<?>>();
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("c"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("d"));
+		sequence.add(new Event<String>("a"));
+		sequence.add(new Event<String>("b"));
+		sequence.add(new Event<String>("r"));
+		sequence.add(new Event<String>("a"));
+
+		symbols = new HashSet<Event<?>>();
+		symbols.add(new Event<String>("a"));
+		symbols.add(new Event<String>("b"));
+		symbols.add(new Event<String>("c"));
+		symbols.add(new Event<String>("d"));
+		symbols.add(new Event<String>("r"));
+		symbols.add(Event.STARTEVENT);
+		symbols.add(Event.ENDEVENT);
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(TrieBasedModelTest.class);
+	}
+}
Index: /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/TrieTest.java
===================================================================
--- /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/TrieTest.java	(revision 433)
+++ /trunk/quest-core-event-test/src/de/ugoe/cs/quest/usageprofiles/TrieTest.java	(revision 433)
@@ -0,0 +1,727 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import junitx.framework.ListAssert;
+
+import org.junit.*;
+
+import de.ugoe.cs.quest.usageprofiles.Trie;
+import de.ugoe.cs.quest.usageprofiles.TrieNode;
+import de.ugoe.cs.quest.usageprofiles.Trie.Edge;
+import de.ugoe.cs.quest.usageprofiles.Trie.TrieVertex;
+import static org.junit.Assert.*;
+
+/**
+ * The class <code>TrieTest</code> contains tests for the class
+ * <code>{@link Trie}</code>.
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class TrieTest {
+
+	List<String> sequence;
+	Collection<String> symbols;
+
+	private static void assertCollectionContent(Collection<?> c1,
+			Collection<?> c2) {
+		assertEquals(c1.size(), c2.size());
+		for (Object obj : c1) {
+			assertTrue(c2.contains(obj));
+		}
+	}
+
+	@Test
+	public void testTrie_1() throws Exception {
+
+		Trie<String> result = new Trie<String>();
+
+		assertNotNull(result);
+		assertEquals(0, result.getNumLeafs());
+		assertEquals(0, result.getNumSymbols());
+		assertEquals(0, result.getNumLeafAncestors());
+		assertTrue(result.getKnownSymbols().isEmpty());
+	}
+
+	@Test
+	public void testTrie_2() throws Exception {
+		Trie<String> trie1 = new Trie<String>();
+		trie1.train(sequence, 3);
+
+		Trie<String> result = new Trie<String>(trie1);
+
+		assertEquals(trie1, result);
+		assertNotSame(trie1, result);
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testTrie_3() throws Exception {
+		new Trie<String>(null);
+	}
+
+	@Test
+	public void testAdd_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		List<String> seq = new ArrayList<String>();
+		seq.add("a");
+		seq.add("b");
+
+		fixture.add(seq);
+
+		assertEquals(1, fixture.getChild("a").getCount());
+		assertEquals(1, fixture.getChild("a").getChild("b").getCount());
+		assertNull(fixture.getChild("b"));
+	}
+
+	@Test
+	public void testAdd_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+
+		fixture.add(new ArrayList<String>());
+
+		assertEquals(0, fixture.getNumSymbols());
+	}
+
+	@Test
+	public void testAdd_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+
+		fixture.add(null);
+
+		assertEquals(0, fixture.getNumSymbols());
+	}
+
+	@Test
+	public void testFind_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> findSequence = new ArrayList<String>();
+		findSequence.add("a");
+		findSequence.add("b");
+		findSequence.add("r");
+		TrieNode<String> expected = fixture.getChild("a").getChild("b")
+				.getChild("r");
+
+		TrieNode<String> result = fixture.find(findSequence);
+
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testFind_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> findSequence = new ArrayList<String>();
+		findSequence.add("c");
+		findSequence.add("a");
+		TrieNode<String> expected = fixture.getChild("c").getChild("a");
+
+		TrieNode<String> result = fixture.find(findSequence);
+
+		assertEquals(expected, result);
+	}
+
+	@Test
+	public void testFind_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> findSequence = new ArrayList<String>();
+
+		TrieNode<String> result = fixture.find(findSequence);
+
+		assertTrue(result.isRoot());
+	}
+
+	@Test
+	public void testFind_4() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		TrieNode<String> result = fixture.find(null);
+
+		assertTrue(result.isRoot());
+	}
+
+	@Test
+	public void testGetChildCreate_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		String symbol = "a";
+
+		TrieNode<String> result = fixture.getChildCreate(symbol);
+
+		assertEquals(symbol, result.getSymbol());
+		assertEquals(0, result.getCount());
+		assertTrue(result.isLeaf());
+	}
+
+	@Test(expected = java.security.InvalidParameterException.class)
+	public void testGetChildCreate_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.getChildCreate(null);
+	}
+
+	@Test
+	public void testGetContextSuffix_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> context = new ArrayList<String>();
+		context.add("a");
+		context.add("a");
+		context.add("b");
+		List<String> expected = new ArrayList<String>();
+		expected.add("a");
+		expected.add("b");
+
+		List<String> result = fixture.getContextSuffix(context);
+
+		ListAssert.assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetContextSuffix_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> context = new ArrayList<String>();
+		context.add("a");
+		context.add("a");
+		context.add("b");
+		context.add("r");
+		List<String> expected = new ArrayList<String>();
+		expected.add("b");
+		expected.add("r");
+
+		List<String> result = fixture.getContextSuffix(context);
+
+		ListAssert.assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetContextSuffix_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> context = new ArrayList<String>();
+		context.add("a");
+		context.add("a");
+		context.add("b");
+		context.add("x");
+		List<String> expected = new ArrayList<String>();
+
+		List<String> result = fixture.getContextSuffix(context);
+
+		ListAssert.assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetContextSuffix_4() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+
+		List<String> result = fixture.getContextSuffix(null);
+
+		// add additional test code here
+		assertNotNull(result);
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetContextSuffix_5() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> context = new ArrayList<String>();
+		context.add("a");
+		context.add("a");
+		context.add("b");
+		List<String> expected = new ArrayList<String>();
+		expected.add("a");
+		expected.add("b");
+
+		List<String> result = fixture.getContextSuffix(context);
+
+		ListAssert.assertEquals(expected, result);
+	}
+
+	@Test
+	public void testGetCount_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+
+		int result = fixture.getCount(subSequence);
+
+		assertEquals(5, result);
+	}
+
+	@Test
+	public void testGetCount_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+		subSequence.add("b");
+
+		int result = fixture.getCount(subSequence);
+
+		assertEquals(2, result);
+	}
+
+	@Test
+	public void testGetCount_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("x");
+
+		int result = fixture.getCount(subSequence);
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testGetCount_4() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+
+		int result = fixture.getCount(subSequence, "a");
+
+		assertEquals(5, result);
+	}
+
+	@Test
+	public void testGetCount_5() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+		subSequence.add("b");
+
+		int result = fixture.getCount(subSequence, "r");
+
+		assertEquals(2, result);
+	}
+
+	@Test
+	public void testGetCount_6() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+
+		int result = fixture.getCount(subSequence, "x");
+
+		assertEquals(0, result);
+	}
+
+	@Test
+	public void testGetFollowingSymbols_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+		Collection<String> expected = new ArrayList<String>();
+		expected.add("b");
+		expected.add("c");
+		expected.add("d");
+
+		Collection<String> result = fixture.getFollowingSymbols(subSequence);
+
+		assertCollectionContent(expected, result);
+	}
+
+	@Test
+	public void testGetFollowingSymbols_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("a");
+		subSequence.add("b");
+		subSequence.add("r");
+
+		Collection<String> result = fixture.getFollowingSymbols(subSequence);
+
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetFollowingSymbols_3() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+		List<String> subSequence = new ArrayList<String>();
+		subSequence.add("x");
+
+		Collection<String> result = fixture.getFollowingSymbols(subSequence);
+
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetNumLeafAncestors_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		int result = fixture.getNumLeafAncestors();
+
+		assertEquals(7, result);
+	}
+
+	@Test
+	public void testGetNumLeafs_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		int result = fixture.getNumLeafs();
+
+		assertEquals(7, result);
+	}
+
+	@Test
+	public void testGetNumSymbols_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		int result = fixture.getNumSymbols();
+
+		assertEquals(5, result);
+	}
+
+	@Test
+	public void testTrain_1() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		int maxOrder = 3;
+
+		fixture.train(sequence, maxOrder);
+
+		// check if symbols are correct
+		assertCollectionContent(symbols, fixture.getKnownSymbols());
+
+		// check if counters are correct and only the correct nodes exist
+		TrieNode<String> root = fixture.find(new ArrayList<String>());
+		TrieNode<String> root_a = root.getChild("a");
+		TrieNode<String> root_a_a = root_a.getChild("a");
+		TrieNode<String> root_a_b = root_a.getChild("b");
+		TrieNode<String> root_a_b_a = root_a_b.getChild("a");
+		TrieNode<String> root_a_b_b = root_a_b.getChild("b");
+		TrieNode<String> root_a_b_c = root_a_b.getChild("c");
+		TrieNode<String> root_a_b_d = root_a_b.getChild("d");
+		TrieNode<String> root_a_b_r = root_a_b.getChild("r");
+		TrieNode<String> root_a_c = root_a.getChild("c");
+		TrieNode<String> root_a_c_a = root_a_c.getChild("a");
+		TrieNode<String> root_a_c_b = root_a_c.getChild("b");
+		TrieNode<String> root_a_c_c = root_a_c.getChild("c");
+		TrieNode<String> root_a_c_d = root_a_c.getChild("d");
+		TrieNode<String> root_a_c_r = root_a_c.getChild("r");
+		TrieNode<String> root_a_d = root_a.getChild("d");
+		TrieNode<String> root_a_d_a = root_a_d.getChild("a");
+		TrieNode<String> root_a_d_b = root_a_d.getChild("b");
+		TrieNode<String> root_a_d_c = root_a_d.getChild("c");
+		TrieNode<String> root_a_d_d = root_a_d.getChild("d");
+		TrieNode<String> root_a_d_r = root_a_d.getChild("r");
+		TrieNode<String> root_a_r = root_a.getChild("r");
+		TrieNode<String> root_b = root.getChild("b");
+		TrieNode<String> root_b_a = root_b.getChild("a");
+		TrieNode<String> root_b_b = root_b.getChild("b");
+		TrieNode<String> root_b_c = root_b.getChild("c");
+		TrieNode<String> root_b_d = root_b.getChild("d");
+		TrieNode<String> root_b_r = root_b.getChild("r");
+		TrieNode<String> root_b_r_a = root_b_r.getChild("a");
+		TrieNode<String> root_b_r_b = root_b_r.getChild("b");
+		TrieNode<String> root_b_r_c = root_b_r.getChild("c");
+		TrieNode<String> root_b_r_d = root_b_r.getChild("d");
+		TrieNode<String> root_b_r_r = root_b_r.getChild("r");
+		TrieNode<String> root_c = root.getChild("c");
+		TrieNode<String> root_c_a = root_c.getChild("a");
+		TrieNode<String> root_c_a_a = root_c_a.getChild("a");
+		TrieNode<String> root_c_a_b = root_c_a.getChild("b");
+		TrieNode<String> root_c_a_c = root_c_a.getChild("c");
+		TrieNode<String> root_c_a_d = root_c_a.getChild("d");
+		TrieNode<String> root_c_a_r = root_c_a.getChild("r");
+		TrieNode<String> root_c_b = root_c.getChild("b");
+		TrieNode<String> root_c_c = root_c.getChild("c");
+		TrieNode<String> root_c_d = root_c.getChild("d");
+		TrieNode<String> root_c_r = root_c.getChild("r");
+		TrieNode<String> root_d = root.getChild("d");
+		TrieNode<String> root_d_a = root_d.getChild("a");
+		TrieNode<String> root_d_a_a = root_d_a.getChild("a");
+		TrieNode<String> root_d_a_b = root_d_a.getChild("b");
+		TrieNode<String> root_d_a_c = root_d_a.getChild("c");
+		TrieNode<String> root_d_a_d = root_d_a.getChild("d");
+		TrieNode<String> root_d_a_r = root_d_a.getChild("r");
+		TrieNode<String> root_d_b = root_d.getChild("b");
+		TrieNode<String> root_d_c = root_d.getChild("c");
+		TrieNode<String> root_d_d = root_d.getChild("d");
+		TrieNode<String> root_d_r = root_d.getChild("r");
+		TrieNode<String> root_r = root.getChild("r");
+		TrieNode<String> root_r_a = root_r.getChild("a");
+		TrieNode<String> root_r_a_a = root_r_a.getChild("a");
+		TrieNode<String> root_r_a_b = root_r_a.getChild("b");
+		TrieNode<String> root_r_a_c = root_r_a.getChild("c");
+		TrieNode<String> root_r_a_d = root_r_a.getChild("d");
+		TrieNode<String> root_r_a_r = root_r_a.getChild("r");
+		TrieNode<String> root_r_b = root_r.getChild("b");
+		TrieNode<String> root_r_c = root_r.getChild("c");
+		TrieNode<String> root_r_d = root_r.getChild("d");
+		TrieNode<String> root_r_r = root_r.getChild("r");
+
+		assertEquals(5, root_a.getCount());
+		assertNull(root_a_a);
+		assertEquals(2, root_a_b.getCount());
+		assertNull(root_a_b_a);
+		assertNull(root_a_b_b);
+		assertNull(root_a_b_c);
+		assertNull(root_a_b_d);
+		assertEquals(2, root_a_b_r.getCount());
+		assertEquals(1, root_a_c.getCount());
+		assertEquals(1, root_a_c_a.getCount());
+		assertNull(root_a_c_b);
+		assertNull(root_a_c_c);
+		assertNull(root_a_c_d);
+		assertNull(root_a_c_r);
+		assertEquals(1, root_a_d.getCount());
+		assertEquals(1, root_a_d_a.getCount());
+		assertNull(root_a_d_b);
+		assertNull(root_a_d_c);
+		assertNull(root_a_d_d);
+		assertNull(root_a_d_r);
+		assertNull(root_a_r);
+
+		assertEquals(2, root_b.getCount());
+		assertNull(root_b_a);
+		assertNull(root_b_b);
+		assertNull(root_b_c);
+		assertNull(root_b_d);
+		assertEquals(2, root_b_r.getCount());
+		assertEquals(2, root_b_r_a.getCount());
+		assertNull(root_b_r_b);
+		assertNull(root_b_r_c);
+		assertNull(root_b_r_d);
+		assertNull(root_b_r_r);
+
+		assertEquals(1, root_c.getCount());
+		assertEquals(1, root_c_a.getCount());
+		assertNull(root_c_a_a);
+		assertNull(root_c_a_b);
+		assertNull(root_c_a_c);
+		assertEquals(1, root_c_a_d.getCount());
+		assertNull(root_c_a_r);
+		assertNull(root_c_b);
+		assertNull(root_c_c);
+		assertNull(root_c_d);
+		assertNull(root_c_r);
+
+		assertEquals(1, root_d.getCount());
+		assertEquals(1, root_d_a.getCount());
+		assertNull(root_d_a_a);
+		assertEquals(1, root_d_a_b.getCount());
+		assertNull(root_d_a_c);
+		assertNull(root_d_a_d);
+		assertNull(root_d_a_r);
+		assertNull(root_d_b);
+		assertNull(root_d_c);
+		assertNull(root_d_d);
+		assertNull(root_d_r);
+
+		assertEquals(2, root_r.getCount());
+		assertEquals(2, root_r_a.getCount());
+		assertNull(root_r_a_a);
+		assertNull(root_r_a_b);
+		assertEquals(1, root_r_a_c.getCount());
+		assertNull(root_r_a_d);
+		assertNull(root_r_a_r);
+		assertNull(root_r_b);
+		assertNull(root_r_c);
+		assertNull(root_r_d);
+		assertNull(root_r_r);
+
+		// check if leafs are really leafs
+		assertTrue(root_a_b_r.isLeaf());
+		assertTrue(root_a_c_a.isLeaf());
+		assertTrue(root_a_d_a.isLeaf());
+		assertTrue(root_b_r_a.isLeaf());
+		assertTrue(root_c_a_d.isLeaf());
+		assertTrue(root_d_a_b.isLeaf());
+		assertTrue(root_r_a_c.isLeaf());
+	}
+
+	@Test
+	public void testTrain_2() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		int maxOrder = 0;
+
+		fixture.train(sequence, maxOrder);
+
+		assertTrue(fixture.getKnownSymbols().isEmpty());
+	}
+
+	@Test
+	public void testTrain_3() throws Exception {
+		Trie<Object> fixture = new Trie<Object>();
+		List<Object> sequence = new ArrayList<Object>();
+		int maxOrder = 1;
+
+		fixture.train(sequence, maxOrder);
+
+		assertTrue(fixture.getKnownSymbols().isEmpty());
+	}
+
+	@Test
+	public void testTrain_4() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		List<String> sequence = new ArrayList<String>();
+		sequence.add("a");
+		sequence.add("b");
+		int maxOrder = 3;
+
+		fixture.train(sequence, maxOrder);
+
+		assertCollectionContent(sequence, fixture.getKnownSymbols());
+		TrieNode<String> root = fixture.find(new ArrayList<String>());
+		TrieNode<String> root_a = root.getChild("a");
+		TrieNode<String> root_a_a = root_a.getChild("a");
+		TrieNode<String> root_a_b = root_a.getChild("b");
+		TrieNode<String> root_b = root.getChild("b");
+		TrieNode<String> root_b_a = root_b.getChild("a");
+		TrieNode<String> root_b_b = root_b.getChild("b");
+
+		assertEquals(1, root_a.getCount());
+		assertNull(root_a_a);
+		assertEquals(1, root_a_b.getCount());
+		assertEquals(1, root_b.getCount());
+		assertNull(root_b_a);
+		assertNull(root_b_b);
+
+		assertTrue(root_a_b.isLeaf());
+		assertTrue(root_b.isLeaf());
+	}
+
+	@Test
+	public void testEdgeEdge_1() throws Exception {
+		Edge result = new Edge();
+
+		assertNotNull(result);
+	}
+
+	@Test
+	public void testTrieVertexTrieVertex_1() throws Exception {
+		String id = "idString";
+
+		TrieVertex result = new TrieVertex(id);
+
+		assertNotNull(result);
+	}
+
+	@Test
+	public void testTrieVertexToString_1() throws Exception {
+		String id = "idString";
+		TrieVertex fixture = new TrieVertex(id);
+
+		String result = fixture.toString();
+
+		assertEquals(id, result);
+	}
+
+	@Test
+	public void testEquals_1() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		Trie<String> fixture = new Trie<String>();
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(true, result);
+	}
+
+	@Test
+	public void testEquals_2() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		trieOther.train(sequence, 2);
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 2);
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(true, result);
+	}
+
+	@Test
+	public void testEquals_3() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		trieOther.train(sequence, 2);
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 3);
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(false, result);
+	}
+
+	@Test
+	public void testEquals_4() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 2);
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(false, result);
+	}
+
+	@Test
+	public void testEquals_5() throws Exception {
+		Trie<String> trieOther = new Trie<String>();
+		trieOther.train(sequence, 2);
+		Trie<String> fixture = new Trie<String>();
+
+		boolean result = fixture.equals(trieOther);
+
+		assertEquals(false, result);
+	}
+
+	@Test
+	public void testEquals_6() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 2);
+
+		boolean result = fixture.equals(fixture);
+
+		assertEquals(true, result);
+	}
+
+	@Test
+	public void testEquals_7() throws Exception {
+		Trie<String> fixture = new Trie<String>();
+		fixture.train(sequence, 2);
+
+		boolean result = fixture.equals(null);
+
+		assertEquals(false, result);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		sequence = new ArrayList<String>();
+		sequence.add("a");
+		sequence.add("b");
+		sequence.add("r");
+		sequence.add("a");
+		sequence.add("c");
+		sequence.add("a");
+		sequence.add("d");
+		sequence.add("a");
+		sequence.add("b");
+		sequence.add("r");
+		sequence.add("a");
+
+		symbols = new HashSet<String>();
+		symbols.add("a");
+		symbols.add("b");
+		symbols.add("c");
+		symbols.add("d");
+		symbols.add("r");
+	}
+
+	public static void main(String[] args) {
+		new org.junit.runner.JUnitCore().run(TrieTest.class);
+	}
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/SequenceInstanceOf.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/SequenceInstanceOf.java	(revision 432)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/SequenceInstanceOf.java	(revision 433)
@@ -5,5 +5,5 @@
 import java.util.NoSuchElementException;
 
-import de.ugoe.cs.quest.data.Event;
+import de.ugoe.cs.quest.eventcore.Event;
 
 /**
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/assertions/AssertEvent.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/assertions/AssertEvent.java	(revision 432)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/assertions/AssertEvent.java	(revision 433)
@@ -1,7 +1,7 @@
 package de.ugoe.cs.quest.assertions;
 
-import de.ugoe.cs.quest.data.Event;
-import de.ugoe.cs.quest.data.IReplayable;
-import de.ugoe.cs.quest.data.ReplayableEvent;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
 
 /**
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/assertions/FileEqualsReplay.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/assertions/FileEqualsReplay.java	(revision 432)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/assertions/FileEqualsReplay.java	(revision 433)
@@ -3,5 +3,5 @@
 import java.security.InvalidParameterException;
 
-import de.ugoe.cs.quest.data.IReplayable;
+import de.ugoe.cs.quest.eventcore.IReplayable;
 import de.ugoe.cs.util.StringTools;
 
@@ -64,5 +64,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getReplay()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
 	 */
 	public String getReplay() {
@@ -82,5 +82,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getTarget()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
 	 */
 	@Override
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/assertions/TextEqualsReplay.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/assertions/TextEqualsReplay.java	(revision 432)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/assertions/TextEqualsReplay.java	(revision 433)
@@ -3,5 +3,5 @@
 import java.security.InvalidParameterException;
 
-import de.ugoe.cs.quest.data.IReplayable;
+import de.ugoe.cs.quest.eventcore.IReplayable;
 import de.ugoe.cs.util.StringTools;
 
@@ -60,5 +60,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getReplay()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
 	 */
 	@Override
@@ -85,5 +85,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getTarget()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
 	 */
 	@Override
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/coverage/CoverageCalculatorObserved.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/coverage/CoverageCalculatorObserved.java	(revision 432)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/coverage/CoverageCalculatorObserved.java	(revision 433)
@@ -7,6 +7,6 @@
 import java.util.Map;
 
-import de.ugoe.cs.quest.data.Event;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 
 /**
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/coverage/CoverageCalculatorProcess.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/coverage/CoverageCalculatorProcess.java	(revision 432)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/coverage/CoverageCalculatorProcess.java	(revision 433)
@@ -6,6 +6,6 @@
 import java.util.Map;
 
-import de.ugoe.cs.quest.data.Event;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 
 /**
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/coverage/SequenceTools.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/coverage/SequenceTools.java	(revision 432)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/coverage/SequenceTools.java	(revision 433)
@@ -10,6 +10,6 @@
 import java.util.Set;
 
-import de.ugoe.cs.quest.data.Event;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 
 /**
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/eventcore/Event.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/eventcore/Event.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/eventcore/Event.java	(revision 433)
@@ -0,0 +1,327 @@
+package de.ugoe.cs.quest.eventcore;
+
+import java.io.Serializable;
+import java.security.InvalidParameterException;
+
+/**
+ * <p>
+ * Base class for all events. An event is described by its {@link #type} and its
+ * {@link #target}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ * @param <T>
+ *            Can be used to declare that events belong to a specific platform
+ *            without subclassing.
+ */
+public class Event<T> implements Serializable {
+
+	/**
+	 * Id for object serialization.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Global start event that can be used to indicate the start of a sequence.
+	 * </p>
+	 */
+	public static final Event<Object> STARTEVENT = new Event<Object>("START");
+
+	/**
+	 * <p>
+	 * Global end event that can be used to indicate the end of a sequence.
+	 */
+	public static final Event<Object> ENDEVENT = new Event<Object>("END");
+
+	/**
+	 * <p>
+	 * Type of the event.
+	 * </p>
+	 */
+	protected String type;
+
+	/**
+	 * </p> Target of the event.
+	 */
+	protected String target = null;
+
+	/**
+	 * <p>
+	 * Short description of the event target.
+	 * </p>
+	 */
+	protected String targetShort = null;
+
+	/**
+	 * Further information about the event that shall be included in its Id.
+	 */
+	protected String idInfo = "";
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new Event with a given type.
+	 * </p>
+	 * 
+	 * @param type
+	 *            type of the event
+	 */
+	public Event(String type) {
+		if (type == null) {
+			throw new InvalidParameterException("Event type must not be null");
+		}
+		this.type = type;
+	}
+
+	/**
+	 * <p>
+	 * Two events are equal, if their {@link #type} and {@link #target} are
+	 * equal.
+	 * </p>
+	 * <p>
+	 * See {@link Object#equals(Object)} for further information.
+	 * </p>
+	 * 
+	 * @param other
+	 *            Event that is compared to this
+	 * @return true, if events are equal, false otherwise
+	 */
+	@Override
+	public boolean equals(Object other) {
+		if (this == other) {
+			return true;
+		}
+		if (other instanceof Event<?>) {
+			Event<?> otherEvent = (Event<?>) other;
+			if (otherEvent.canEqual(this)) {
+				if (type != null) {
+					return targetEquals(otherEvent.target)
+							&& type.equals(otherEvent.type);
+				} else {
+					return targetEquals(otherEvent.target)
+							&& otherEvent.type == null;
+				}
+			} else {
+				return false;
+			}
+		} else {
+			return false;
+		}
+	}
+
+	public boolean canEqual(Object other) {
+		return (other instanceof Event<?>);
+	}
+
+	/**
+	 * <p>
+	 * Returns {@link #getStandardId()} as String representation of the event.
+	 * </p>
+	 * 
+	 * @return String represenation of the event
+	 */
+	@Override
+	public String toString() {
+		return getStandardId();
+	}
+
+	/**
+	 * Informations about the event important for its Id that is neither target
+	 * nor type.
+	 * 
+	 * @return {@link #idInfo} of the event
+	 */
+	public String getIdInfo() {
+		return idInfo;
+	}
+
+	/**
+	 * <p>
+	 * If {@link #targetShort} is set, a shortend version of the Id is returned
+	 * of the form {@link #targetShort}.{@link #type}.{@link #idInfo} is
+	 * returned. Otherwise the standard Id is returned (see
+	 * {@link #getStandardId()}).
+	 * </p>
+	 * 
+	 * @return if available, shortend Id string; {@link #getStandardId()}
+	 *         otherwise
+	 */
+	public String getShortId() {
+		String shortId = null;
+		if (targetShort != null) {
+			shortId = targetShort + "." + getType();
+			if (!"".equals(idInfo)) {
+				shortId += "." + idInfo;
+			}
+		} else {
+			shortId = getStandardId();
+		}
+		return shortId;
+	}
+
+	/**
+	 * <p>
+	 * Returns the Id string of the event. It has the form {@link #target}.
+	 * {@link #type}.{@link #idInfo};
+	 * <p>
+	 * 
+	 * @return Id string of the event
+	 */
+	public String getStandardId() {
+		String id = "";
+		if (target != null) {
+			id += target + ".";
+		}
+		id += getType();
+		if (!"".equals(idInfo)) {
+			id += "." + idInfo;
+		}
+		return id;
+	}
+
+	/**
+	 * <p>
+	 * Returns the {@link #target} of the event.
+	 * </p>
+	 * 
+	 * @return {@link #target} of the event
+	 */
+	public String getTarget() {
+		return target;
+	}
+
+	/**
+	 * <p>
+	 * Returns the {@link #targetShort} of the event.
+	 * </p>
+	 * 
+	 * @return {@link #targetShort} of the event
+	 */
+	protected String getTargetShort() {
+		return targetShort;
+	}
+
+	/**
+	 * <p>
+	 * Returns the {@link #type} of the event.
+	 * </p>
+	 * 
+	 * @return {@link #type} of the event
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		int multiplier = 17;
+		int hash = 42;
+		if (type != null) {
+			hash = multiplier * hash + type.hashCode();
+		}
+		hash = multiplier * hash + targetHashCode();
+
+		return hash;
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #idInfo} of the event. The idInfo is optional and
+	 * contains information important for the event's Id that is neither target
+	 * nor type.
+	 * </p>
+	 * 
+	 * @param info
+	 *            {@link #idInfo} of the event
+	 */
+	public void setIdInfo(String info) {
+		idInfo = info;
+	}
+
+	/**
+	 * <p>
+	 * Sets the target of the event. Once set, the target cannot be changed.
+	 * </p>
+	 * 
+	 * @param target
+	 *            target of the event
+	 * @return true, if target was changed, false otherwise
+	 */
+	public boolean setTarget(String target) {
+		if (this.target != null) {
+			return false;
+		}
+		this.target = target;
+		return true;
+	}
+
+	/**
+	 * <p>
+	 * Sets the short description of the event target. Once set, the target
+	 * cannot be changed.
+	 * </p>
+	 * 
+	 * @param targetShort
+	 *            short target description
+	 * @return true, if target was changed, false otherwise
+	 */
+	public boolean setTargetShort(String targetShort) {
+		if (this.targetShort != null) {
+			return false;
+		}
+		this.targetShort = targetShort;
+		return true;
+	}
+
+	/**
+	 * <p>
+	 * This function is used by {@link #equals(Object)} to determine if the
+	 * targets of both events are equal. The standard implementation provided by
+	 * this class performs a String comparison between the target strings.
+	 * </p>
+	 * <p>
+	 * Subclasses can override this method to implemented more sophisticated
+	 * means for the target comparison, e.g., to account for changes in the
+	 * title of a widget.
+	 * </p>
+	 * 
+	 * @param otherTarget
+	 *            other target string to which the target if this event is
+	 *            compared to
+	 * @return true if the targets are equals; false otherwise
+	 */
+	protected boolean targetEquals(String otherTarget) {
+		boolean retVal;
+		if (target != null) {
+			retVal = target.equals(otherTarget);
+		} else {
+			retVal = (otherTarget == null);
+		}
+		return retVal;
+	}
+
+	/**
+	 * <p>
+	 * This function is used by {@link #hashCode()} to determine how the hash of
+	 * the {@link #target}. It has to be overridden by subclasses that implement
+	 * {@link #targetEquals(String)}, to ensure that the equals/hashCode
+	 * contract remains valid.
+	 * </p>
+	 * 
+	 * @return hash of the target
+	 */
+	protected int targetHashCode() {
+		if (target != null) {
+			return target.hashCode();
+		} else {
+			return 0;
+		}
+	}
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/eventcore/IReplayable.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/eventcore/IReplayable.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/eventcore/IReplayable.java	(revision 433)
@@ -0,0 +1,35 @@
+package de.ugoe.cs.quest.eventcore;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * This interface is used by {@link ReplayableEvent}to describe how events can
+ * be replayed. It can be used to define a sequence of fine-grained platform
+ * events that make up an abstract event.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IReplayable extends Serializable {
+
+	/**
+	 * <p>
+	 * Returns a string to be written to the replay script that describes the
+	 * replayable platform event.
+	 * </p>
+	 * 
+	 * @return string for the replay script
+	 */
+	String getReplay();
+
+	/**
+	 * <p>
+	 * Returns the target of the replayable.
+	 * </p>
+	 * 
+	 * @return target of the replayable
+	 */
+	String getTarget();
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/eventcore/ReplayableEvent.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/eventcore/ReplayableEvent.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/eventcore/ReplayableEvent.java	(revision 433)
@@ -0,0 +1,167 @@
+package de.ugoe.cs.quest.eventcore;
+
+import java.security.InvalidParameterException;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.quest.IReplayDecorator;
+
+/**
+ * <p>
+ * Subclass of {@link Event} for events that contain all informations required
+ * for replaying them, i.e., generating scripts that can used for automated
+ * software execution.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ * @param <T>
+ *            Allows only types that extend {@link IReplayable} and is used to
+ *            define a list of replayables that describe the replay of the
+ *            event.
+ */
+public class ReplayableEvent<T extends IReplayable> extends Event<T> {
+
+	/**
+	 * Id for object serialization.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * List of {@link IReplayable}s of type T that describes the replay of an
+	 * event. The {@link IReplayable}s can be interpreted as <it>sub-events</it>
+	 * on the platform level that make up the abstract event.
+	 * </p>
+	 */
+	protected List<T> replayEvents = new LinkedList<T>();;
+
+	/**
+	 * <p>
+	 * Defines whether the replay is valid or invalid. It may be invalid, e.g.,
+	 * due to errors during the generation of the event or lack of vital
+	 * information.
+	 * </p>
+	 */
+	protected boolean replayValid = true;
+
+	/**
+	 * <p>
+	 * {@link IReplayDecorator} used when replays of this type are written.
+	 * </p>
+	 */
+	protected IReplayDecorator decorator = null;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new event with the given type.
+	 * <p>
+	 * 
+	 * @param type
+	 *            type of the event
+	 * @see Event#Event(String)
+	 */
+	public ReplayableEvent(String type) {
+		super(type);
+	}
+
+	/**
+	 * <p>
+	 * Adds a new {@link IReplayable} of type T to the replay sequence.
+	 * </p>
+	 * 
+	 * @param replayable
+	 *            element that is added to the sequence
+	 * @throws InvalidParameterException
+	 *             thrown is replayable is null
+	 */
+	public void addReplayEvent(T replayable) {
+		if (replayable == null) {
+			throw new InvalidParameterException("replayble must not be null");
+		}
+		replayEvents.add(replayable);
+	}
+
+	/**
+	 * <p>
+	 * Adds a {@link List}ist of {@link IReplayable} to the replay sequence.
+	 * </p>
+	 * 
+	 * @param generatedReplaySeq
+	 *            {@link List} that is added to the sequence
+	 * @throws InvalidParameterException
+	 *             thrown if generatedReplaySeq is null
+	 */
+	public void addReplaySequence(List<T> generatedReplaySeq) {
+		if (generatedReplaySeq == null) {
+			throw new InvalidParameterException(
+					"generatedReplaySeq must not be null");
+		}
+		replayEvents.addAll(generatedReplaySeq);
+	}
+
+	/**
+	 * <p>
+	 * Returns the {@link IReplayDecorator} of the event.
+	 * </p>
+	 * 
+	 * @return {@link IReplayDecorator} of the event; null if no decorator has
+	 *         been set
+	 */
+	public IReplayDecorator getReplayDecorator() {
+		return decorator;
+	}
+
+	/**
+	 * <p>
+	 * Returns a the list of replay events.
+	 * </p>
+	 * <p>
+	 * The return value is a copy of the list used internally!
+	 * </p>
+	 * 
+	 * @return list of replay events.
+	 */
+	public List<T> getReplayMessages() {
+		return new LinkedList<T>(replayEvents);
+	}
+
+	/**
+	 * <p>
+	 * Returns whether the replay is valid or not.
+	 * </p>
+	 * 
+	 * @return true, if replay is valid; false otherwise.
+	 */
+	public boolean hasValidReplay() {
+		return replayValid;
+	}
+
+	/**
+	 * <p>
+	 * Marks the replay as invalid. Once marked as invalid, it remains so and
+	 * cannot be changed back to valid.
+	 * </p>
+	 */
+	public void invalidateReplay() {
+		replayValid = false;
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link IReplayDecorator} associated with the event.
+	 * </p>
+	 * 
+	 * @param decorator
+	 *            decorator associated with the event
+	 */
+	public void setDecorator(IReplayDecorator decorator) {
+		this.decorator = decorator;
+	}
+	
+	@Override
+	public boolean canEqual(Object other) {
+		return (other instanceof ReplayableEvent<?>);
+	}
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomaton.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomaton.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/DeterministicFiniteAutomaton.java	(revision 433)
@@ -0,0 +1,80 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+/**
+ * <p>
+ * Implements a Deterministic Finite Automata (DFA) capable of random session
+ * generation. It is a special case of a first-order Markov model, where the
+ * transition probability is equally high for all following states.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class DeterministicFiniteAutomaton extends FirstOrderMarkovModel {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new DeterministicFiniteAutomaton.
+	 * </p>
+	 * 
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 */
+	public DeterministicFiniteAutomaton(Random r) {
+		super(r);
+	}
+
+	/**
+	 * <p>
+	 * Calculates the proability of the next state. Each of the following states
+	 * in the automaton is equally probable.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getProbability(java.util.List,
+	 *      de.ugoe.cs.quest.eventcore.Event)
+	 */
+	@Override
+	public double getProbability(List<? extends Event<?>> context,
+			Event<?> symbol) {
+		if( context==null ) {
+			throw new InvalidParameterException("context must not be null");
+		}
+		if( symbol==null ) {
+			throw new InvalidParameterException("symbol must not be null");
+		}
+		double result = 0.0d;
+
+		List<Event<?>> contextCopy;
+		if (context.size() >= trieOrder) {
+			contextCopy = new LinkedList<Event<?>>(context.subList(
+					context.size() - trieOrder + 1, context.size()));
+		} else {
+			contextCopy = new LinkedList<Event<?>>(context);
+		}
+
+		Collection<Event<?>> followers = trie.getFollowingSymbols(contextCopy);
+
+		if (followers.size() != 0 && followers.contains(symbol)) {
+			result = 1.0d / followers.size();
+		}
+
+		return result;
+	}
+
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModel.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModel.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/FirstOrderMarkovModel.java	(revision 433)
@@ -0,0 +1,264 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.util.StringTools;
+import de.ugoe.cs.util.console.Console;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.SparseMultigraph;
+import edu.uci.ics.jung.graph.util.EdgeType;
+
+import Jama.Matrix;
+
+/**
+ * <p>
+ * Implements first-order Markov models. The implementation is based on
+ * {@link HighOrderMarkovModel} and restricts the Markov order to 1. In
+ * comparison to {@link HighOrderMarkovModel}, more calculations are possible
+ * with first-order models, e.g., the calculation of the entropy (
+ * {@link #calcEntropy()}).
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class FirstOrderMarkovModel extends HighOrderMarkovModel implements
+		IDotCompatible {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Maximum number of iterations when calculating the stationary distribution
+	 * as the limit of multiplying the transmission matrix with itself.
+	 * </p>
+	 */
+	final static int MAX_STATDIST_ITERATIONS = 1000;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new FirstOrderMarkovModel.
+	 * </p>
+	 * 
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 */
+	public FirstOrderMarkovModel(Random r) {
+		super(1, r);
+	}
+
+	/**
+	 * <p>
+	 * Generates the transmission matrix of the Markov model.
+	 * </p>
+	 * 
+	 * @return transmission matrix
+	 */
+	private Matrix getTransmissionMatrix() {
+		List<Event<?>> knownSymbols = new ArrayList<Event<?>>(
+				trie.getKnownSymbols());
+		int numStates = knownSymbols.size();
+		Matrix transmissionMatrix = new Matrix(numStates, numStates);
+
+		for (int i = 0; i < numStates; i++) {
+			Event<?> currentSymbol = knownSymbols.get(i);
+			List<Event<?>> context = new ArrayList<Event<?>>();
+			context.add(currentSymbol);
+			for (int j = 0; j < numStates; j++) {
+				Event<?> follower = knownSymbols.get(j);
+				double prob = getProbability(context, follower);
+				transmissionMatrix.set(i, j, prob);
+			}
+		}
+		return transmissionMatrix;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the entropy of the model. To make it possible that the model
+	 * is stationary, a transition from {@link Event#ENDEVENT} to
+	 * {@link Event#STARTEVENT} is added.
+	 * </p>
+	 * 
+	 * @return entropy of the model or NaN if it could not be calculated
+	 */
+	public double calcEntropy() {
+		Matrix transmissionMatrix = getTransmissionMatrix();
+		List<Event<?>> knownSymbols = new ArrayList<Event<?>>(
+				trie.getKnownSymbols());
+		int numStates = knownSymbols.size();
+
+		List<Integer> startIndexList = new LinkedList<Integer>();
+		List<Integer> endIndexList = new LinkedList<Integer>();
+		for( int i=0 ; i<knownSymbols.size() ; i++ ) {
+			String id = knownSymbols.get(i).getStandardId();
+			if( id.equals(Event.STARTEVENT.getStandardId()) || id.contains(Event.STARTEVENT.getStandardId()+"-=-") ) {
+				startIndexList.add(i);
+			}
+			if( id.equals(Event.ENDEVENT.getStandardId()) || id.contains("-=-"+Event.ENDEVENT.getStandardId()) ) {
+				endIndexList.add(i);
+			}
+		}
+		
+		if (startIndexList.isEmpty()) {	
+			Console.printerrln("Error calculating entropy. Initial state of markov chain not found.");
+			return Double.NaN;
+		}
+		if (endIndexList.isEmpty()) {
+			Console.printerrln("Error calculating entropy. End state of markov chain not found.");
+			return Double.NaN;
+		}
+		for( Integer i : endIndexList ) {
+			for(Integer j : startIndexList ) {
+				transmissionMatrix.set(i, j, 1);
+			}
+		}
+
+		// Calculate stationary distribution by raising the power of the
+		// transmission matrix.
+		// The rank of the matrix should fall to 1 and each two should be the
+		// vector of the stationory distribution.
+		int iter = 0;
+		int rank = transmissionMatrix.rank();
+		Matrix stationaryMatrix = (Matrix) transmissionMatrix.clone();
+		while (iter < MAX_STATDIST_ITERATIONS && rank > 1) {
+			stationaryMatrix = stationaryMatrix.times(stationaryMatrix);
+			rank = stationaryMatrix.rank();
+			iter++;
+		}
+
+		if (rank != 1) {
+			Console.traceln("rank: " + rank);
+			Console.printerrln("Unable to calculate stationary distribution.");
+			return Double.NaN;
+		}
+
+		double entropy = 0.0;
+		for (int i = 0; i < numStates; i++) {
+			for (int j = 0; j < numStates; j++) {
+				if (transmissionMatrix.get(i, j) != 0 && transmissionMatrix.get(i, j)!=1) {
+					double tmp = stationaryMatrix.get(0, i);
+					tmp *= transmissionMatrix.get(i, j);
+					tmp *= Math.log(transmissionMatrix.get(i, j)) / Math.log(2);
+					entropy -= tmp;
+				}
+			}
+		}
+		return entropy;
+	}
+
+	/**
+	 * <p>
+	 * The dot represenation of {@link FirstOrderMarkovModel}s is its graph
+	 * representation with the states as nodes and directed edges weighted with
+	 * transition probabilities.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IDotCompatible#getDotRepresentation()
+	 */
+	@Override
+	public String getDotRepresentation() {
+		StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append("digraph model {" + StringTools.ENDLINE);
+
+		List<Event<?>> knownSymbols = new ArrayList<Event<?>>(
+				trie.getKnownSymbols());
+		for (Event<?> symbol : knownSymbols) {
+			final String thisSaneId = symbol.getShortId().replace("\"", "\\\"")
+					.replaceAll("[\r\n]", "");
+			stringBuilder.append(" " + knownSymbols.indexOf(symbol) + " [label=\""
+					+ thisSaneId + "\"];" + StringTools.ENDLINE);
+			List<Event<?>> context = new ArrayList<Event<?>>();
+			context.add(symbol);
+			Collection<Event<?>> followers = trie.getFollowingSymbols(context);
+			for (Event<?> follower : followers) {
+				stringBuilder.append(" " + knownSymbols.indexOf(symbol) + " -> "
+						+ knownSymbols.indexOf(follower) + " ");
+				stringBuilder.append("[label=\""
+						+ getProbability(context, follower) + "\"];"
+						+ StringTools.ENDLINE);
+			}
+		}
+		stringBuilder.append('}' + StringTools.ENDLINE);
+		return stringBuilder.toString();
+	}
+
+	/**
+	 * <p>
+	 * Returns a {@link Graph} representation of the model with the states as
+	 * nodes and directed edges weighted with transition probabilities.
+	 * </p>
+	 * 
+	 * @return {@link Graph} of the model
+	 */
+	public Graph<String, MarkovEdge> getGraph() {
+		Graph<String, MarkovEdge> graph = new SparseMultigraph<String, MarkovEdge>();
+
+		List<Event<?>> knownSymbols = new ArrayList<Event<?>>(
+				trie.getKnownSymbols());
+
+		for (Event<?> symbol : knownSymbols) {
+			String from = symbol.getShortId();
+			List<Event<?>> context = new ArrayList<Event<?>>();
+			context.add(symbol);
+
+			Collection<Event<?>> followers = trie.getFollowingSymbols(context);
+
+			for (Event<?> follower : followers) {
+				String to = follower.getShortId();
+				MarkovEdge prob = new MarkovEdge(getProbability(context,
+						follower));
+				graph.addEdge(prob, from, to, EdgeType.DIRECTED);
+			}
+		}
+		return graph;
+	}
+
+	/**
+	 * Inner class used for the {@link Graph} representation of the model.
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	static public class MarkovEdge {
+		/**
+		 * <p>
+		 * Weight of the edge, i.e., its transition probability.
+		 * </p>
+		 */
+		double weight;
+
+		/**
+		 * <p>
+		 * Constructor. Creates a new MarkovEdge.
+		 * </p>
+		 * 
+		 * @param weight
+		 *            weight of the edge, i.e., its transition probability
+		 */
+		MarkovEdge(double weight) {
+			this.weight = weight;
+		}
+
+		/**
+		 * <p>
+		 * The weight of the edge as {@link String}.
+		 * </p>
+		 */
+		public String toString() {
+			return "" + weight;
+		}
+	}
+
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModel.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModel.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/HighOrderMarkovModel.java	(revision 433)
@@ -0,0 +1,87 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+/**
+ * <p>
+ * Implements high-order Markov models.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class HighOrderMarkovModel extends TrieBasedModel {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new HighOrderMarkovModel with a defined Markov
+	 * order.
+	 * </p>
+	 * 
+	 * @param maxOrder
+	 *            Markov order of the model
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 */
+	public HighOrderMarkovModel(int maxOrder, Random r) {
+		super(maxOrder, r);
+	}
+
+	/**
+	 * <p>
+	 * Calculates the probability of the next Event being symbol based on the
+	 * order of the Markov model. The order is defined in the constructor
+	 * {@link #HighOrderMarkovModel(int, Random)}.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getProbability(java.util.List,
+	 *      de.ugoe.cs.quest.eventcore.Event)
+	 */
+	@Override
+	public double getProbability(List<? extends Event<?>> context,
+			Event<?> symbol) {
+		if (context == null) {
+			throw new InvalidParameterException("context must not be null");
+		}
+		if (symbol == null) {
+			throw new InvalidParameterException("symbol must not be null");
+		}
+		double result = 0.0d;
+
+		List<Event<?>> contextCopy;
+		if (context.size() >= trieOrder) {
+			contextCopy = new LinkedList<Event<?>>(context.subList(
+					context.size() - trieOrder + 1, context.size()));
+		} else {
+			contextCopy = new LinkedList<Event<?>>(context);
+		}
+
+		Collection<Event<?>> followers = trie.getFollowingSymbols(contextCopy);
+		int sumCountFollowers = 0; // N(s\sigma')
+		for (Event<?> follower : followers) {
+			sumCountFollowers += trie.getCount(contextCopy, follower);
+		}
+
+		int countSymbol = trie.getCount(contextCopy, symbol);
+		if (sumCountFollowers != 0) {
+			result = ((double) countSymbol / sumCountFollowers);
+		}
+
+		return result;
+	}
+
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IDotCompatible.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IDotCompatible.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IDotCompatible.java	(revision 433)
@@ -0,0 +1,22 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+/**
+ * <p>
+ * Models implementing this interface provide a graph representation of
+ * themselves as a {@link String} with Dot syntax.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IDotCompatible {
+
+	/**
+	 * <p>
+	 * Returns a Dot representation of the model.
+	 * </p>
+	 * 
+	 * @return string with Dot syntax that describes the model.
+	 */
+	public abstract String getDotRepresentation();
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IMemory.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IMemory.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IMemory.java	(revision 433)
@@ -0,0 +1,40 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.List;
+
+/**
+ * <p>
+ * This interface defines basic functions for classes that implement a memory
+ * about the recent events of a sequences.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ * @param <T>
+ *            Type of the sequence elements that are memorized.
+ */
+public interface IMemory<T> {
+
+	/**
+	 * Adds an element to the end of the memory.
+	 * 
+	 * @param element
+	 *            Element to be added.
+	 */
+	public void add(T element);
+
+	/**
+	 * <p>
+	 * Returns the last <code>num</code> memorized elements. If the history is
+	 * shorter than <code>num</code>, the length of the returned
+	 * {@link java.util.List} may be less than <code>num</code>.
+	 * </p>
+	 * 
+	 * @param num
+	 *            Number of states from the end of the memory to be returned.
+	 * @return {@link java.util.List} of memorized elements.
+	 */
+	public List<T> getLast(int num);
+
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IStochasticProcess.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IStochasticProcess.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IStochasticProcess.java	(revision 433)
@@ -0,0 +1,194 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.io.Serializable;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.List;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+/**
+ * <p>
+ * This interface defines the functionalities provided by stochastic processes.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public interface IStochasticProcess extends Serializable {
+
+	/**
+	 * <p>
+	 * Returns the probability, that the next event is {@code symbol} given the
+	 * last events are {@code context}. The last element of {@code context} is
+	 * the most recent in the history, the first element is the oldest.
+	 * </p>
+	 * 
+	 * @param context
+	 *            recently observed symbols
+	 * @param symbol
+	 *            event for which the probability is calculated
+	 * @return probabilty the {@code symbol} is the next event, given the last
+	 *         events {@code context}
+	 * @throws InvalidParameterException
+	 *             thrown if context or symbol is null
+	 */
+	double getProbability(List<? extends Event<?>> context, Event<?> symbol);
+
+	/**
+	 * <p>
+	 * Returns the probabilitiy that a given sequence is generated by the
+	 * stochastic process.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequences of which the probability is calculated
+	 * @return probability of the sequences; 1.0 if sequence is empty or null
+	 * @throws InvalidParameterException
+	 *             thrown if sequence is null
+	 */
+	double getProbability(List<? extends Event<?>> sequence);
+
+	/**
+	 * <p>
+	 * Generates a random sequence of events. The sequence starts with
+	 * {@link Event#STARTEVENT} and finishes with {@link Event#ENDEVENT}.
+	 * </p>
+	 * 
+	 * @return randomly generated sequence
+	 */
+	public List<? extends Event<?>> randomSequence();
+
+	/**
+	 * <p>
+	 * Generates a random sequence of events. The sequence starts with
+	 * {@link Event#STARTEVENT} and finishes with
+	 * <ul>
+	 * <li>{@link Event#ENDEVENT} if validEnd==true.</li>
+	 * <li>b) if a generated sequences reaches {@link Event#ENDEVENT} before
+	 * maxLength, the sequence finishes and is shorter than maxLenght.
+	 * Otherwise, the sequence finishes as soon as maxLength is reached and the
+	 * final event of the sequence must not be {@link Event#ENDEVENT}.</li>
+	 * </ul>
+	 * </p>
+	 * 
+	 * @param maxLength
+	 *            maximum length of the generated sequence
+	 * @param validEnd
+	 *            if true, only sequences that finish with
+	 *            {@link Event#ENDEVENT} are generated
+	 * @return randomly generated sequence
+	 * 
+	 */
+	public List<? extends Event<?>> randomSequence(int maxLength,
+			boolean validEnd);
+
+	/**
+	 * <p>
+	 * Generates all sequences of a given length are possible, i.e., have a
+	 * positive probability.<br>
+	 * All states are used as possible starting states.
+	 * </p>
+	 * 
+	 * @param length
+	 *            length of the generated sequences
+	 * @return generated sequences
+	 * @see #generateSequences(int, boolean)
+	 * @throws InvalidParameterException
+	 *             thrown if length is less than or equal to 0
+	 */
+	public Collection<List<? extends Event<?>>> generateSequences(int length);
+
+	/**
+	 * <p>
+	 * Generates all sequences of given length that can are possible, i.e., have
+	 * positive probability.<br>
+	 * If {@code fromStart==true}, all generated sequences start in
+	 * {@link Event#STARTEVENT}. Otherwise this method is the same as
+	 * {@link #generateSequences(int)}.
+	 * </p>
+	 * 
+	 * @param length
+	 *            length of the generated sequences
+	 * @param fromStart
+	 *            if true, all generated sequences start with
+	 *            {@link Event#STARTEVENT}
+	 * @return generated sequences
+	 * @throws InvalidParameterException
+	 *             thrown if length is less than or equal to 0
+	 */
+	public Collection<List<? extends Event<?>>> generateSequences(int length,
+			boolean fromStart);
+
+	/**
+	 * <p>
+	 * Generates all sequences starting with {@link Event#STARTEVENT} and
+	 * finishing with {@link Event#ENDEVENT} of a given length. It is possible
+	 * that no such sequence exists with the defined length and the returned set
+	 * is empty. If {@code length} is less than 2 the returned set is always
+	 * empty.
+	 * </p>
+	 * 
+	 * @param length
+	 * @return generated sequences
+	 * @throws InvalidParameterException
+	 *             thrown if length is less than or equal to 0
+	 */
+	public Collection<List<? extends Event<?>>> generateValidSequences(
+			int length);
+
+	/**
+	 * <p>
+	 * Returns the number of states known by the stochastic process, i.e., the
+	 * size of its alphabet.
+	 * </p>
+	 * 
+	 * @return number of states
+	 */
+	public int getNumSymbols();
+
+	/**
+	 * <p>
+	 * Returns a string representation of all known states.
+	 * </p>
+	 * 
+	 * @return string representation for all known states
+	 */
+	public String[] getSymbolStrings();
+
+	/**
+	 * <p>
+	 * Returns the number of states the process would have if it would be
+	 * flattened through state-splitting to a first-order Markov model.
+	 * </p>
+	 * <p>
+	 * If it is not possible to flatten the model, -1 is returned.
+	 * </p>
+	 * 
+	 * @return number of states an equivalent FOM would have; -1 if not
+	 *         available
+	 */
+	public int getNumFOMStates();
+
+	/**
+	 * <p>
+	 * Returns the number of transitions the process would have if it would be
+	 * flattened through state-splitting to a first-order Markov model.
+	 * </p>
+	 * 
+	 * @return number of transitions an equivalent FOM would have; -1 if not
+	 *         available
+	 */
+	public int getNumTransitions();
+
+	/**
+	 * <p>
+	 * Returns all states known by the stochastic process, i.e., its
+	 * {@link Event}s.
+	 * </p>
+	 * 
+	 * @return events known by the process
+	 */
+	public Collection<? extends Event<?>> getEvents();
+
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IncompleteMemory.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IncompleteMemory.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/IncompleteMemory.java	(revision 433)
@@ -0,0 +1,95 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * <p>
+ * Implements a round-trip buffered memory of a specified length that can be
+ * used to remember the recent history. Every event that happend longer ago than
+ * the length of the memory is forgotten, hence the memory is incomplete.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ * 
+ * @param <T>
+ *            Type which is memorized.
+ */
+public class IncompleteMemory<T> implements IMemory<T> {
+
+	/**
+	 * <p>
+	 * Maximum length of the memory.
+	 * </p>
+	 */
+	private int length;
+
+	/**
+	 * <p>
+	 * Internal storage of the history.
+	 * </p>
+	 */
+	private List<T> history;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new IncompleteMemory.
+	 * </p>
+	 * 
+	 * @param length
+	 *            number of recent events that are remembered
+	 * @throws InvalidParameterException
+	 *             This exception is thrown if the length is smaller than 1
+	 */
+	public IncompleteMemory(int length) {
+		if (length < 1) {
+			throw new InvalidParameterException(
+					"Length of IncompleteMemory must be at least 1.");
+		}
+		this.length = length;
+		history = new LinkedList<T>();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IMemory#add(java.lang.Object)
+	 */
+	@Override
+	public void add(T state) {
+		if (history.size() == length) {
+			history.remove(0);
+		}
+		history.add(state);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IMemory#getLast(int)
+	 */
+	@Override
+	public List<T> getLast(int num) {
+		if( num<1 ) {
+			return new LinkedList<T>();
+		} else {
+		return new LinkedList<T>(history.subList(
+				Math.max(0, history.size() - num),
+				history.size())); // defensive copy
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the current length of the memory. This can be less than
+	 * {@link #length}, if the overall history is less than {@link #length}.
+	 * </p>
+	 * 
+	 * @return length of the current memory
+	 */
+	public int getLength() {
+		return history.size();
+	}
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/ModelFlattener.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/ModelFlattener.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/ModelFlattener.java	(revision 433)
@@ -0,0 +1,137 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+
+/**
+ * <p>
+ * This class provides functions to create flattened first-order Markov models
+ * from {@link HighOrderMarkovModel}s and {@link PredictionByPartialMatch}
+ * models through state splitting.
+ * </p>
+ * <p>
+ * If possible, the normal high-order markov model should be used, as the Events
+ * may be broken by the flattener, as, e.g., the information
+ * {@link ReplayableEvent}s contain is not preserved.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public class ModelFlattener {
+
+	private static final String EVENT_SEPARATOR = "-=-";
+
+	Trie<Event<?>> firstOrderTrie;
+
+	/**
+	 * <p>
+	 * Takes a {@link HighOrderMarkovModel} and returns a
+	 * {@link FirstOrderMarkovModel} that conserves the high-order memory
+	 * through state splitting.
+	 * </p>
+	 * 
+	 * @param model
+	 *            model that is flattened
+	 * @return flattened first-order Markov model
+	 */
+	public FirstOrderMarkovModel flattenHighOrderMarkovModel(
+			HighOrderMarkovModel model) {
+		int markovOrder = model.trieOrder - 1;
+		FirstOrderMarkovModel firstOrderModel = new FirstOrderMarkovModel(
+				new Random());
+		firstOrderModel.trieOrder = 2;
+		if (markovOrder == 1) {
+			firstOrderModel.trie = new Trie<Event<?>>(model.trie);
+			firstOrderModel.trieOrder = 2;
+		} else {
+			firstOrderTrie = new Trie<Event<?>>();
+			TrieNode<Event<?>> rootNode = model.trie.find(null);
+			generateFirstOrderTrie(rootNode, new LinkedList<String>(), markovOrder);
+			firstOrderTrie.updateKnownSymbols();
+			firstOrderModel.trie = firstOrderTrie;
+		}
+
+		return firstOrderModel;
+	}
+
+	/**
+	 * <p>
+	 * <b>This method is not available yet and always return null!</b>
+	 * </p>
+	 * <p>
+	 * Takes a {@link PredictionByPartialMatch} model and returns a
+	 * {@link FirstOrderMarkovModel} that conserves the high-order memory
+	 * through state splitting.
+	 * </p>
+	 * 
+	 * @param model
+	 *            model that is flattened
+	 * @return flattened first-order Markov model
+	 */
+	public FirstOrderMarkovModel flattenPredictionByPartialMatch(
+			PredictionByPartialMatch model) {
+		// TODO implement method
+		return null;
+	}
+
+	/**
+	 * <p>
+	 * Converts all nodes of the given depth into first-order node through
+	 * state-splitting. For each node at the given depth a new node is created
+	 * and appropriate transitions will be added.
+	 * </p>
+	 * <p>
+	 * This method traverses through the tree recursively. If the recursion
+	 * reaches the desired depth in the tree, node are added.
+	 * </p>
+	 * 
+	 * @param currentNode
+	 *            node whose sub-trie is currently traversed
+	 * @param parentIDs
+	 *            ID strings of the ancestors of the currentNode
+	 * @param depth
+	 *            depth to go - NOT the current depth.
+	 */
+	private void generateFirstOrderTrie(TrieNode<Event<?>> currentNode,
+			List<String> parentIDs, int depth) {
+		for (TrieNode<Event<?>> child : currentNode.getChildren()) {
+			String currentId = child.getSymbol().getStandardId();
+			if (depth > 1) {
+				List<String> childParentIDs = new LinkedList<String>(parentIDs);
+				childParentIDs.add(currentId);
+				generateFirstOrderTrie(child, childParentIDs, depth - 1);
+
+			} else {
+				StringBuilder firstOrderID = new StringBuilder();
+				for (String parentID : parentIDs) {
+					firstOrderID.append(parentID + EVENT_SEPARATOR);
+				}
+				firstOrderID.append(currentId);
+				TrieNode<Event<?>> firstOrderNode = firstOrderTrie
+						.getChildCreate(new Event<Object>(firstOrderID
+								.toString()));
+				firstOrderNode.setCount(child.getCount());
+				for (TrieNode<Event<?>> transitionChild : child.getChildren()) {
+					StringBuilder transitionID = new StringBuilder();
+					for (String parentID : parentIDs.subList(1,
+							parentIDs.size())) {
+						transitionID.append(parentID + EVENT_SEPARATOR);
+					}
+					transitionID.append(currentId + EVENT_SEPARATOR);
+					transitionID.append(transitionChild.getSymbol()
+							.getStandardId());
+					TrieNode<Event<?>> firstOrderTransitionChild = firstOrderNode
+							.getChildCreate(new Event<Object>(transitionID
+									.toString()));
+					firstOrderTransitionChild.setCount(transitionChild
+							.getCount());
+				}
+			}
+		}
+	}
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatch.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatch.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/PredictionByPartialMatch.java	(revision 433)
@@ -0,0 +1,200 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+import de.ugoe.cs.quest.eventcore.Event;
+
+/**
+ * <p>
+ * Implements Prediction by Partial Match (PPM) based on the following formula
+ * (LaTeX-style notation):<br>
+ * P_{PPM}(X_n|X_{n-1},...,X_{n-k}) = \sum_{i=k}^min escape^{k-i} P_{MM^i}(X_n
+ * |X_{n-1},...,X_{n-i})(1-escape)+escape^(k-min)P(X_n|X_{n-i},... ,X_{n-min})<br>
+ * P_{MM^i} denotes the probability in an i-th order Markov model.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * 
+ */
+public class PredictionByPartialMatch extends TrieBasedModel {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Minimum order of the Markov model.
+	 * </p>
+	 */
+	protected int minOrder;
+
+	/**
+	 * <p>
+	 * Probability to use a lower-order Markov model
+	 * </p>
+	 */
+	protected double probEscape;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new PredictionByPartialMatch model with a given
+	 * Markov order and a default escape probability of 0.1.
+	 * </p>
+	 * 
+	 * @param markovOrder
+	 *            Markov order of the model
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 */
+	public PredictionByPartialMatch(int markovOrder, Random r) {
+		this(markovOrder, r, 0.1);
+	}
+
+	/**
+	 * <p>
+	 * Creates a new PredictionByPartialMatch model with a given Markov order
+	 * and escape probability.
+	 * </p>
+	 * 
+	 * @param markovOrder
+	 *            Markov order of the model
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 * @param probEscape
+	 *            escape probability used by the model
+	 */
+	public PredictionByPartialMatch(int markovOrder, Random r, double probEscape) {
+		this(markovOrder, 0, r, probEscape);
+	}
+
+	/**
+	 * <p>
+	 * Creates a new PredictionByPartialMatch model with a given Markov order
+	 * and escape probability.
+	 * </p>
+	 * 
+	 * @param markovOrder
+	 *            Markov order of the model
+	 * @param minOrder
+	 *            minimum order of the model; if this order is reached, there is
+	 *            no escape
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 * @param probEscape
+	 *            escape probability used by the model
+	 * @throws InvalidParameterException thrown if minOrder is less than 0 or greater than markovOrder or probEscape is not in the interval (0,1)
+	 */
+	public PredictionByPartialMatch(int markovOrder, int minOrder, Random r,
+			double probEscape) {
+		super(markovOrder, r);
+		if( minOrder< 0 ) {
+			throw new InvalidParameterException("minOrder must be greather than or equal to 0");
+		}
+		if( minOrder>markovOrder) {
+			throw new InvalidParameterException("minOrder must be less than or equal to markovOrder");
+		}
+		if( probEscape<=0.0 || probEscape>=1.0) {
+			throw new InvalidParameterException("probEscape must be in the interval (0,1)");
+		}
+		this.probEscape = probEscape;
+		this.minOrder = minOrder;
+	}
+
+	/**
+	 * <p>
+	 * Sets the escape probability of the model.
+	 * </p>
+	 * 
+	 * @param probEscape
+	 *            new escape probability
+	 */
+	public void setProbEscape(double probEscape) {
+		this.probEscape = probEscape;
+	}
+
+	/**
+	 * <p>
+	 * Returns the escape probability of the model.
+	 * </p>
+	 * 
+	 * @return escape probability of the model
+	 */
+	public double getProbEscape() {
+		return probEscape;
+	}
+
+	/**
+	 * <p>
+	 * Calculates the probability of the next event based on the formula:<br>
+	 * P_{PPM}(X_n|X_{n-1},...,X_{n-k}) = \sum_{i=k}^min escape^{k-i}
+	 * P_{MM^i}(X_n
+	 * |X_{n-1},...,X_{n-i})(1-escape)+escape^(k-min)P(X_n|X_{n-i},...
+	 * ,X_{n-min})<br>
+	 * P_{MM^i} denotes the probability in an i-th order Markov model.
+	 * </p>
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getProbability(java.util.List,
+	 *      de.ugoe.cs.quest.eventcore.Event)
+	 */
+	@Override
+	public double getProbability(List<? extends Event<?>> context,
+			Event<?> symbol) {
+		if (context == null) {
+			throw new InvalidParameterException("context must not be null");
+		}
+		if (symbol == null) {
+			throw new InvalidParameterException("symbol must not be null");
+		}
+		double result = 0.0d;
+		double resultCurrentContex = 0.0d;
+		double resultShorterContex = 0.0d;
+
+		List<Event<?>> contextCopy;
+		if (context.size() >= trieOrder) {
+			contextCopy = new LinkedList<Event<?>>(context.subList(
+					context.size() - trieOrder + 1, context.size()));
+		} else {
+			contextCopy = new LinkedList<Event<?>>(context);
+		}
+
+		Collection<Event<?>> followers = trie.getFollowingSymbols(contextCopy); // \Sigma'
+		int sumCountFollowers = 0; // N(s\sigma')
+		for (Event<?> follower : followers) {
+			sumCountFollowers += trie.getCount(contextCopy, follower);
+		}
+
+		int countSymbol = trie.getCount(contextCopy, symbol); // N(s\sigma)
+		if (sumCountFollowers == 0) {
+			resultCurrentContex = 0.0;
+		} else {
+			resultCurrentContex = (double) countSymbol / sumCountFollowers;
+		}
+		if (contextCopy.size() > minOrder) {
+			resultCurrentContex *= (1 - probEscape);
+			contextCopy.remove(0);
+			if (contextCopy.size() >= minOrder) {
+				double probSuffix = getProbability(contextCopy, symbol);
+
+				if (followers.size() == 0) {
+					resultShorterContex = probSuffix;
+				} else {
+					resultShorterContex = probEscape * probSuffix;
+				}
+			}
+		}
+		result = resultCurrentContex + resultShorterContex;
+
+		return result;
+	}
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/Trie.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/Trie.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/Trie.java	(revision 433)
@@ -0,0 +1,472 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.io.Serializable;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.util.StringTools;
+
+import edu.uci.ics.jung.graph.DelegateTree;
+import edu.uci.ics.jung.graph.Graph;
+import edu.uci.ics.jung.graph.Tree;
+
+/**
+ * <p>
+ * This class implements a <it>trie</it>, i.e., a tree of sequences that the
+ * occurence of subsequences up to a predefined length. This length is the trie
+ * order.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * 
+ * @param <T>
+ *            Type of the symbols that are stored in the trie.
+ * 
+ * @see TrieNode
+ */
+public class Trie<T> implements IDotCompatible, Serializable {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Collection of all symbols occuring in the trie.
+	 * </p>
+	 */
+	private Collection<T> knownSymbols;
+
+	/**
+	 * <p>
+	 * Reference to the root of the trie.
+	 * </p>
+	 */
+	private final TrieNode<T> rootNode;
+
+	/**
+	 * <p>
+	 * Contructor. Creates a new Trie.
+	 * </p>
+	 */
+	public Trie() {
+		rootNode = new TrieNode<T>();
+		knownSymbols = new LinkedHashSet<T>();
+	}
+
+	/**
+	 * <p>
+	 * Copy-Constructor. Creates a new Trie as the copy of other. The other trie
+	 * must noch be null.
+	 * </p>
+	 * 
+	 * @param other
+	 *            Trie that is copied
+	 */
+	public Trie(Trie<T> other) {
+		if (other == null) {
+			throw new InvalidParameterException("other trie must not be null");
+		}
+		rootNode = new TrieNode<T>(other.rootNode);
+		knownSymbols = new LinkedHashSet<T>(other.knownSymbols);
+	}
+
+	/**
+	 * <p>
+	 * Returns a collection of all symbols occuring in the trie.
+	 * </p>
+	 * 
+	 * @return symbols occuring in the trie
+	 */
+	public Collection<T> getKnownSymbols() {
+		return new LinkedHashSet<T>(knownSymbols);
+	}
+
+	/**
+	 * <p>
+	 * Trains the current trie using the given sequence and adds all subsequence
+	 * of length {@code maxOrder}.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence whose subsequences are added to the trie
+	 * @param maxOrder
+	 *            maximum length of the subsequences added to the trie
+	 */
+	public void train(List<T> sequence, int maxOrder) {
+		if (maxOrder < 1) {
+			return;
+		}
+		IncompleteMemory<T> latestActions = new IncompleteMemory<T>(maxOrder);
+		int i = 0;
+		for (T currentEvent : sequence) {
+			latestActions.add(currentEvent);
+			knownSymbols.add(currentEvent);
+			i++;
+			if (i >= maxOrder) {
+				add(latestActions.getLast(maxOrder));
+			}
+		}
+		int sequenceLength = sequence.size();
+		for (int j = maxOrder - 1; j > 0; j--) {
+			add(sequence.subList(sequenceLength - j, sequenceLength));
+		}
+	}
+
+	/**
+	 * <p>
+	 * Adds a given subsequence to the trie and increases the counters
+	 * accordingly.
+	 * </p>
+	 * 
+	 * @param subsequence
+	 *            subsequence whose counters are increased
+	 * @see TrieNode#add(List)
+	 */
+	protected void add(List<T> subsequence) {
+		if (subsequence != null && !subsequence.isEmpty()) {
+			knownSymbols.addAll(subsequence);
+			subsequence = new LinkedList<T>(subsequence); // defensive copy!
+			T firstSymbol = subsequence.get(0);
+			TrieNode<T> node = getChildCreate(firstSymbol);
+			node.add(subsequence);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the child of the root node associated with the given symbol or
+	 * creates it if it does not exist yet.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol whose node is required
+	 * @return node associated with the symbol
+	 * @see TrieNode#getChildCreate(Object)
+	 */
+	protected TrieNode<T> getChildCreate(T symbol) {
+		return rootNode.getChildCreate(symbol);
+	}
+
+	/**
+	 * <p>
+	 * Returns the child of the root node associated with the given symbol or
+	 * null if it does not exist.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol whose node is required
+	 * @return node associated with the symbol; null if no such node exists
+	 * @see TrieNode#getChild(Object)
+	 */
+	protected TrieNode<T> getChild(T symbol) {
+		return rootNode.getChild(symbol);
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of occurences of the given sequence.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence whose number of occurences is required
+	 * @return number of occurences of the sequence
+	 */
+	public int getCount(List<T> sequence) {
+		int count = 0;
+		TrieNode<T> node = find(sequence);
+		if (node != null) {
+			count = node.getCount();
+		}
+		return count;
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of occurences of the given prefix and a symbol that
+	 * follows it.<br>
+	 * Convenience function to simplify usage of {@link #getCount(List)}.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            prefix of the sequence
+	 * @param follower
+	 *            suffix of the sequence
+	 * @return number of occurences of the sequence
+	 * @see #getCount(List)
+	 */
+	public int getCount(List<T> sequence, T follower) {
+		List<T> tmpSequence = new LinkedList<T>(sequence);
+		tmpSequence.add(follower);
+		return getCount(tmpSequence);
+
+	}
+
+	/**
+	 * <p>
+	 * Searches the trie for a given sequence and returns the node associated
+	 * with the sequence or null if no such node is found.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence that is searched for
+	 * @return node associated with the sequence
+	 * @see TrieNode#find(List)
+	 */
+	public TrieNode<T> find(List<T> sequence) {
+		if (sequence == null || sequence.isEmpty()) {
+			return rootNode;
+		}
+		List<T> sequenceCopy = new LinkedList<T>(sequence);
+		TrieNode<T> result = null;
+		TrieNode<T> node = getChild(sequenceCopy.get(0));
+		if (node != null) {
+			sequenceCopy.remove(0);
+			result = node.find(sequenceCopy);
+		}
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Returns a collection of all symbols that follow a given sequence in the
+	 * trie. In case the sequence is not found or no symbols follow the sequence
+	 * the result will be empty.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence whose followers are returned
+	 * @return symbols following the given sequence
+	 * @see TrieNode#getFollowingSymbols()
+	 */
+	public Collection<T> getFollowingSymbols(List<T> sequence) {
+		Collection<T> result = new LinkedList<T>();
+		TrieNode<T> node = find(sequence);
+		if (node != null) {
+			result = node.getFollowingSymbols();
+		}
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Returns the longest suffix of the given context that is contained in the
+	 * tree and whose children are leaves.
+	 * </p>
+	 * 
+	 * @param context
+	 *            context whose suffix is searched for
+	 * @return longest suffix of the context
+	 */
+	public List<T> getContextSuffix(List<T> context) {
+		List<T> contextSuffix;
+		if (context != null) {
+			contextSuffix = new LinkedList<T>(context); // defensive copy
+		} else {
+			contextSuffix = new LinkedList<T>();
+		}
+		boolean suffixFound = false;
+
+		while (!suffixFound) {
+			if (contextSuffix.isEmpty()) {
+				suffixFound = true; // suffix is the empty word
+			} else {
+				TrieNode<T> node = find(contextSuffix);
+				if (node != null) {
+					if (!node.getFollowingSymbols().isEmpty()) {
+						suffixFound = true;
+					}
+				}
+				if (!suffixFound) {
+					contextSuffix.remove(0);
+				}
+			}
+		}
+
+		return contextSuffix;
+	}
+
+	/**
+	 * <p>
+	 * Helper class for graph visualization of a trie.
+	 * </p>
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	static public class Edge {
+	}
+
+	/**
+	 * <p>
+	 * Helper class for graph visualization of a trie.
+	 * </p>
+	 * 
+	 * @author Steffen Herbold
+	 * @version 1.0
+	 */
+	static public class TrieVertex {
+
+		/**
+		 * <p>
+		 * Id of the vertex.
+		 * </p>
+		 */
+		private String id;
+
+		/**
+		 * <p>
+		 * Contructor. Creates a new TrieVertex.
+		 * </p>
+		 * 
+		 * @param id
+		 *            id of the vertex
+		 */
+		protected TrieVertex(String id) {
+			this.id = id;
+		}
+
+		/**
+		 * <p>
+		 * Returns the id of the vertex.
+		 * </p>
+		 * 
+		 * @see java.lang.Object#toString()
+		 */
+		@Override
+		public String toString() {
+			return id;
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns a {@link Graph} representation of the trie.
+	 * </p>
+	 * 
+	 * @return {@link Graph} representation of the trie
+	 */
+	protected Tree<TrieVertex, Edge> getGraph() {
+		DelegateTree<TrieVertex, Edge> graph = new DelegateTree<TrieVertex, Edge>();
+		rootNode.getGraph(null, graph);
+		return graph;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IDotCompatible#getDotRepresentation()
+	 */
+	public String getDotRepresentation() {
+		StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append("digraph model {" + StringTools.ENDLINE);
+		rootNode.appendDotRepresentation(stringBuilder);
+		stringBuilder.append('}' + StringTools.ENDLINE);
+		return stringBuilder.toString();
+	}
+
+	/**
+	 * <p>
+	 * Returns the string representation of the root node.
+	 * </p>
+	 * 
+	 * @see TrieNode#toString()
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return rootNode.toString();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of symbols contained in the trie.
+	 * </p>
+	 * 
+	 * @return number of symbols contained in the trie
+	 */
+	public int getNumSymbols() {
+		return knownSymbols.size();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of trie nodes that are ancestors of a leaf. This is
+	 * the equivalent to the number of states a first-order markov model would
+	 * have.
+	 * <p>
+	 * 
+	 * @return number of trie nodes that are ancestors of leafs.
+	 */
+	public int getNumLeafAncestors() {
+		List<TrieNode<T>> ancestors = new LinkedList<TrieNode<T>>();
+		rootNode.getLeafAncestors(ancestors);
+		return ancestors.size();
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of trie nodes that are leafs.
+	 * </p>
+	 * 
+	 * @return number of leafs in the trie
+	 */
+	public int getNumLeafs() {
+		return rootNode.getNumLeafs();
+	}
+
+	/**
+	 * <p>
+	 * Updates the list of known symbols by replacing it with all symbols that
+	 * are found in the child nodes of the root node. This should be the same as
+	 * all symbols that are contained in the trie.
+	 * </p>
+	 */
+	public void updateKnownSymbols() {
+		knownSymbols = new HashSet<T>();
+		for (TrieNode<T> node : rootNode.getChildren()) {
+			knownSymbols.add(node.getSymbol());
+		}
+	}
+
+	/**
+	 * <p>
+	 * Two Tries are defined as equal, if their {@link #rootNode} are equal.
+	 * </p>
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@SuppressWarnings("rawtypes")
+	@Override
+	public boolean equals(Object other) {
+		if (other == this) {
+			return true;
+		}
+		if (other instanceof Trie) {
+			return rootNode.equals(((Trie) other).rootNode);
+		}
+		return false;
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		int multiplier = 17;
+		int hash = 42;
+		if (rootNode != null) {
+			hash = multiplier * hash + rootNode.hashCode();
+		}
+		return hash;
+	}
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/TrieBasedModel.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/TrieBasedModel.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/TrieBasedModel.java	(revision 433)
@@ -0,0 +1,416 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.Trie.Edge;
+import de.ugoe.cs.quest.usageprofiles.Trie.TrieVertex;
+import edu.uci.ics.jung.graph.Tree;
+
+/**
+ * <p>
+ * Implements a skeleton for stochastic processes that can calculate
+ * probabilities based on a trie. The skeleton provides all functionalities of
+ * {@link IStochasticProcess} except
+ * {@link IStochasticProcess#getProbability(List, Event)}.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * @version 1.0
+ */
+public abstract class TrieBasedModel implements IStochasticProcess {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * The order of the trie, i.e., the maximum length of subsequences stored in
+	 * the trie.
+	 * </p>
+	 */
+	protected int trieOrder;
+
+	/**
+	 * <p>
+	 * Trie on which the probability calculations are based.
+	 * </p>
+	 */
+	protected Trie<Event<?>> trie = null;
+
+	/**
+	 * <p>
+	 * Random number generator used by probabilistic sequence generation
+	 * methods.
+	 * </p>
+	 */
+	protected final Random r;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new TrieBasedModel that can be used for stochastic
+	 * processes with a Markov order less than or equal to {@code markovOrder}.
+	 * </p>
+	 * 
+	 * @param markovOrder
+	 *            Markov order of the model
+	 * @param r
+	 *            random number generator used by probabilistic methods of the
+	 *            class
+	 * @throws InvalidParameterException
+	 *             thrown if markovOrder is less than 0 or the random number
+	 *             generator r is null
+	 */
+	public TrieBasedModel(int markovOrder, Random r) {
+		super();
+		if (markovOrder < 0) {
+			throw new InvalidParameterException(
+					"markov order must not be less than 0");
+		}
+		if (r == null) {
+			throw new InvalidParameterException(
+					"random number generator r must not be null");
+		}
+		this.trieOrder = markovOrder + 1;
+		this.r = r;
+	}
+
+	/**
+	 * <p>
+	 * Trains the model by generating a trie from which probabilities are
+	 * calculated. The trie is newly generated based solely on the passed
+	 * sequences. If an existing model should only be updated, use
+	 * {@link #update(Collection)} instead.
+	 * </p>
+	 * 
+	 * @param sequences
+	 *            training data
+	 * @throws InvalidParameterException
+	 *             thrown is sequences is null
+	 */
+	public void train(Collection<List<? extends Event<?>>> sequences) {
+		trie = null;
+		update(sequences);
+	}
+
+	/**
+	 * <p>
+	 * Trains the model by updating the trie from which the probabilities are
+	 * calculated. This function updates an existing trie. In case no trie
+	 * exists yet, a new trie is generated and the function behaves like
+	 * {@link #train(Collection)}.
+	 * </p>
+	 * 
+	 * @param sequences
+	 *            training data
+	 * @throws InvalidParameterException
+	 *             thrown is sequences is null
+	 */
+	public void update(Collection<List<? extends Event<?>>> sequences) {
+		if (sequences == null) {
+			throw new InvalidParameterException("sequences must not be null");
+		}
+		if (trie == null) {
+			trie = new Trie<Event<?>>();
+		}
+		for (List<? extends Event<?>> sequence : sequences) {
+			List<Event<?>> currentSequence = new LinkedList<Event<?>>(sequence); // defensive
+																					// copy
+			currentSequence.add(0, Event.STARTEVENT);
+			currentSequence.add(Event.ENDEVENT);
+
+			trie.train(currentSequence, trieOrder);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#randomSequence()
+	 */
+	@Override
+	public List<? extends Event<?>> randomSequence() {
+		return randomSequence(Integer.MAX_VALUE, true);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#randomSequence()
+	 */
+	@Override
+	public List<? extends Event<?>> randomSequence(int maxLength,
+			boolean validEnd) {
+		List<Event<?>> sequence = new LinkedList<Event<?>>();
+		if (trie != null) {
+			boolean endFound = false;
+			while (!endFound) { // outer loop for length checking
+				sequence = new LinkedList<Event<?>>();
+				IncompleteMemory<Event<?>> context = new IncompleteMemory<Event<?>>(
+						trieOrder - 1);
+				context.add(Event.STARTEVENT);
+
+				while (!endFound && sequence.size() <= maxLength) {
+					double randVal = r.nextDouble();
+					double probSum = 0.0;
+					List<Event<?>> currentContext = context.getLast(trieOrder);
+					for (Event<?> symbol : trie.getKnownSymbols()) {
+						probSum += getProbability(currentContext, symbol);
+						if (probSum >= randVal) {
+							if (!(Event.STARTEVENT.equals(symbol) || Event.ENDEVENT
+									.equals(symbol))) {
+								// only add the symbol the sequence if it is not
+								// START or END
+								context.add(symbol);
+								sequence.add(symbol);
+							}
+							endFound = (Event.ENDEVENT.equals(symbol))
+									|| (!validEnd && sequence.size() == maxLength);
+							break;
+						}
+					}
+				}
+			}
+		}
+		return sequence;
+	}
+
+	/**
+	 * <p>
+	 * Returns a Dot representation of the internal trie.
+	 * </p>
+	 * 
+	 * @return dot representation of the internal trie
+	 */
+	public String getTrieDotRepresentation() {
+		if (trie == null) {
+			return "";
+		} else {
+			return trie.getDotRepresentation();
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns a {@link Tree} of the internal trie that can be used for
+	 * visualization.
+	 * </p>
+	 * 
+	 * @return {@link Tree} depicting the internal trie
+	 */
+	public Tree<TrieVertex, Edge> getTrieGraph() {
+		if (trie == null) {
+			return null;
+		} else {
+			return trie.getGraph();
+		}
+	}
+
+	/**
+	 * <p>
+	 * The string representation of the model is {@link Trie#toString()} of
+	 * {@link #trie}.
+	 * </p>
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		if (trie == null) {
+			return "";
+		} else {
+			return trie.toString();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getNumStates()
+	 */
+	@Override
+	public int getNumSymbols() {
+		if (trie == null) {
+			return 0;
+		} else {
+			return trie.getNumSymbols();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getStateStrings()
+	 */
+	@Override
+	public String[] getSymbolStrings() {
+		if (trie == null) {
+			return new String[0];
+		}
+		String[] stateStrings = new String[getNumSymbols()];
+		int i = 0;
+		for (Event<?> symbol : trie.getKnownSymbols()) {
+			if (symbol.toString() == null) {
+				stateStrings[i] = "null";
+			} else {
+				stateStrings[i] = symbol.toString();
+			}
+			i++;
+		}
+		return stateStrings;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getEvents()
+	 */
+	@Override
+	public Collection<? extends Event<?>> getEvents() {
+		if (trie == null) {
+			return new HashSet<Event<?>>();
+		} else {
+			return trie.getKnownSymbols();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.usageprofiles.IStochasticProcess#generateSequences(int)
+	 */
+	@Override
+	public Collection<List<? extends Event<?>>> generateSequences(int length) {
+		return generateSequences(length, false);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.usageprofiles.IStochasticProcess#generateSequences(int,
+	 * boolean)
+	 */
+	@Override
+	public Set<List<? extends Event<?>>> generateSequences(int length,
+			boolean fromStart) {
+		Set<List<? extends Event<?>>> sequenceSet = new LinkedHashSet<List<? extends Event<?>>>();
+		if (length < 1) {
+			throw new InvalidParameterException(
+					"Length of generated subsequences must be at least 1.");
+		}
+		if (length == 1) {
+			if (fromStart) {
+				List<Event<?>> subSeq = new LinkedList<Event<?>>();
+				subSeq.add(Event.STARTEVENT);
+				sequenceSet.add(subSeq);
+			} else {
+				for (Event<?> event : getEvents()) {
+					List<Event<?>> subSeq = new LinkedList<Event<?>>();
+					subSeq.add(event);
+					sequenceSet.add(subSeq);
+				}
+			}
+			return sequenceSet;
+		}
+		Collection<? extends Event<?>> events = getEvents();
+		Collection<List<? extends Event<?>>> seqsShorter = generateSequences(
+				length - 1, fromStart);
+		for (Event<?> event : events) {
+			for (List<? extends Event<?>> seqShorter : seqsShorter) {
+				Event<?> lastEvent = event;
+				if (getProbability(seqShorter, lastEvent) > 0.0) {
+					List<Event<?>> subSeq = new ArrayList<Event<?>>(seqShorter);
+					subSeq.add(lastEvent);
+					sequenceSet.add(subSeq);
+				}
+			}
+		}
+		return sequenceSet;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.usageprofiles.IStochasticProcess#generateValidSequences
+	 * (int)
+	 */
+	@Override
+	public Collection<List<? extends Event<?>>> generateValidSequences(
+			int length) {
+		// check for min-length implicitly done by generateSequences
+		Collection<List<? extends Event<?>>> allSequences = generateSequences(
+				length, true);
+		Collection<List<? extends Event<?>>> validSequences = new LinkedHashSet<List<? extends Event<?>>>();
+		for (List<? extends Event<?>> sequence : allSequences) {
+			if (sequence.size() == length
+					&& Event.ENDEVENT.equals(sequence.get(sequence.size() - 1))) {
+				validSequences.add(sequence);
+			}
+		}
+		return validSequences;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getProbability(java.util
+	 * .List)
+	 */
+	@Override
+	public double getProbability(List<? extends Event<?>> sequence) {
+		if (sequence == null) {
+			throw new InvalidParameterException("sequence must not be null");
+		}
+		double prob = 1.0;
+		List<Event<?>> context = new LinkedList<Event<?>>();
+		for (Event<?> event : sequence) {
+			prob *= getProbability(context, event);
+			context.add(event);
+		}
+		return prob;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getNumFOMStates()
+	 */
+	@Override
+	public int getNumFOMStates() {
+		if (trie == null) {
+			return 0;
+		} else {
+			return trie.getNumLeafAncestors();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see de.ugoe.cs.quest.usageprofiles.IStochasticProcess#getNumTransitions()
+	 */
+	@Override
+	public int getNumTransitions() {
+		if (trie == null) {
+			return 0;
+		} else {
+			return trie.getNumLeafs();
+		}
+	}
+}
Index: /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/TrieNode.java
===================================================================
--- /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/TrieNode.java	(revision 433)
+++ /trunk/quest-core-events/src/de/ugoe/cs/quest/usageprofiles/TrieNode.java	(revision 433)
@@ -0,0 +1,443 @@
+package de.ugoe.cs.quest.usageprofiles;
+
+import java.io.Serializable;
+import java.security.InvalidParameterException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.ugoe.cs.quest.usageprofiles.Trie.Edge;
+import de.ugoe.cs.quest.usageprofiles.Trie.TrieVertex;
+import de.ugoe.cs.util.StringTools;
+import edu.uci.ics.jung.graph.DelegateTree;
+import edu.uci.ics.jung.graph.Tree;
+
+/**
+ * <p>
+ * This class implements a node of a trie. Each node is associated with a symbol
+ * and has a counter. The counter marks the number of occurences of the sequence
+ * defined by the path from the root of the trie to this node.
+ * </p>
+ * 
+ * @author Steffen Herbold
+ * 
+ * @param <T>
+ *            Type of the symbols that are stored in the trie.
+ * @see Trie
+ */
+class TrieNode<T> implements Serializable {
+
+	/**
+	 * <p>
+	 * Id for object serialization.
+	 * </p>
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * <p>
+	 * Counter for the number of occurences of the sequence.
+	 * </p>
+	 */
+	private int count;
+
+	/**
+	 * <p>
+	 * Symbol associated with the node.
+	 * </p>
+	 */
+	private final T symbol;
+
+	/**
+	 * <p>
+	 * Child nodes of this node. If the node is a leaf this collection is empty.
+	 * </p>
+	 */
+	private Collection<TrieNode<T>> children;
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new TrieNode without a symbol associated.<br>
+	 * <b>This constructor should only be used to create the root node of the
+	 * trie!</b>
+	 * </p>
+	 */
+	TrieNode() {
+		this.symbol = null;
+		count = 0;
+		children = new LinkedList<TrieNode<T>>();
+	}
+
+	/**
+	 * <p>
+	 * Constructor. Creates a new TrieNode. The symbol must not be null.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol associated with the trie node
+	 */
+	TrieNode(T symbol) {
+		if (symbol == null) {
+			throw new InvalidParameterException(
+					"symbol must not be null. null is reserved for root node!");
+		}
+		this.symbol = symbol;
+		count = 0;
+		children = new LinkedList<TrieNode<T>>();
+	}
+
+	/**
+	 * <p>
+	 * Copy-Constructor. Creates a new TrieNode as copy of other. Other must not
+	 * be null.
+	 * </p>
+	 * 
+	 * @param other
+	 */
+	TrieNode(TrieNode<T> other) {
+		if (other == null) {
+			throw new InvalidParameterException("other must not be null");
+		}
+		symbol = other.symbol;
+		count = other.count;
+		children = new LinkedList<TrieNode<T>>();
+		for (TrieNode<T> child : other.children) {
+			children.add(new TrieNode<T>(child));
+		}
+	}
+
+	/**
+	 * <p>
+	 * Adds a given subsequence to the trie and increases the counters
+	 * accordingly.
+	 * </p>
+	 * 
+	 * @param subsequence
+	 *            subsequence whose counters are increased
+	 * @see Trie#add(List)
+	 */
+	public void add(List<T> subsequence) {
+		if (!subsequence.isEmpty()) {
+			if (!symbol.equals(subsequence.get(0))) { // should be guaranteed by
+														// the
+														// recursion/TrieRoot!
+				throw new AssertionError("Invalid trie operation!");
+			}
+			count++;
+			subsequence.remove(0);
+			if (!subsequence.isEmpty()) {
+				T nextSymbol = subsequence.get(0);
+				getChildCreate(nextSymbol).add(subsequence);
+			}
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the symbol associated with the node.
+	 * </p>
+	 * 
+	 * @return symbol associated with the node
+	 */
+	public T getSymbol() {
+		return symbol;
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of occurences of the sequence represented by the node.
+	 * </p>
+	 * 
+	 * @return number of occurences of the sequence represented by the node
+	 */
+	public int getCount() {
+		return count;
+	}
+
+	/**
+	 * <p>
+	 * Returns the child of the node associated with the given symbol or creates
+	 * it if it does not exist yet.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol whose node is required
+	 * @return node associated with the symbol
+	 * @see Trie#getChildCreate(Object)
+	 */
+	protected TrieNode<T> getChildCreate(T symbol) {
+		TrieNode<T> node = getChild(symbol);
+		if (node == null) {
+			node = new TrieNode<T>(symbol);
+			children.add(node);
+		}
+		return node;
+	}
+
+	/**
+	 * <p>
+	 * Returns the child of the node associated with the given symbol or null if
+	 * it does not exist.
+	 * </p>
+	 * 
+	 * @param symbol
+	 *            symbol whose node is required
+	 * @return node associated with the symbol; null if no such node exists
+	 * @see Trie#getChild(Object)
+	 */
+	protected TrieNode<T> getChild(T symbol) {
+		for (TrieNode<T> child : children) {
+			if (child.getSymbol().equals(symbol)) {
+				return child;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * <p>
+	 * Returns all children of this node.
+	 * </p>
+	 * 
+	 * @return children of this node
+	 */
+	protected Collection<TrieNode<T>> getChildren() {
+		return children;
+	}
+
+	/**
+	 * <p>
+	 * Searches the sub-trie of this trie node for a given sequence and returns
+	 * the node associated with the sequence or null if no such node is found.
+	 * </p>
+	 * 
+	 * @param sequence
+	 *            sequence that is searched for
+	 * @return node associated with the sequence
+	 * @see Trie#find(List)
+	 */
+	public TrieNode<T> find(List<T> subsequence) {
+		TrieNode<T> result = null;
+		if (subsequence.isEmpty()) {
+			result = this;
+		} else {
+			TrieNode<T> node = getChild(subsequence.get(0));
+			if (node != null) {
+				subsequence.remove(0);
+				result = node.find(subsequence);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * <p>
+	 * Returns a collection of all symbols that follow a this node, i.e., the
+	 * symbols associated with the children of this node.
+	 * </p>
+	 * 
+	 * @return symbols follow this node
+	 * @see TrieNode#getFollowingSymbols()
+	 */
+	public Collection<T> getFollowingSymbols() {
+		Collection<T> followingSymbols = new LinkedList<T>();
+		for (TrieNode<T> child : children) {
+			followingSymbols.add(child.getSymbol());
+		}
+		return followingSymbols;
+	}
+
+	/**
+	 * <p>
+	 * The string representation of a node is {@code symbol.toString()#count}
+	 * </p>
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		String str = symbol.toString() + " #" + count;
+		if (!children.isEmpty()) {
+			str += StringTools.ENDLINE + children.toString();
+		}
+		return str;
+	}
+
+	/**
+	 * <p>
+	 * Generates a {@link Tree} represenation of the trie.
+	 * </p>
+	 * 
+	 * @param parent
+	 *            parent vertex in the generated tree
+	 * @param graph
+	 *            complete tree
+	 */
+	void getGraph(TrieVertex parent, DelegateTree<TrieVertex, Edge> graph) {
+		TrieVertex currentVertex;
+		if (isRoot()) {
+			currentVertex = new TrieVertex("root");
+			graph.addVertex(currentVertex);
+		} else {
+			currentVertex = new TrieVertex(getSymbol().toString() + "#"
+					+ getCount());
+			graph.addChild(new Edge(), parent, currentVertex);
+		}
+		for (TrieNode<T> node : children) {
+			node.getGraph(currentVertex, graph);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Appends the current node to the dot representation of the trie.
+	 * </p>
+	 * 
+	 * @param stringBuilder
+	 *            {@link StringBuilder} to which the dot representation is
+	 *            appended
+	 */
+	void appendDotRepresentation(StringBuilder stringBuilder) {
+		String thisSaneId;
+		if (isRoot()) {
+			thisSaneId = "root";
+		} else {
+			thisSaneId = symbol.toString().replace("\"", "\\\"")
+					.replaceAll("[\r\n]", "")
+					+ "#" + count;
+		}
+		stringBuilder.append(" " + hashCode() + " [label=\"" + thisSaneId
+				+ "\"];" + StringTools.ENDLINE);
+		for (TrieNode<T> childNode : children) {
+			stringBuilder.append(" " + hashCode() + " -> "
+					+ childNode.hashCode() + ";" + StringTools.ENDLINE);
+		}
+		for (TrieNode<T> childNode : children) {
+			childNode.appendDotRepresentation(stringBuilder);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Checks if the node is a leaf.
+	 * </p>
+	 * 
+	 * @return true if the node is a leaf, false otherwise.
+	 */
+	protected boolean isLeaf() {
+		return children.isEmpty();
+	}
+
+	/**
+	 * <p>
+	 * Checks if the node is the root.
+	 * </p>
+	 * 
+	 * @return true if the node is the root of the trie, false otherwise
+	 */
+	protected boolean isRoot() {
+		return symbol == null;
+	}
+
+	/**
+	 * <p>
+	 * Recursive methods that collects all nodes that are ancestors of leafs and
+	 * stores them in the set.
+	 * </p>
+	 * 
+	 * @param ancestors
+	 *            set of all ancestors of leafs
+	 */
+	protected void getLeafAncestors(List<TrieNode<T>> ancestors) {
+		boolean isAncestor = false;
+		for (TrieNode<T> child : children) {
+			child.getLeafAncestors(ancestors);
+			isAncestor |= child.isLeaf();
+		}
+		if (isAncestor) {
+			ancestors.add(this);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Returns the number of descendants of this node that are leafs. This does
+	 * not only include direct children of this node, but all leafs in the
+	 * sub-trie with this node as root.
+	 * </p>
+	 * 
+	 * @return number of leafs in this sub-trie
+	 */
+	protected int getNumLeafs() {
+		int numLeafs = 0;
+		for (TrieNode<T> child : children) {
+			if (child.isLeaf()) {
+				numLeafs++;
+			} else {
+				numLeafs += child.getNumLeafs();
+			}
+		}
+		return numLeafs;
+	}
+
+	/**
+	 * <p>
+	 * Sets the {@link #count} of this node.
+	 * </p>
+	 * <p>
+	 * This function should only be used sparingly and very carefully! The count
+	 * is usually maintained automatically by the training procedures.
+	 * </p>
+	 * 
+	 * @param count
+	 *            new count
+	 */
+	protected void setCount(int count) {
+		this.count = count;
+	}
+
+	/**
+	 * <p>
+	 * Two TrieNodes are defined as equal, if their {@link #count},
+	 * {@link #symbol}, and {@link #children} are equal.
+	 * </p>
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@SuppressWarnings("rawtypes")
+	@Override
+	public boolean equals(Object other) {
+		if (other == this) {
+			return true;
+		}
+		if (other instanceof TrieNode) {
+			TrieNode otherNode = (TrieNode) other;
+			if (symbol == null) {
+				return count == otherNode.count && otherNode.symbol == null
+						&& children.equals(otherNode.children);
+			} else {
+				return count == otherNode.count
+						&& symbol.equals(((TrieNode) other).symbol)
+						&& children.equals(((TrieNode) other).children);
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		int multiplier = 17;
+		int hash = 42;
+		if (symbol != null) {
+			hash = multiplier * hash + symbol.hashCode();
+		}
+		hash = multiplier * hash + count;
+		hash = multiplier * hash + children.hashCode();
+		return hash;
+	}
+}
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/ReplayGenerator.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/ReplayGenerator.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/ReplayGenerator.java	(revision 433)
@@ -9,6 +9,6 @@
 
 import de.ugoe.cs.quest.IReplayDecorator;
-import de.ugoe.cs.quest.data.IReplayable;
-import de.ugoe.cs.quest.data.ReplayableEvent;
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
 import de.ugoe.cs.util.StringTools;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/AbstractTrainCommand.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/AbstractTrainCommand.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/AbstractTrainCommand.java	(revision 433)
@@ -7,7 +7,7 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.SequenceInstanceOf;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.TrieBasedModel;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
 import de.ugoe.cs.util.console.Command;
 
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDcalcCoverage.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDcalcCoverage.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDcalcCoverage.java	(revision 433)
@@ -9,7 +9,7 @@
 import de.ugoe.cs.quest.coverage.CoverageCalculatorObserved;
 import de.ugoe.cs.quest.coverage.CoverageCalculatorProcess;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDcalcEntropy.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDcalcEntropy.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDcalcEntropy.java	(revision 433)
@@ -6,5 +6,5 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDflattenModel.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDflattenModel.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDflattenModel.java	(revision 433)
@@ -6,7 +6,7 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel;
-import de.ugoe.cs.quest.models.HighOrderMarkovModel;
-import de.ugoe.cs.quest.models.ModelFlattener;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.HighOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.ModelFlattener;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateFixedLengthSequences.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateFixedLengthSequences.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateFixedLengthSequences.java	(revision 433)
@@ -12,7 +12,7 @@
 
 import de.ugoe.cs.quest.CommandHelpers;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateGreedy.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateGreedy.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateGreedy.java	(revision 433)
@@ -12,7 +12,7 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.coverage.SequenceTools;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 import de.ugoe.cs.util.ArrayTools;
 import de.ugoe.cs.util.console.Command;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateHybrid.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateHybrid.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateHybrid.java	(revision 433)
@@ -10,7 +10,7 @@
 
 import de.ugoe.cs.quest.CommandHelpers;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateRandomReplay.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateRandomReplay.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateRandomReplay.java	(revision 433)
@@ -9,6 +9,6 @@
 import de.ugoe.cs.quest.ReplayGenerator;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.data.ReplayableEvent;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateRandomSequences.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateRandomSequences.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateRandomSequences.java	(revision 433)
@@ -7,7 +7,7 @@
 
 import de.ugoe.cs.quest.CommandHelpers;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateReplayfile.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateReplayfile.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDgenerateReplayfile.java	(revision 433)
@@ -9,5 +9,5 @@
 import de.ugoe.cs.quest.SequenceInstanceOf;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.data.ReplayableEvent;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDlistSymbols.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDlistSymbols.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDlistSymbols.java	(revision 433)
@@ -7,5 +7,5 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDmodelSize.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDmodelSize.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDmodelSize.java	(revision 433)
@@ -6,5 +6,5 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDprintDot.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDprintDot.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDprintDot.java	(revision 433)
@@ -6,5 +6,5 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.IDotCompatible;
+import de.ugoe.cs.quest.usageprofiles.IDotCompatible;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDprintTrieDot.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDprintTrieDot.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDprintTrieDot.java	(revision 433)
@@ -6,6 +6,6 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.Trie;
-import de.ugoe.cs.quest.models.TrieBasedModel;
+import de.ugoe.cs.quest.usageprofiles.Trie;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDsequenceStatistics.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDsequenceStatistics.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDsequenceStatistics.java	(revision 433)
@@ -10,6 +10,6 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.SequenceInstanceOf;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
+import de.ugoe.cs.quest.eventcore.Event;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDshowMarkovModel.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDshowMarkovModel.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDshowMarkovModel.java	(revision 433)
@@ -13,6 +13,6 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel;
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel.MarkovEdge;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel.MarkovEdge;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDshowTrie.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDshowTrie.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDshowTrie.java	(revision 433)
@@ -13,8 +13,8 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.Trie;
-import de.ugoe.cs.quest.models.TrieBasedModel;
-import de.ugoe.cs.quest.models.Trie.Edge;
-import de.ugoe.cs.quest.models.Trie.TrieVertex;
+import de.ugoe.cs.quest.usageprofiles.Trie;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
+import de.ugoe.cs.quest.usageprofiles.Trie.Edge;
+import de.ugoe.cs.quest.usageprofiles.Trie.TrieVertex;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDtrainDFA.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDtrainDFA.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDtrainDFA.java	(revision 433)
@@ -4,6 +4,6 @@
 import java.util.Random;
 
-import de.ugoe.cs.quest.models.DeterministicFiniteAutomaton;
-import de.ugoe.cs.quest.models.TrieBasedModel;
+import de.ugoe.cs.quest.usageprofiles.DeterministicFiniteAutomaton;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
 import de.ugoe.cs.util.console.Console;
 
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDtrainMarkovModel.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDtrainMarkovModel.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDtrainMarkovModel.java	(revision 433)
@@ -4,7 +4,7 @@
 import java.util.Random;
 
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel;
-import de.ugoe.cs.quest.models.HighOrderMarkovModel;
-import de.ugoe.cs.quest.models.TrieBasedModel;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.HighOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
 import de.ugoe.cs.util.console.Console;
 
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDtrainPPM.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDtrainPPM.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDtrainPPM.java	(revision 433)
@@ -4,6 +4,6 @@
 import java.util.Random;
 
-import de.ugoe.cs.quest.models.PredictionByPartialMatch;
-import de.ugoe.cs.quest.models.TrieBasedModel;
+import de.ugoe.cs.quest.usageprofiles.PredictionByPartialMatch;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
 import de.ugoe.cs.util.console.Console;
 
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDupdateModel.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDupdateModel.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/commands/CMDupdateModel.java	(revision 433)
@@ -7,7 +7,7 @@
 import de.ugoe.cs.quest.CommandHelpers;
 import de.ugoe.cs.quest.SequenceInstanceOf;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.TrieBasedModel;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.TrieBasedModel;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/data/GlobalDataContainer.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/data/GlobalDataContainer.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/data/GlobalDataContainer.java	(revision 433)
@@ -12,5 +12,5 @@
 
 import de.ugoe.cs.quest.SequenceInstanceOf;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 
 /**
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/EFGModelGenerator.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/EFGModelGenerator.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/EFGModelGenerator.java	(revision 433)
@@ -8,8 +8,8 @@
 
 import de.ugoe.cs.quest.commands.CMDupdateModel;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.efg.data.EFGEvent;
-import de.ugoe.cs.quest.models.DeterministicFiniteAutomaton;
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.eventcore.Event;
+import de.ugoe.cs.quest.usageprofiles.DeterministicFiniteAutomaton;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
 import edu.umd.cs.guitar.model.GUITARConstants;
 import edu.umd.cs.guitar.model.IO;
@@ -21,5 +21,5 @@
  * <p>
  * Provides functionality to generates models defined in the package
- * de.ugoe.cs.quest.models from EFGs.
+ * de.ugoe.cs.quest.usageprofiles from EFGs.
  * </p>
  * 
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/GUITARTestCaseParser.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/GUITARTestCaseParser.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/GUITARTestCaseParser.java	(revision 433)
@@ -5,6 +5,6 @@
 import java.util.List;
 
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.efg.data.EFGEvent;
+import de.ugoe.cs.quest.eventcore.Event;
 import edu.umd.cs.guitar.model.IO;
 import edu.umd.cs.guitar.model.data.EFG;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/commands/CMDefgTestCasesToSequences.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/commands/CMDefgTestCasesToSequences.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/commands/CMDefgTestCasesToSequences.java	(revision 433)
@@ -9,7 +9,7 @@
 
 import de.ugoe.cs.quest.CommandHelpers;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
 import de.ugoe.cs.quest.efg.GUITARTestCaseParser;
+import de.ugoe.cs.quest.eventcore.Event;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/commands/CMDefgToDFA.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/commands/CMDefgToDFA.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/commands/CMDefgToDFA.java	(revision 433)
@@ -6,5 +6,5 @@
 import de.ugoe.cs.quest.data.GlobalDataContainer;
 import de.ugoe.cs.quest.efg.EFGModelGenerator;
-import de.ugoe.cs.quest.models.DeterministicFiniteAutomaton;
+import de.ugoe.cs.quest.usageprofiles.DeterministicFiniteAutomaton;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/commands/CMDefgToMM.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/commands/CMDefgToMM.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/commands/CMDefgToMM.java	(revision 433)
@@ -6,5 +6,5 @@
 import de.ugoe.cs.quest.data.GlobalDataContainer;
 import de.ugoe.cs.quest.efg.EFGModelGenerator;
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
 import de.ugoe.cs.util.console.Command;
 import de.ugoe.cs.util.console.Console;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/data/EFGEvent.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/data/EFGEvent.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/data/EFGEvent.java	(revision 433)
@@ -1,5 +1,5 @@
 package de.ugoe.cs.quest.efg.data;
 
-import de.ugoe.cs.quest.data.ReplayableEvent;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
 
 /**
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/data/EFGReplayable.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/data/EFGReplayable.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/efg/data/EFGReplayable.java	(revision 433)
@@ -1,5 +1,5 @@
 package de.ugoe.cs.quest.efg.data;
 
-import de.ugoe.cs.quest.data.IReplayable;
+import de.ugoe.cs.quest.eventcore.IReplayable;
 import de.ugoe.cs.util.StringTools;
 
@@ -42,5 +42,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getReplay()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
 	 */
 	@Override
@@ -57,5 +57,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getTarget()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
 	 */
 	@Override
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/jfc/data/JFCEvent.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/jfc/data/JFCEvent.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/jfc/data/JFCEvent.java	(revision 433)
@@ -4,6 +4,6 @@
 import java.util.Map;
 
-import de.ugoe.cs.quest.data.IReplayable;
-import de.ugoe.cs.quest.data.ReplayableEvent;
+import de.ugoe.cs.quest.eventcore.IReplayable;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
 import de.ugoe.cs.quest.jfc.JFCLogParser;
 
@@ -174,5 +174,5 @@
 	 * </p>
 	 * 
-	 * @see de.ugoe.cs.quest.data.Event#targetEquals(java.lang.String)
+	 * @see de.ugoe.cs.quest.eventcore.Event#targetEquals(java.lang.String)
 	 */
 	@Override
@@ -188,5 +188,5 @@
 	 * </p>
 	 * 
-	 * @see de.ugoe.cs.quest.data.Event#targetHashCode()
+	 * @see de.ugoe.cs.quest.eventcore.Event#targetHashCode()
 	 */
 	@Override
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/AbstractInsertEventComposite.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/AbstractInsertEventComposite.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/AbstractInsertEventComposite.java	(revision 433)
@@ -5,5 +5,5 @@
 import org.eclipse.swt.widgets.Composite;
 
-import de.ugoe.cs.quest.data.Event;
+import de.ugoe.cs.quest.eventcore.Event;
 
 abstract public class AbstractInsertEventComposite extends Composite {
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/EditSequenceDialog.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/EditSequenceDialog.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/EditSequenceDialog.java	(revision 433)
@@ -19,5 +19,5 @@
 import org.eclipse.swt.graphics.Point;
 
-import de.ugoe.cs.quest.data.Event;
+import de.ugoe.cs.quest.eventcore.Event;
 
 public class EditSequenceDialog extends Dialog {
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/InsertAssertionDialog.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/InsertAssertionDialog.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/InsertAssertionDialog.java	(revision 433)
@@ -17,5 +17,5 @@
 import org.eclipse.swt.widgets.Button;
 
-import de.ugoe.cs.quest.data.Event;
+import de.ugoe.cs.quest.eventcore.Event;
 
 public class InsertAssertionDialog extends Dialog {
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/InsertFileEquals.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/InsertFileEquals.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/InsertFileEquals.java	(revision 433)
@@ -14,5 +14,5 @@
 import de.ugoe.cs.quest.assertions.AssertEvent;
 import de.ugoe.cs.quest.assertions.FileEqualsReplay;
-import de.ugoe.cs.quest.data.Event;
+import de.ugoe.cs.quest.eventcore.Event;
 
 import org.eclipse.swt.events.SelectionAdapter;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/InsertTextEquals.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/InsertTextEquals.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/InsertTextEquals.java	(revision 433)
@@ -15,5 +15,5 @@
 import de.ugoe.cs.quest.assertions.AssertEvent;
 import de.ugoe.cs.quest.assertions.TextEqualsReplay;
-import de.ugoe.cs.quest.data.Event;
+import de.ugoe.cs.quest.eventcore.Event;
 import de.ugoe.cs.util.ArrayTools;
 
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/ModelPropertiesDialog.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/ModelPropertiesDialog.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/ModelPropertiesDialog.java	(revision 433)
@@ -14,6 +14,6 @@
 import org.eclipse.swt.layout.FillLayout;
 
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 
 import org.eclipse.swt.events.SelectionAdapter;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/ModelsTabComposite.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/ModelsTabComposite.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/ModelsTabComposite.java	(revision 433)
@@ -10,7 +10,7 @@
 
 import de.ugoe.cs.quest.data.GlobalDataContainer;
-import de.ugoe.cs.quest.models.FirstOrderMarkovModel;
-import de.ugoe.cs.quest.models.IDotCompatible;
-import de.ugoe.cs.quest.models.IStochasticProcess;
+import de.ugoe.cs.quest.usageprofiles.FirstOrderMarkovModel;
+import de.ugoe.cs.quest.usageprofiles.IDotCompatible;
+import de.ugoe.cs.quest.usageprofiles.IStochasticProcess;
 import de.ugoe.cs.util.console.CommandExecuter;
 
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/SequencesDialog.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/SequencesDialog.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/swt/SequencesDialog.java	(revision 433)
@@ -16,6 +16,6 @@
 
 import de.ugoe.cs.quest.SequenceInstanceOf;
-import de.ugoe.cs.quest.data.Event;
 import de.ugoe.cs.quest.data.GlobalDataContainer;
+import de.ugoe.cs.quest.eventcore.Event;
 
 import org.eclipse.swt.events.SelectionAdapter;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/web/data/WebEvent.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/web/data/WebEvent.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/web/data/WebEvent.java	(revision 433)
@@ -3,5 +3,5 @@
 import java.util.List;
 
-import de.ugoe.cs.quest.data.ReplayableEvent;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
 
 /**
@@ -89,5 +89,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.ReplayableEvent#equals(java.lang.Object)
+	 * @see de.ugoe.cs.quest.eventcore.ReplayableEvent#equals(java.lang.Object)
 	 */
 	@Override
@@ -99,5 +99,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.ReplayableEvent#hashCode()
+	 * @see de.ugoe.cs.quest.eventcore.ReplayableEvent#hashCode()
 	 */
 	@Override
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/web/data/WebRequest.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/web/data/WebRequest.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/web/data/WebRequest.java	(revision 433)
@@ -4,5 +4,5 @@
 import java.util.List;
 
-import de.ugoe.cs.quest.data.IReplayable;
+import de.ugoe.cs.quest.eventcore.IReplayable;
 
 /**
@@ -81,5 +81,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getReplay()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
 	 */
 	@Override
@@ -125,5 +125,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getTarget()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
 	 */
 	@Override
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/EventGenerator.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/EventGenerator.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/EventGenerator.java	(revision 433)
@@ -17,5 +17,5 @@
 import org.jdom.input.SAXBuilder;
 
-import de.ugoe.cs.quest.data.Event;
+import de.ugoe.cs.quest.eventcore.Event;
 import de.ugoe.cs.quest.windows.data.WindowTree;
 import de.ugoe.cs.quest.windows.data.WindowTreeNode;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/SequenceSplitter.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/SequenceSplitter.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/SequenceSplitter.java	(revision 433)
@@ -4,5 +4,5 @@
 import java.util.List;
 
-import de.ugoe.cs.quest.data.Event;
+import de.ugoe.cs.quest.eventcore.Event;
 import de.ugoe.cs.quest.windows.data.WindowsEvent;
 import de.ugoe.cs.quest.windows.data.WindowsMessage;
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/data/WindowsEvent.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/data/WindowsEvent.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/data/WindowsEvent.java	(revision 433)
@@ -10,5 +10,5 @@
 import org.w3c.dom.NodeList;
 
-import de.ugoe.cs.quest.data.ReplayableEvent;
+import de.ugoe.cs.quest.eventcore.ReplayableEvent;
 
 /**
@@ -34,5 +34,5 @@
 	 * </p>
 	 * 
-	 * @see de.ugoe.cs.quest.data.Event#Event(String)
+	 * @see de.ugoe.cs.quest.eventcore.Event#Event(String)
 	 * @param type
 	 *            type of the event.
Index: /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/data/WindowsMessage.java
===================================================================
--- /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/data/WindowsMessage.java	(revision 432)
+++ /trunk/quest-ui-core/src/de/ugoe/cs/quest/windows/data/WindowsMessage.java	(revision 433)
@@ -5,5 +5,5 @@
 import java.util.Map;
 
-import de.ugoe.cs.quest.data.IReplayable;
+import de.ugoe.cs.quest.eventcore.IReplayable;
 import de.ugoe.cs.util.StringTools;
 
@@ -476,5 +476,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getReplay()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getReplay()
 	 */
 	@Override
@@ -512,5 +512,5 @@
 	 * (non-Javadoc)
 	 * 
-	 * @see de.ugoe.cs.quest.data.IReplayable#getTarget()
+	 * @see de.ugoe.cs.quest.eventcore.IReplayable#getTarget()
 	 */
 	@Override
